/** * call-agent-tool.js — Sub Agent 直接调用工具 * * 让 Master Agent 直接调用指定的 Sub Agent。 * Master 获取 orchestrate plan 后,按步骤逐个调用此工具执行。 */ /** * 创建 call_sub_agent 工具定义 * @returns {ToolDefinition} */ function createCallAgentTool() { return { name: 'call_sub_agent', description: `直接调用一个 Sub Agent 执行任务。你可以指定 agent 名称和任务描述。 适用场景: - 简单任务,直接调用对应 Agent - 按照 orchestrate 工具返回的 plan,逐步调用 Agent - 修复循环中,指定 executor 修复特定问题`, parameters: { type: 'object', required: ['agent', 'task'], properties: { agent: { type: 'string', description: '要调用的 Agent 名称(如 coder, verifier, writer 等)', }, task: { type: 'string', description: '给该 Agent 的任务描述', }, }, }, async execute(params, context) { const { agent, task } = params; const { agentManager, onSubAgentData } = context; if (!agentManager) { throw new Error('call_sub_agent 需要 agentManager'); } // 验证 agent 存在(所有 skill 已通过 skill-config-loader 加载到 config.agents) try { agentManager.getAgentConfig(agent); } catch { const available = agentManager.listAgents().map(a => a.name).join(', '); throw new Error(`Agent "${agent}" 不存在。可用 Agent: ${available}`); } // 调用 agent,传递流式回调 const result = await agentManager.callAgent(agent, task, { onData: (chunk) => { if (onSubAgentData && chunk && chunk.trim()) { onSubAgentData(agent, chunk); } }, }); return { agent, status: 'success', output: result.output || '', }; }, }; } /** * 创建 list_agents 工具定义 * @returns {ToolDefinition} */ function createListAgentsTool() { return { name: 'list_agents', description: '列出所有可用的 Sub Agent 及其描述。在不确定该调用哪个 Agent 时使用。', parameters: { type: 'object', properties: {}, }, async execute(_params, context) { const { agentManager, config } = context; const agents = []; const agentConfigs = config?.agents || {}; for (const [name, cfg] of Object.entries(agentConfigs)) { // 跳过 master 自身和 gateway if (name === 'master' || name === 'gateway') continue; agents.push({ name, type: cfg.type, description: cfg.description || '', }); } // 也列出 agent groups const groups = []; const groupConfigs = config?.agentGroups || {}; for (const [name, grp] of Object.entries(groupConfigs)) { groups.push({ name, description: grp.description || grp.name || '', agents: grp.agents || [], isDefault: grp.default || false, }); } return { agents, groups }; }, }; } module.exports = { createCallAgentTool, createListAgentsTool };