Files
nanobot-ts/src/agent/tools/base.ts

56 lines
1.6 KiB
TypeScript

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<string, unknown>, 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<string, unknown>;
/** Which parameters are required. Defaults to all keys if not set. */
readonly required?: string[];
execute(args: Record<string, unknown>): Promise<string>;
}
export class ToolRegistry {
private _tools = new Map<string, Tool>();
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<string, unknown>): Promise<string> {
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.]`;
}
}
}