openclaw-vainplex/src/agents/pi-tool-definition-adapter.ts
Mario Zechner cf1d3f7a7c fix: update pi packages to 0.51.0, remove bogus type augmentation
- Update @mariozechner/pi-agent-core, pi-ai, pi-coding-agent, pi-tui to 0.51.0
- Delete src/types/pi-coding-agent.d.ts (declared additionalExtensionPaths which SDK never supported)
- Fix ToolDefinition.execute signature (parameter order changed in 0.51.0)
- Remove dead additionalExtensionPaths from createAgentSession calls
2026-02-02 01:52:33 +01:00

122 lines
4.2 KiB
TypeScript

import type {
AgentTool,
AgentToolResult,
AgentToolUpdateCallback,
} from "@mariozechner/pi-agent-core";
import type { ToolDefinition } from "@mariozechner/pi-coding-agent";
import type { ClientToolDefinition } from "./pi-embedded-runner/run/params.js";
import { logDebug, logError } from "../logger.js";
import { runBeforeToolCallHook } from "./pi-tools.before-tool-call.js";
import { normalizeToolName } from "./tool-policy.js";
import { jsonResult } from "./tools/common.js";
// biome-ignore lint/suspicious/noExplicitAny: TypeBox schema type from pi-agent-core uses a different module instance.
type AnyAgentTool = AgentTool<any, unknown>;
function isPlainObject(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function describeToolExecutionError(err: unknown): {
message: string;
stack?: string;
} {
if (err instanceof Error) {
const message = err.message?.trim() ? err.message : String(err);
return { message, stack: err.stack };
}
return { message: String(err) };
}
export function toToolDefinitions(tools: AnyAgentTool[]): ToolDefinition[] {
return tools.map((tool) => {
const name = tool.name || "tool";
const normalizedName = normalizeToolName(name);
return {
name,
label: tool.label ?? name,
description: tool.description ?? "",
// biome-ignore lint/suspicious/noExplicitAny: TypeBox schema from pi-agent-core uses a different module instance.
parameters: tool.parameters,
execute: async (
toolCallId,
params,
signal,
onUpdate: AgentToolUpdateCallback<unknown> | undefined,
_ctx,
): Promise<AgentToolResult<unknown>> => {
try {
return await tool.execute(toolCallId, params, signal, onUpdate);
} catch (err) {
if (signal?.aborted) {
throw err;
}
const name =
err && typeof err === "object" && "name" in err
? String((err as { name?: unknown }).name)
: "";
if (name === "AbortError") {
throw err;
}
const described = describeToolExecutionError(err);
if (described.stack && described.stack !== described.message) {
logDebug(`tools: ${normalizedName} failed stack:\n${described.stack}`);
}
logError(`[tools] ${normalizedName} failed: ${described.message}`);
return jsonResult({
status: "error",
tool: normalizedName,
error: described.message,
});
}
},
} satisfies ToolDefinition;
});
}
// Convert client tools (OpenResponses hosted tools) to ToolDefinition format
// These tools are intercepted to return a "pending" result instead of executing
export function toClientToolDefinitions(
tools: ClientToolDefinition[],
onClientToolCall?: (toolName: string, params: Record<string, unknown>) => void,
hookContext?: { agentId?: string; sessionKey?: string },
): ToolDefinition[] {
return tools.map((tool) => {
const func = tool.function;
return {
name: func.name,
label: func.name,
description: func.description ?? "",
parameters: func.parameters as any,
execute: async (
toolCallId,
params,
_signal,
_onUpdate: AgentToolUpdateCallback<unknown> | undefined,
_ctx,
): Promise<AgentToolResult<unknown>> => {
const outcome = await runBeforeToolCallHook({
toolName: func.name,
params,
toolCallId,
ctx: hookContext,
});
if (outcome.blocked) {
throw new Error(outcome.reason);
}
const adjustedParams = outcome.params;
const paramsRecord = isPlainObject(adjustedParams) ? adjustedParams : {};
// Notify handler that a client tool was called
if (onClientToolCall) {
onClientToolCall(func.name, paramsRecord);
}
// Return a pending result - the client will execute this tool
return jsonResult({
status: "pending",
tool: func.name,
message: "Tool execution delegated to client",
});
},
} satisfies ToolDefinition;
});
}