2026-08-21 16:33:06 +08:00

91 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();