Add AgentTool.prepareArguments and ToolDefinition.prepareArguments hook that runs before schema validation in the agent loop. This lets tools silently accept legacy argument shapes from resumed old sessions without polluting the public schema. The built-in edit tool uses this to fold legacy top-level oldText/newText into edits[] when resuming sessions that predate the edits-only schema. - AgentTool/ToolDefinition: typed prepareArguments returning Static<TParameters> - agent-loop: prepareToolCallArguments() runs before validateToolArguments() - edit tool: prepareEditArguments folds legacy fields, validateEditInput is strict - Documented in extensions.md with edit-tool example
44 lines
1.6 KiB
TypeScript
44 lines
1.6 KiB
TypeScript
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
import type { ExtensionContext, ToolDefinition } from "../extensions/types.js";
|
|
|
|
/** Wrap a ToolDefinition into an AgentTool for the core runtime. */
|
|
export function wrapToolDefinition<TDetails = unknown>(
|
|
definition: ToolDefinition<any, TDetails>,
|
|
ctxFactory?: () => ExtensionContext,
|
|
): AgentTool<any, TDetails> {
|
|
return {
|
|
name: definition.name,
|
|
label: definition.label,
|
|
description: definition.description,
|
|
parameters: definition.parameters,
|
|
prepareArguments: definition.prepareArguments,
|
|
execute: (toolCallId, params, signal, onUpdate) =>
|
|
definition.execute(toolCallId, params, signal, onUpdate, ctxFactory?.() as ExtensionContext),
|
|
};
|
|
}
|
|
|
|
/** Wrap multiple ToolDefinitions into AgentTools for the core runtime. */
|
|
export function wrapToolDefinitions(
|
|
definitions: ToolDefinition<any, any>[],
|
|
ctxFactory?: () => ExtensionContext,
|
|
): AgentTool<any>[] {
|
|
return definitions.map((definition) => wrapToolDefinition(definition, ctxFactory));
|
|
}
|
|
|
|
/**
|
|
* Synthesize a minimal ToolDefinition from an AgentTool.
|
|
*
|
|
* This keeps AgentSession's internal registry definition-first even when a caller
|
|
* provides plain AgentTool overrides that do not include prompt metadata or renderers.
|
|
*/
|
|
export function createToolDefinitionFromAgentTool(tool: AgentTool<any>): ToolDefinition<any, unknown> {
|
|
return {
|
|
name: tool.name,
|
|
label: tool.label,
|
|
description: tool.description,
|
|
parameters: tool.parameters as any,
|
|
prepareArguments: tool.prepareArguments,
|
|
execute: async (toolCallId, params, signal, onUpdate) => tool.execute(toolCallId, params, signal, onUpdate),
|
|
};
|
|
}
|