/** * Tool Registry — 工具注册表 * * 管理所有可用工具(内置 + MCP),提供查找、注册、注销功能。 */ import type { MetonaToolDef, MetonaToolCall, MetonaToolResult, } from '../types'; import type { IMetonaTool, ToolRegistryEntry, ToolExecutionContext } from '../types/metona-tool'; export class ToolRegistry { private tools = new Map(); private disabledTools = new Set(); /** 注册内置工具 */ registerBuiltin(tool: IMetonaTool): void { this.tools.set(tool.definition.name, { tool, source: 'builtin', enabled: true, }); } /** 注册 MCP 工具 */ registerMCP(serverName: string, tool: IMetonaTool): void { this.tools.set(tool.definition.name, { tool, source: 'mcp', serverName, enabled: true, }); } /** 注销 MCP Server 提供的所有工具 */ unregisterMCPTools(serverName: string): void { for (const [name, entry] of this.tools) { if (entry.source === 'mcp' && entry.serverName === serverName) { this.tools.delete(name); } } } /** 获取工具 */ get(name: string): IMetonaTool | undefined { const entry = this.tools.get(name); if (!entry?.enabled) return undefined; if (this.disabledTools.has(name)) return undefined; return entry.tool; } /** 列出所有已启用工具的定义 */ listTools(): MetonaToolDef[] { return Array.from(this.tools.values()) .filter((e) => e.enabled && !this.disabledTools.has(e.tool.definition.name)) .map((e) => e.tool.definition); } /** 列出所有工具定义(含已禁用的,供设置 UI 使用) */ listAllTools(): Array { return Array.from(this.tools.values()).map((e) => ({ ...e.tool.definition, enabled: e.enabled && !this.disabledTools.has(e.tool.definition.name), })); } /** 设置工具启用/禁用状态(供 IPC tools:toggle 调用) */ setToolEnabled(name: string, enabled: boolean): void { if (enabled) { this.disabledTools.delete(name); } else { this.disabledTools.add(name); } } /** 执行工具 */ async execute( toolCall: MetonaToolCall, context: ToolExecutionContext, ): Promise { const tool = this.get(toolCall.name); if (!tool) { return { toolCallId: toolCall.id, toolName: toolCall.name, result: null, success: false, error: `Unknown tool: ${toolCall.name}`, durationMs: 0, timestamp: Date.now(), }; } const startTs = Date.now(); try { const result = await tool.execute(toolCall.args, context); return { toolCallId: toolCall.id, toolName: toolCall.name, result, success: true, durationMs: Date.now() - startTs, timestamp: Date.now(), }; } catch (error) { return { toolCallId: toolCall.id, toolName: toolCall.name, result: null, success: false, error: (error as Error).message, durationMs: Date.now() - startTs, timestamp: Date.now(), }; } } /** 获取工具数量 */ get size(): number { return Array.from(this.tools.values()).filter((e) => e.enabled && !this.disabledTools.has(e.tool.definition.name)).length; } }