Files
fusion/plugins/fusion-plugin-acp-runtime/src/tool-mapping.ts
gsxdsm c5ae5572a2 feat(acp): session/update event bridge (U4)
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>
2026-06-03 08:55:20 -07:00

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>;
}