91 lines
2.7 KiB
TypeScript
91 lines
2.7 KiB
TypeScript
import { Agent } from './agent.js';
|
||
import { getTools } from '../tools/registry.js';
|
||
|
||
/**
|
||
* SubAgentManager 单例 — 管理所有子 Agent 的创建、查询和多轮对话编排
|
||
*/
|
||
export class SubAgentManager {
|
||
private agents: Map<string, Agent> = new Map();
|
||
|
||
/**
|
||
* 创建一个子 Agent(只有普通工具,没有 sub-agent 管理工具,防止无限递归)
|
||
*/
|
||
spawn(name: string, systemPrompt: string): Agent {
|
||
if (this.agents.has(name)) {
|
||
throw new Error(`子 Agent "${name}" 已存在`);
|
||
}
|
||
const agent = new Agent({
|
||
name,
|
||
systemPrompt,
|
||
tools: getTools(), // 只有全局注册的普通工具
|
||
});
|
||
this.agents.set(name, agent);
|
||
return agent;
|
||
}
|
||
|
||
get(name: string): Agent | undefined {
|
||
return this.agents.get(name);
|
||
}
|
||
|
||
list(): Agent[] {
|
||
return Array.from(this.agents.values());
|
||
}
|
||
|
||
/**
|
||
* 运行两个 Agent 之间的多轮对话
|
||
* @param agent1Name 发起方 Agent 名称
|
||
* @param agent2Name 回应方 Agent 名称
|
||
* @param maxTurns 最大对话轮次(一轮 = agent1 发言 + agent2 回应)
|
||
* @param topic 对话主题
|
||
* @returns 完整对话记录
|
||
*/
|
||
async runConversation(
|
||
agent1Name: string,
|
||
agent2Name: string,
|
||
maxTurns: number,
|
||
topic: string,
|
||
): Promise<string> {
|
||
const agent1 = this.agents.get(agent1Name);
|
||
const agent2 = this.agents.get(agent2Name);
|
||
|
||
if (!agent1) {
|
||
return `错误: 子 Agent "${agent1Name}" 不存在。可用的 Agent: ${this.listNames()}`;
|
||
}
|
||
if (!agent2) {
|
||
return `错误: 子 Agent "${agent2Name}" 不存在。可用的 Agent: ${this.listNames()}`;
|
||
}
|
||
|
||
const transcript: string[] = [];
|
||
transcript.push(`=== 对话开始: ${agent1Name} vs ${agent2Name},主题: ${topic},轮次: ${maxTurns} ===\n`);
|
||
|
||
// 第一轮:agent1 发起对话
|
||
let currentMessage = `请就以下话题开始对话:${topic}。你是对话的发起方,请先发言。`;
|
||
let speaker = agent1;
|
||
let listener = agent2;
|
||
|
||
for (let turn = 1; turn <= maxTurns; turn++) {
|
||
// 当前发言者回复
|
||
const response = await speaker.run(currentMessage);
|
||
const line = `[${speaker.name}]: ${response}`;
|
||
console.log(line);
|
||
transcript.push(line);
|
||
|
||
// 将回复传给另一方
|
||
currentMessage = `[${speaker.name}]: ${response}\n请回复。`;
|
||
|
||
// 交换发言者
|
||
[speaker, listener] = [listener, speaker];
|
||
}
|
||
|
||
transcript.push(`\n=== 对话结束 ===`);
|
||
return transcript.join('\n');
|
||
}
|
||
|
||
private listNames(): string {
|
||
return Array.from(this.agents.keys()).join(', ') || '(无)';
|
||
}
|
||
}
|
||
|
||
/** 全局单例 */
|
||
export const subAgentManager = new SubAgentManager();
|