UNPKG

mcp-subagents

Version:

Multi-Agent AI Orchestration via Model Context Protocol - Access specialized CLI AI agents (Aider, Qwen, Gemini, Goose, etc.) with intelligent fallback and configuration

111 lines 4.67 kB
import { QwenAgent } from './qwen.js'; import { GeminiAgent } from './gemini.js'; import { AiderAgent } from './aider.js'; import { GooseAgent } from './goose.js'; import { CodexAgent } from './codex.js'; import { OpenCodeAgent } from './opencode.js'; import { ClaudeAgent } from './claude.js'; import { AgentNotFoundError } from '../errors.js'; import { ConfigManager } from '../config.js'; export class AgentRegistry { agents = new Map(); detectionResults = new Map(); configManager; constructor() { this.configManager = new ConfigManager(); } static async create(detectedAgents) { const registry = new AgentRegistry(); await registry.initialize(detectedAgents); return registry; } async initialize(detectedAgents) { for (const detection of detectedAgents) { this.detectionResults.set(detection.name, detection); // Only create agents that are available and ready if (detection.available && detection.authStatus === 'ready') { const agent = this.createAgent(detection); this.agents.set(detection.name, agent); } } } createAgent(detection) { // Get configuration from config file/environment (this has priority over defaults) const globalConfig = this.configManager.getAgentConfig(detection.name); // Get agent-specific defaults const agentDefaults = this.getAgentDefaults(detection.name); // Merge defaults with global config (global config overrides defaults) const mergedDefaults = { ...agentDefaults, ...globalConfig.env, // merge environment variables from config ...(globalConfig.model !== undefined && { model: globalConfig.model }) // prefer config model over default }; const agentConfig = { priority: globalConfig.priority || 1, maxConcurrent: globalConfig.maxConcurrent || 1, inputMethod: detection.inputMethod, defaults: mergedDefaults, ...(detection.autoAcceptFlag && { autoAcceptFlag: detection.autoAcceptFlag }), ...(detection.modelFlag && { modelFlag: detection.modelFlag }), ...(detection.requiresSubcommand && { subcommand: detection.requiresSubcommand }) }; switch (detection.name) { case 'qwen': return new QwenAgent('qwen', agentConfig); case 'gemini': return new GeminiAgent('gemini', agentConfig); case 'aider': return new AiderAgent('aider', agentConfig); case 'goose': return new GooseAgent('goose', agentConfig); case 'codex': return new CodexAgent('codex', agentConfig); case 'opencode': return new OpenCodeAgent('opencode', agentConfig); case 'claude': return new ClaudeAgent('claude', agentConfig); default: // This will never be reached if the agent is correctly detected } // Should be unreachable if detection logic is correct throw new Error(`Unknown agent: ${detection.name}`); } getAgent(name) { const agent = this.agents.get(name); if (!agent) { const detection = this.detectionResults.get(name); if (!detection) { throw new AgentNotFoundError(`Agent '${name}' not detected`); } if (!detection.available) { throw new AgentNotFoundError(`Agent '${name}' not available. Install it first.`); } if (detection.authStatus !== 'ready') { throw new AgentNotFoundError(`Agent '${name}' requires authentication: ${detection.authInstructions}`); } throw new AgentNotFoundError(`Agent '${name}' is detected but not initialized`); } return agent; } listAvailableAgents() { return Array.from(this.agents.keys()); } getDetectionResults() { return Array.from(this.detectionResults.values()); } getAgentDefaults(agent) { // Built-in defaults - these have the LOWEST priority and will be overridden // by configuration file settings and environment variables const defaults = { qwen: { model: 'qwen3-coder-max' }, gemini: {}, aider: { model: 'gpt-4o' }, goose: {}, codex: { fullAuto: true }, opencode: {}, claude: {} }; return defaults[agent] || {}; } } //# sourceMappingURL=registry.js.map