orchestrate-tool.js 4.24 KB
/**
 * orchestrate-tool.js — Orchestrator 编排规划工具
 *
 * 将 Orchestrator 封装为 Master Agent 可调用的规划工具。
 * 仅输出编排计划(步骤列表),Master 自行按步骤调用 call_sub_agent 执行,
 * 并管理修复循环和重试逻辑。
 */

/**
 * 创建 orchestrate 工具定义
 * @returns {ToolDefinition}
 */
function createOrchestrateTool() {
    return {
        name: 'orchestrate',
        description: `多 Agent 编排规划工具。当你判断任务需要多个 Sub Agent 协作完成时使用。
输入任务描述,返回执行步骤列表(调用哪些 Agent、执行顺序、依赖关系)。
获得计划后,你需要按步骤逐个调用 call_sub_agent 执行。`,

        parameters: {
            type: 'object',
            required: ['task'],
            properties: {
                task: {
                    type: 'string',
                    description: '需要编排的任务描述',
                },
                agentGroup: {
                    type: 'string',
                    description: '使用的 Agent 分组(如 development, novel-writing)。不指定则使用默认组',
                },
            },
        },

        async execute(params, context) {
            const { task, agentGroup } = params;
            const { config } = context;

            if (!config) {
                throw new Error('orchestrate tool 需要 config');
            }

            return planOrchestration(task, config, agentGroup);
        },
    };
}

/**
 * 分析任务 → 输出编排步骤列表
 */
function planOrchestration(task, config, agentGroup) {
    const groupName = agentGroup || findDefaultGroup(config);
    const group = config.agentGroups?.[groupName];

    if (!group) {
        return {
            status: 'error',
            message: `Agent group "${groupName}" 不存在。可用组: ${Object.keys(config.agentGroups || {}).join(', ')}`,
        };
    }

    // 获取组内 agents 的配置信息
    const agents = group.agents.map(name => {
        const agentConfig = config.agents?.[name];
        return {
            name,
            type: agentConfig?.type || 'unknown',
            description: agentConfig?.description || '',
        };
    });

    const executors = agents.filter(a => a.type === 'executor');
    const validators = agents.filter(a => a.type === 'validator');

    // 生成编排计划
    const steps = [];
    let stepNum = 1;

    for (const executor of executors) {
        steps.push({
            step: stepNum++,
            action: 'call_sub_agent',
            agent: executor.name,
            type: 'executor',
            description: `调用 ${executor.name}(${executor.description})执行任务`,
        });
    }

    for (const validator of validators) {
        steps.push({
            step: stepNum++,
            action: 'call_sub_agent',
            agent: validator.name,
            type: 'validator',
            description: `调用 ${validator.name}(${validator.description})验证结果`,
            dependsOn: executors.map(e => e.name),
        });
    }

    steps.push({
        step: stepNum++,
        action: 'conditional',
        condition: 'any_validator_failed',
        description: '如果有 validator 失败 → 调用 executor 修复 → 重新验证。重复直到全部通过或你判断无法修复。',
    });

    return {
        status: 'success',
        plan: {
            task,
            agentGroup: groupName,
            groupDescription: group.description || group.name,
            steps,
            agents,
            notes: [
                '按步骤逐个调用 call_sub_agent 工具执行',
                'executor 完成后再调 validator 验证',
                'validator 失败时,将失败原因传给 executor 修复',
                '全部 validator 通过后任务完成',
                '你负责管理执行顺序、重试和结果判断',
            ],
        },
    };
}

/**
 * 找到默认 agent group
 */
function findDefaultGroup(config) {
    const groups = config.agentGroups || {};
    for (const [name, group] of Object.entries(groups)) {
        if (group.default) return name;
    }
    return Object.keys(groups)[0] || 'development';
}

module.exports = { createOrchestrateTool };