Maps ACP session/update notifications to AgentRuntime callbacks using the authoritative SDK 0.24.0 vocabulary: agent_message_chunk->onText, agent_thought_chunk->onThinking, tool_call->onToolStart, tool_call_update (completed/failed)->onToolEnd correlated by toolCallId, plan as full replacement. tool-mapping.ts derives display names + normalizes args. createSession now passes a bridging client handler into connect() so streamed updates reach the engine callbacks. +24 tests (77 total). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
47 lines
1.6 KiB
TypeScript
47 lines
1.6 KiB
TypeScript
// Pure helpers mapping ACP `ToolCall` metadata into the display name + args
|
|
// shape Fusion's `onToolStart`/`onToolEnd` callbacks expect.
|
|
//
|
|
// ACP's `kind` is agent-defined, optional, and partial (U4). These helpers must
|
|
// never throw on missing/odd input — a missing title falls back to a label
|
|
// derived from `kind`, and a missing/non-object `rawInput` normalizes to `{}`.
|
|
|
|
import type { ToolKind } from "@agentclientprotocol/sdk";
|
|
|
|
/** Human-readable labels for each ACP `ToolKind`. */
|
|
const KIND_LABELS: Record<ToolKind, string> = {
|
|
read: "Read",
|
|
edit: "Edit",
|
|
delete: "Delete",
|
|
move: "Move",
|
|
search: "Search",
|
|
execute: "Execute",
|
|
think: "Think",
|
|
fetch: "Fetch",
|
|
switch_mode: "Switch Mode",
|
|
other: "Tool",
|
|
};
|
|
|
|
/**
|
|
* Resolve a display name for a tool call. Prefers the agent-supplied `title`;
|
|
* falls back to a label derived from `kind`; final fallback is `"tool"`.
|
|
*/
|
|
export function toolDisplayName(toolCall: { title?: string | null; kind?: ToolKind | null }): string {
|
|
const title = typeof toolCall.title === "string" ? toolCall.title.trim() : "";
|
|
if (title) return title;
|
|
const kind = toolCall.kind;
|
|
if (kind && kind in KIND_LABELS) return KIND_LABELS[kind];
|
|
return "tool";
|
|
}
|
|
|
|
/**
|
|
* Normalize a tool call's `rawInput` to a plain object. Returns `{}` when the
|
|
* input is undefined, null, or any non-object (arrays included) so downstream
|
|
* code can always treat args as a record.
|
|
*/
|
|
export function normalizeToolArgs(rawInput: unknown): Record<string, unknown> {
|
|
if (rawInput === null || typeof rawInput !== "object" || Array.isArray(rawInput)) {
|
|
return {};
|
|
}
|
|
return rawInput as Record<string, unknown>;
|
|
}
|