From 48fb137c13116dc3c26befcc11df3e8693d605c4 Mon Sep 17 00:00:00 2001 From: Anais Saraiva Date: Mon, 21 Sep 2026 16:31:55 +0200 Subject: [PATCH] fixes --- docs/ARCHITECTURE.md | 5 ++++ docs/FRONTEND.md | 4 ++- frontend/src/components/AdminPanel.tsx | 3 +- frontend/src/components/SharePage.tsx | 2 +- frontend/src/components/dialogs.tsx | 10 +++---- frontend/src/components/ui.tsx | 4 ++- frontend/src/lib/api.ts | 3 +- frontend/src/lib/types.ts | 1 + src/db.ts | 3 +- src/drivers/registry.ts | 38 ++++++++++++++++++++++++++ src/index.ts | 19 +++++++++++-- 11 files changed, 78 insertions(+), 14 deletions(-) diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 0ed2df7..8adfbc0 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -103,6 +103,11 @@ Models are addressed as `"driver:model"` (split on the first `:`). - `OllamaDriver`: model discovery via `GET {OLLAMA_HOST}/api/tags`, chat via `POST /api/chat` with NDJSON streaming. +- `GET /api/models` is served from an in-memory cache in `DriverRegistry` + (`MODEL_CACHE_TTL_MS` = 60 s) so logins don't hit Ollama every time. + Concurrent misses share one in-flight upstream fetch. Admins pass + `?refresh=1` to force a fresh fetch (used by the "Ollama models" view); + the flag is ignored for non-admins. Admin pull/delete invalidate the cache. - `ApiDriverBase`: shared OpenAI-compatible `/models` + `/chat/completions` (SSE) implementation; concrete drivers only set base URL, key, and fallback model list. A driver is enabled only when its `*_ENABLED` flag is set **and** diff --git a/docs/FRONTEND.md b/docs/FRONTEND.md index 4d231b6..c54fa90 100644 --- a/docs/FRONTEND.md +++ b/docs/FRONTEND.md @@ -50,7 +50,9 @@ read-only `SharePage` (no auth), everything else renders the authenticated app. tabbed hub (Accounts / Features / Mail) reusing `AdminPanel`, server feature `Switch`es (`registrationEnabled`, `ocrEnabled` via `/api/admin/settings`), SMTP status card. Follows the platform theme. -- `SharePage.tsx` — public read-only view, fetches `/api/share/:id` unauthenticated. +- `SharePage.tsx` — public read-only view, fetches `/api/share/:id` unauthenticated + (`{ title, topic, model, authorName, authorAvatarUrl, sharedAt, messages }`); + user messages render the author's avatar via `Avatar` (URL or initials). - `Markdown.tsx` — `react-markdown` + GFM; code blocks get a language label and a copy button. diff --git a/frontend/src/components/AdminPanel.tsx b/frontend/src/components/AdminPanel.tsx index f3338cf..bfb8f5d 100644 --- a/frontend/src/components/AdminPanel.tsx +++ b/frontend/src/components/AdminPanel.tsx @@ -32,7 +32,8 @@ export function OllamaModelsModal({ open, onClose }: { open: boolean; onClose: ( async function refreshInstalled() { try { - const res = await api.models(); + // Admin view: force a fresh upstream fetch, bypassing the 60s user cache. + const res = await api.models({ refresh: true }); setInstalled(res.models.filter((m) => m.driver === "ollama")); } catch { /* ignore */ } } diff --git a/frontend/src/components/SharePage.tsx b/frontend/src/components/SharePage.tsx index 8b7d146..270c656 100644 --- a/frontend/src/components/SharePage.tsx +++ b/frontend/src/components/SharePage.tsx @@ -65,7 +65,7 @@ export function SharePage({ publicId }: { publicId: string }) { {chat?.messages.map((m, i) => (
{m.role === "user" - ? + ? : }
diff --git a/frontend/src/components/dialogs.tsx b/frontend/src/components/dialogs.tsx index 31eaad8..cd30d10 100644 --- a/frontend/src/components/dialogs.tsx +++ b/frontend/src/components/dialogs.tsx @@ -794,7 +794,7 @@ function SecuritySection({ onKeyRotated }: { onKeyRotated?: () => void }) {

Access key

Rotate your access key. Old sessions are revoked immediately — you'll log back in with the new key.

-
@@ -805,7 +805,7 @@ function SecuritySection({ onKeyRotated }: { onKeyRotated?: () => void }) { {totpOn === false && !secret && ( <>

Add a 6-digit code from your authenticator app on top of your access key.

- + )} {secret && ( @@ -825,7 +825,7 @@ function SecuritySection({ onKeyRotated }: { onKeyRotated?: () => void }) { inputMode="numeric" className="text-center tracking-[0.4em]" /> - +
)} @@ -843,7 +843,7 @@ function SecuritySection({ onKeyRotated }: { onKeyRotated?: () => void }) { />
- @@ -863,7 +863,7 @@ function SecuritySection({ onKeyRotated }: { onKeyRotated?: () => void }) { Danger zone

Permanently delete your account with all chats, shares and sessions. Cannot be undone.

- diff --git a/frontend/src/components/ui.tsx b/frontend/src/components/ui.tsx index 86c9884..0506698 100644 --- a/frontend/src/components/ui.tsx +++ b/frontend/src/components/ui.tsx @@ -11,9 +11,10 @@ type ButtonProps = React.ButtonHTMLAttributes & { size?: "sm" | "md" | "lg" | "icon"; }; -export function Button({ variant = "primary", size = "md", className, ...props }: ButtonProps) { +export function Button({ variant = "primary", size = "md", type = "button", className, ...props }: ButtonProps) { return (