import type { ToolCall, ToolResult } from '@/api/types'; import type { ToolRun } from '@/components/ToolCallLine'; export interface AcpWireMeta { status?: 'running' | 'completed' | 'failed' | 'canceled'; kind?: string | null; title?: string; output?: unknown; error?: string; } export interface CoderToolCallWire { id: string; function: { name: string; arguments: string }; } function parseArgs(raw: string): Record { try { const parsed = JSON.parse(raw) as Record; return parsed && typeof parsed === 'object' ? parsed : {}; } catch { return {}; } } export function wireToolCallToRun(wire: CoderToolCallWire): ToolRun { const args = parseArgs(wire.function.arguments); const acp = args._acp as AcpWireMeta | undefined; const { _acp: _ignored, ...rest } = args; const lifecycle = acp?.status ?? 'running'; const call: ToolCall = { id: wire.id, name: wire.function.name, args: rest, }; if (lifecycle === 'running') { return { call, result: null }; } const result: ToolResult = { tool_call_id: wire.id, output: acp?.output ?? null, truncated: false, ...(acp?.error ? { error: acp.error } : {}), }; return { call, result }; } export function mergeWireToolCall( existing: CoderToolCallWire[] | undefined, incoming: { id: string; name: string; args: Record }, ): CoderToolCallWire[] { const entry: CoderToolCallWire = { id: incoming.id, function: { name: incoming.name, arguments: JSON.stringify(incoming.args) }, }; const list = existing ?? []; const idx = list.findIndex((tc) => tc.id === incoming.id); if (idx >= 0) { const next = [...list]; next[idx] = entry; return next; } return [...list, entry]; } export function wireToolCallsToRuns(wires: CoderToolCallWire[] | undefined): ToolRun[] { return (wires ?? []).map(wireToolCallToRun); }