summaryrefslogtreecommitdiffhomepage
path: root/src/app
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-27 20:20:02 +0900
committerAdam Malczewski <[email protected]>2026-06-27 20:20:02 +0900
commitf5dc22f7c14d6c0dd4bcedee5a85b21ecd294aed (patch)
tree8ba78efaefc25148dfb550b4332204822f5acf5d /src/app
parentfa0bd9c0e433b1abddc814b48a358c94954c7d36 (diff)
downloaddispatch-web-f5dc22f7c14d6c0dd4bcedee5a85b21ecd294aed.tar.gz
dispatch-web-f5dc22f7c14d6c0dd4bcedee5a85b21ecd294aed.zip
feat(vision): resolve persisted image URLs against the API base
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/<conv>/<uuid>.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; <img src> 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.
Diffstat (limited to 'src/app')
-rw-r--r--src/app/App.svelte2
-rw-r--r--src/app/store.svelte.ts9
2 files changed, 11 insertions, 0 deletions
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}
</div>
@@ -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 `<img src>`.
+ */
+ 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