v2.2-paseo-providers: Paseo provider stack + v2.2.1 pane-scoped chat fixes
Ship Paseo-equivalent provider snapshot, AgentComposerBar, ACP dispatch rewrite with streaming/persist, permission prompts, and agent commands. Follow-up: pane-scoped chat resolution, CoderMessageList tool timeline, WS user-delta replace, and inference orphan tool_call stripping. Archive openspec v2-2; update CHANGELOG and CURRENT. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
68
apps/web/src/lib/coder-tools.ts
Normal file
68
apps/web/src/lib/coder-tools.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
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<string, unknown> {
|
||||
try {
|
||||
const parsed = JSON.parse(raw) as Record<string, unknown>;
|
||||
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<string, unknown> },
|
||||
): 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);
|
||||
}
|
||||
Reference in New Issue
Block a user