import Anthropic from '@anthropic-ai/sdk'; import type { Tool, ToolResult, Message, AgentConfig } from '../types/index.js'; export class Agent { private client: Anthropic; private config: AgentConfig; private tools: Map = new Map(); private conversationHistory: Message[] = []; constructor(config: AgentConfig) { this.config = config; this.client = new Anthropic({ apiKey: config.apiKey, }); } // 注册工具 registerTool(tool: Tool): void { this.tools.set(tool.name, tool); } // 获取所有工具定义(用于 Claude API) private getToolDefinitions(): Anthropic.Tool[] { return Array.from(this.tools.values()).map((tool) => ({ name: tool.name, description: tool.description, input_schema: { type: 'object' as const, properties: Object.fromEntries( Object.entries(tool.parameters).map(([key, param]) => [ key, { type: param.type, description: param.description, }, ]) ), required: Object.entries(tool.parameters) .filter(([, param]) => param.required) .map(([key]) => key), }, })); } // 执行工具 private async executeTool( toolName: string, input: Record ): Promise { const tool = this.tools.get(toolName); if (!tool) { return { success: false, output: '', error: `Tool "${toolName}" not found`, }; } try { return await tool.execute(input); } catch (error) { return { success: false, output: '', error: error instanceof Error ? error.message : String(error), }; } } // 发送消息并处理响应 async chat( userMessage: string, onStream?: (text: string) => void ): Promise { // 添加用户消息到历史 this.conversationHistory.push({ role: 'user', content: userMessage, }); const messages: Anthropic.MessageParam[] = this.conversationHistory.map( (msg) => ({ role: msg.role, content: msg.content, }) ); let fullResponse = ''; // 循环处理,直到没有工具调用 while (true) { const response = await this.client.messages.create({ model: this.config.model, max_tokens: this.config.maxTokens, system: this.config.systemPrompt, tools: this.getToolDefinitions(), messages, }); // 处理响应内容 const textBlocks: string[] = []; const toolUseBlocks: Anthropic.ToolUseBlock[] = []; for (const block of response.content) { if (block.type === 'text') { textBlocks.push(block.text); if (onStream) { onStream(block.text); } } else if (block.type === 'tool_use') { toolUseBlocks.push(block); } } fullResponse += textBlocks.join(''); // 如果没有工具调用,结束循环 if (toolUseBlocks.length === 0) { break; } // 添加 assistant 消息 messages.push({ role: 'assistant', content: response.content, }); // 处理工具调用 const toolResults: Anthropic.ToolResultBlockParam[] = []; for (const toolUse of toolUseBlocks) { if (onStream) { onStream(`\n[调用工具: ${toolUse.name}]\n`); } const result = await this.executeTool( toolUse.name, toolUse.input as Record ); if (onStream) { onStream( result.success ? `[结果: ${result.output}]\n` : `[错误: ${result.error}]\n` ); } toolResults.push({ type: 'tool_result', tool_use_id: toolUse.id, content: result.success ? result.output : `Error: ${result.error}`, }); } // 添加工具结果 messages.push({ role: 'user', content: toolResults, }); } // 保存助手响应到历史 this.conversationHistory.push({ role: 'assistant', content: fullResponse, }); return fullResponse; } // 清空对话历史 clearHistory(): void { this.conversationHistory = []; } // 获取对话历史 getHistory(): Message[] { return [...this.conversationHistory]; } }