From f78a91c20f658dd404277919a0b872b352c99bb6 Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Tue, 19 May 2026 19:40:21 +0900 Subject: Phase 1: single agent + basic UI - Bun monorepo with @dispatch/core, @dispatch/api, @dispatch/frontend - Agent runtime with Vercel AI SDK, streaming via WebSocket - Tools: read_file, write_file, list_files (scoped to working directory) - Hono API server with POST /chat, GET /status, GET /health, WS /ws - Svelte 5 + DaisyUI frontend with chat UI, theme switcher, copy button - OpenCode Go (Zen) as LLM provider, deepseek-v4-flash-free model - Docker setup (dev + prod) with bin/ scripts and gopass secrets - Biome v2 linting/formatting, Vitest tests (44 passing) - Debug info attached to error messages for diagnostics --- .../frontend/src/lib/components/ChatInput.svelte | 45 +++++++++++++++ .../frontend/src/lib/components/ChatMessage.svelte | 26 +++++++++ .../frontend/src/lib/components/ChatPanel.svelte | 58 +++++++++++++++++++ packages/frontend/src/lib/components/Header.svelte | 54 ++++++++++++++++++ .../src/lib/components/ThemeSwitcher.svelte | 65 ++++++++++++++++++++++ .../src/lib/components/ToolCallDisplay.svelte | 50 +++++++++++++++++ 6 files changed, 298 insertions(+) create mode 100644 packages/frontend/src/lib/components/ChatInput.svelte create mode 100644 packages/frontend/src/lib/components/ChatMessage.svelte create mode 100644 packages/frontend/src/lib/components/ChatPanel.svelte create mode 100644 packages/frontend/src/lib/components/Header.svelte create mode 100644 packages/frontend/src/lib/components/ThemeSwitcher.svelte create mode 100644 packages/frontend/src/lib/components/ToolCallDisplay.svelte (limited to 'packages/frontend/src/lib/components') diff --git a/packages/frontend/src/lib/components/ChatInput.svelte b/packages/frontend/src/lib/components/ChatInput.svelte new file mode 100644 index 0000000..b929923 --- /dev/null +++ b/packages/frontend/src/lib/components/ChatInput.svelte @@ -0,0 +1,45 @@ + + +
+ + +
diff --git a/packages/frontend/src/lib/components/ChatMessage.svelte b/packages/frontend/src/lib/components/ChatMessage.svelte new file mode 100644 index 0000000..447bb29 --- /dev/null +++ b/packages/frontend/src/lib/components/ChatMessage.svelte @@ -0,0 +1,26 @@ + + +
+
+ {#if message.content} + {message.content} + {/if} + {#if message.isStreaming} + + {/if} + {#if message.toolCalls && message.toolCalls.length > 0} +
+ {#each message.toolCalls as toolCall (toolCall.id)} + + {/each} +
+ {/if} +
+
diff --git a/packages/frontend/src/lib/components/ChatPanel.svelte b/packages/frontend/src/lib/components/ChatPanel.svelte new file mode 100644 index 0000000..44efb0b --- /dev/null +++ b/packages/frontend/src/lib/components/ChatPanel.svelte @@ -0,0 +1,58 @@ + + +
+ +
+ + + {wsClient.connectionStatus} + + | + + Agent: + + {chatStore.agentStatus === "running" ? "running..." : chatStore.agentStatus} + + +
+ + +
+ {#if chatStore.messages.length === 0} +
+ Send a message to start a conversation +
+ {/if} + {#each chatStore.messages as message (message.id)} + + {/each} +
+
diff --git a/packages/frontend/src/lib/components/Header.svelte b/packages/frontend/src/lib/components/Header.svelte new file mode 100644 index 0000000..79d371c --- /dev/null +++ b/packages/frontend/src/lib/components/Header.svelte @@ -0,0 +1,54 @@ + + + + +{#if showThemeSwitcher} + (showThemeSwitcher = false)} /> +{/if} diff --git a/packages/frontend/src/lib/components/ThemeSwitcher.svelte b/packages/frontend/src/lib/components/ThemeSwitcher.svelte new file mode 100644 index 0000000..6984e3f --- /dev/null +++ b/packages/frontend/src/lib/components/ThemeSwitcher.svelte @@ -0,0 +1,65 @@ + + + +
e.key === "Escape" && onclose()} + aria-label="Close theme switcher" +>
+ + + diff --git a/packages/frontend/src/lib/components/ToolCallDisplay.svelte b/packages/frontend/src/lib/components/ToolCallDisplay.svelte new file mode 100644 index 0000000..f8e1f38 --- /dev/null +++ b/packages/frontend/src/lib/components/ToolCallDisplay.svelte @@ -0,0 +1,50 @@ + + +
+ + + {#if isExpanded} +
+
+

Arguments

+
{JSON.stringify(toolCall.arguments, null, 2)}
+
+ {#if toolCall.result !== undefined} +
+

Result

+
{toolCall.result}
+
+ {/if} +
+ {/if} +
-- cgit v1.2.3