diff options
| author | Adam Malczewski <[email protected]> | 2026-05-19 20:50:12 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-05-19 20:50:12 +0900 |
| commit | de6df4abdd8a6eb9a0217050ce17e0925f04602b (patch) | |
| tree | 17866778894054732e082e0ca381d33c9e9d6560 | |
| parent | b3d16aa62a1b8724fe57ab3846a83f03a4a3fbc0 (diff) | |
| download | dispatch-de6df4abdd8a6eb9a0217050ce17e0925f04602b.tar.gz dispatch-de6df4abdd8a6eb9a0217050ce17e0925f04602b.zip | |
fix: review findings — multi-turn history, race condition, collapse UI
- Core: toCoreMessages now includes tool calls and tool results in history
- Core: isError read from step tool results instead of hardcoded false
- API: status set synchronously before async generator to prevent race
- Frontend: DaisyUI collapse-open class applied dynamically on expanded state
- Frontend: removed duplicate isConnected update in wsClient.onEvent
| -rw-r--r-- | packages/api/src/agent-manager.ts | 1 | ||||
| -rw-r--r-- | packages/core/src/agent/agent.ts | 12 | ||||
| -rw-r--r-- | packages/frontend/src/lib/chat.svelte.ts | 4 | ||||
| -rw-r--r-- | packages/frontend/src/lib/components/ToolCallDisplay.svelte | 2 |
4 files changed, 12 insertions, 7 deletions
diff --git a/packages/api/src/agent-manager.ts b/packages/api/src/agent-manager.ts index 2991ee1..45e195c 100644 --- a/packages/api/src/agent-manager.ts +++ b/packages/api/src/agent-manager.ts @@ -69,6 +69,7 @@ export class AgentManager { async processMessage(message: string): Promise<void> { const agent = this.getOrCreateAgent(); + this.status = "running"; this.messageCount += 1; try { diff --git a/packages/core/src/agent/agent.ts b/packages/core/src/agent/agent.ts index a20a4ce..c28d691 100644 --- a/packages/core/src/agent/agent.ts +++ b/packages/core/src/agent/agent.ts @@ -17,7 +17,14 @@ function toCoreMessages(messages: ChatMessage[]): CoreMessage[] { if (msg.role === "user") { result.push({ role: "user", content: msg.content }); } else if (msg.role === "assistant") { - result.push({ role: "assistant", content: msg.content }); + const parts: Array<{ type: "text"; text: string } | { type: "tool-call"; toolCallId: string; toolName: string; args: Record<string, unknown> }> = [{ type: "text", text: msg.content }]; + for (const tc of msg.toolCalls ?? []) { + parts.push({ type: "tool-call", toolCallId: tc.id, toolName: tc.name, args: tc.arguments }); + } + result.push({ role: "assistant", content: parts }); + for (const tr of msg.toolResults ?? []) { + result.push({ role: "tool", content: [{ type: "tool-result", toolCallId: tr.toolCallId, toolName: "", result: tr.result }] }); + } } } return result; @@ -108,12 +115,13 @@ export class Agent { const stepToolResults = step.toolResults as unknown as Array<{ toolCallId: string; result: unknown; + isError?: boolean; }>; for (const tr of stepToolResults) { const toolResult: ToolResult = { toolCallId: tr.toolCallId, result: typeof tr.result === "string" ? tr.result : JSON.stringify(tr.result), - isError: false, + isError: tr.isError ?? false, }; toolResults.push(toolResult); yield { type: "tool-result", toolResult }; diff --git a/packages/frontend/src/lib/chat.svelte.ts b/packages/frontend/src/lib/chat.svelte.ts index e5367c2..fc5f68c 100644 --- a/packages/frontend/src/lib/chat.svelte.ts +++ b/packages/frontend/src/lib/chat.svelte.ts @@ -66,10 +66,6 @@ function createChatStore() { let currentAssistantId: string | null = null; wsClient.onEvent((event) => { - const connected = wsClient.connectionStatus === "connected"; - if (connected !== isConnected) { - isConnected = connected; - } handleEvent(event); }); diff --git a/packages/frontend/src/lib/components/ToolCallDisplay.svelte b/packages/frontend/src/lib/components/ToolCallDisplay.svelte index f8e1f38..83d21ba 100644 --- a/packages/frontend/src/lib/components/ToolCallDisplay.svelte +++ b/packages/frontend/src/lib/components/ToolCallDisplay.svelte @@ -10,7 +10,7 @@ function toggle() { } </script> -<div class="collapse collapse-arrow bg-base-200 my-1 rounded-lg border border-base-300"> +<div class="collapse collapse-arrow bg-base-200 my-1 rounded-lg border border-base-300 {isExpanded ? 'collapse-open' : ''}"> <button type="button" class="collapse-title flex items-center gap-2 text-sm font-medium cursor-pointer w-full text-left" |
