2026-07-10 17:21:38 +08:00

93 lines
2.7 KiB
TypeScript

import { ContextManager } from '../context.js';
import { chat } from '../llm.js';
import { getTools } from '../tools/registry.js';
import { Tool } from '../types/index.js';
import { hooks } from '../hooks/index.js';
export interface AgentConfig {
name: string;
systemPrompt: string;
/** 该 Agent 可用的工具列表,默认使用全局注册的所有工具 */
tools?: Tool[];
}
export class Agent {
public name: string;
private context: ContextManager;
private tools: Tool[];
constructor(config: AgentConfig) {
this.name = config.name;
this.tools = config.tools ?? getTools();
this.context = new ContextManager();
this.context.add({ role: 'system', content: config.systemPrompt });
}
/**
* 运行 Agent 循环:发送消息 → 处理 tool_calls → 返回最终回复
*/
async run(userMessage: string): Promise<string> {
this.context.add({ role: 'user', content: userMessage });
const openaiTools = this.tools.length > 0
? this.tools.map((t) => ({
type: 'function' as const,
function: {
name: t.name,
description: t.description,
parameters: t.parameters,
},
}))
: undefined;
let reply = await chat(this.context.getMessages(), openaiTools);
// 工具调用循环
while (reply.tool_calls && reply.tool_calls.length > 0) {
this.context.add({
role: 'assistant',
content: '',
tool_calls: reply.tool_calls,
} as any);
for (const tc of reply.tool_calls) {
const tool = this.tools.find((t) => t.name === tc.function.name);
if (!tool) {
this.context.add({
role: 'tool',
tool_call_id: tc.id,
content: `错误: 未知工具 ${tc.function.name}`,
} as any);
continue;
}
hooks.emit('tool:before', { toolCall: tc, agentName: this.name });
try {
const args = JSON.parse(tc.function.arguments);
const result = await tool.execute(args);
this.context.add({
role: 'tool',
tool_call_id: tc.id,
content: result,
} as any);
hooks.emit('tool:after', { toolCall: tc, result, agentName: this.name });
} catch (e: any) {
this.context.add({
role: 'tool',
tool_call_id: tc.id,
content: `工具执行错误: ${e.message}`,
} as any);
hooks.emit('tool:after', { toolCall: tc, result: `错误: ${e.message}`, agentName: this.name });
}
}
reply = await chat(this.context.getMessages(), openaiTools);
}
const content = reply.content!;
this.context.add({ role: 'assistant', content });
return content;
}
}