From f5dc22f7c14d6c0dd4bcedee5a85b21ecd294aed Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Sat, 27 Jun 2026 20:20:02 +0900 Subject: feat(vision): resolve persisted image URLs against the API base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Images are now stored on disk under tmp (not SQLite) and served via GET /images/:conversationId/:imageId. Persisted ImageChunk.url is a compact relative HTTP path (/images//.png) instead of a base64 data URL. No wire/transport-contract type change (behavior only) — re-mirrored the delta notes. - New pure resolveImageUrl(url, apiBase) helper (core/chunks/image-url.ts, +8 tests): data/absolute URLs pass through; relative paths are prepended with the API base (no double slash; empty base -> root-relative). Exported from core/chunks + re-exported from features/chat. - ChatView: new apiBaseUrl prop; uses resolveImageUrl. The optimistic echo's data URL passes through; persisted relative paths resolve against the base. +3 tests. - AppStore exposes httpBase (getter); App.svelte passes apiBaseUrl into ChatView and the heartbeat RunModal (also renders image chunks). Verification: svelte-check 0/0; vitest 959/959 (run twice, +11); biome clean; vite build OK. See backend-handoff.md §2j-update-2. Not merged or pushed. --- src/app/App.svelte | 2 ++ src/app/store.svelte.ts | 9 +++++++++ 2 files changed, 11 insertions(+) (limited to 'src/app') diff --git a/src/app/App.svelte b/src/app/App.svelte index f41d7ba..7d70f67 100644 --- a/src/app/App.svelte +++ b/src/app/App.svelte @@ -516,6 +516,7 @@ onShowEarlier={handleShowEarlier} thinkingKeyBase={store.activeChat.thinkingKeyBase} providerRetry={store.activeChat.providerRetry} + apiBaseUrl={store.httpBase} /> {/key} @@ -610,6 +611,7 @@ closeChat={closeRunChat} stopRun={stopHeartbeatRun} onClose={() => (heartbeatRun = null)} + apiBaseUrl={store.httpBase} /> {/key} {/if} diff --git a/src/app/store.svelte.ts b/src/app/store.svelte.ts index 554d5e0..8353820 100644 --- a/src/app/store.svelte.ts +++ b/src/app/store.svelte.ts @@ -157,6 +157,12 @@ export interface AppStore { readonly activeConversationId: string | null; /** The workspace currently in view (URL slug); tabs are filtered to it. */ readonly activeWorkspaceId: string; + /** + * The resolved HTTP API base URL (e.g. `http://localhost:24203`). Used to + * resolve relative image URLs served by the backend (`/images/…`) into + * absolute URLs for ``. + */ + readonly httpBase: string; readonly activeChat: ChatStore; readonly models: readonly string[]; /** Per-model metadata (contextWindow, etc.) from `GET /models`. */ @@ -1127,6 +1133,9 @@ export function createAppStore(opts?: CreateAppStoreOptions): AppStore { get activeWorkspaceId(): string { return activeWorkspaceId; }, + get httpBase(): string { + return httpBase; + }, setActiveWorkspace(workspaceId: string): void { activeWorkspaceId = workspaceId; // Reset to a fresh draft scoped to the new workspace so a new chat is -- cgit v1.2.3