import type { ToolDefinition } from '../../provider/types.ts'; /** Safely extract a string from tool args (avoids no-base-to-string lint). */ export function strArg(args: Record, key: string, fallback = ''): string { const v = args[key]; return typeof v === 'string' ? v : fallback; } export interface Tool { readonly name: string; readonly description: string; /** JSON Schema `properties` object for the tool's parameters. */ readonly parameters: Record; /** Which parameters are required. Defaults to all keys if not set. */ readonly required?: string[]; execute(args: Record): Promise; } export class ToolRegistry { private _tools = new Map(); register(tool: Tool): void { this._tools.set(tool.name, tool); } get(name: string): Tool | undefined { return this._tools.get(name); } getDefinitions(): ToolDefinition[] { return [...this._tools.values()].map((t) => ({ type: 'function' as const, function: { name: t.name, description: t.description, parameters: { type: 'object', properties: t.parameters, required: t.required ?? Object.keys(t.parameters), }, }, })); } async execute(name: string, args: Record): Promise { const tool = this._tools.get(name); if (!tool) return `Error: unknown tool "${name}"`; try { return await tool.execute(args); } catch (err) { return `Error: ${String(err)}\n[Analyze the error above and retry with a different approach if needed.]`; } } }