UNPKG

pm-orchestrator-enhancement

Version:

PM Orchestrator Enhancement - Multi-agent parallel execution system

229 lines 8.52 kB
"use strict"; /** * Workflow Manager * * ワークフロー設定ファイルの読み込み、検証、条件分岐ロジックを提供します。 */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.WorkflowManager = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const yaml = __importStar(require("js-yaml")); class WorkflowManager { constructor(configPath) { this.workflows = new Map(); this.configPath = configPath || path.join(__dirname, '../../workflows'); } /** * ワークフロー設定ファイルを読み込む */ async loadWorkflows() { this.workflows.clear(); // YAMLファイルを読み込む const yamlFiles = fs.readdirSync(this.configPath).filter(f => f.endsWith('.yaml') || f.endsWith('.yml')); for (const file of yamlFiles) { await this.loadYamlFile(path.join(this.configPath, file)); } // JSONファイルを読み込む const jsonFiles = fs.readdirSync(this.configPath).filter(f => f.endsWith('.json')); for (const file of jsonFiles) { await this.loadJsonFile(path.join(this.configPath, file)); } } /** * YAMLファイルを読み込む */ async loadYamlFile(filePath) { const content = fs.readFileSync(filePath, 'utf8'); const workflows = yaml.load(content); for (const workflow of workflows) { this.validateWorkflow(workflow); this.workflows.set(workflow.pattern, workflow); } } /** * JSONファイルを読み込む */ async loadJsonFile(filePath) { const content = fs.readFileSync(filePath, 'utf8'); const workflows = JSON.parse(content); for (const workflow of workflows) { this.validateWorkflow(workflow); this.workflows.set(workflow.pattern, workflow); } } /** * ワークフロー設定を検証する */ validateWorkflow(workflow) { if (!workflow.name || !workflow.pattern) { throw new Error(`Invalid workflow: name and pattern are required`); } if (!workflow.subagents || workflow.subagents.length === 0) { throw new Error(`Invalid workflow ${workflow.name}: at least one subagent is required`); } // 依存関係の検証 const subagentNames = new Set(workflow.subagents.map(s => s.name)); for (const subagent of workflow.subagents) { if (subagent.dependsOn) { for (const dep of subagent.dependsOn) { if (!subagentNames.has(dep)) { throw new Error(`Invalid workflow ${workflow.name}: subagent ${subagent.name} depends on non-existent subagent ${dep}`); } } } } // 循環依存の検証 this.detectCircularDependency(workflow); } /** * 循環依存を検出する */ detectCircularDependency(workflow) { const visited = new Set(); const stack = new Set(); const visit = (name) => { if (stack.has(name)) { throw new Error(`Circular dependency detected in workflow ${workflow.name}: ${name}`); } if (visited.has(name)) { return; } stack.add(name); visited.add(name); const subagent = workflow.subagents.find(s => s.name === name); if (subagent?.dependsOn) { for (const dep of subagent.dependsOn) { visit(dep); } } stack.delete(name); }; for (const subagent of workflow.subagents) { visit(subagent.name); } } /** * パターンに一致するワークフローを取得する */ getWorkflow(pattern) { return this.workflows.get(pattern); } /** * タスク入力からワークフローを選択する */ selectWorkflow(userInput, detectedPattern) { // 検出されたパターンに基づいて選択 if (detectedPattern) { const workflow = this.getWorkflow(detectedPattern); if (workflow) { return workflow; } } // パターンマッチングによる選択 for (const [pattern, workflow] of this.workflows.entries()) { if (this.matchesPattern(userInput, pattern)) { return workflow; } } return undefined; } /** * パターンマッチング */ matchesPattern(userInput, pattern) { const lowerInput = userInput.toLowerCase(); // パターンごとのキーワードマッチング const patternKeywords = { PR_REVIEW_RESPONSE: ['pr', 'pull request', 'review', 'coderabbit'], LIST_MODIFICATION: ['version', 'update', '箇所', 'すべて', '全て'], COMPLEX_IMPLEMENTATION: ['実装', 'implement', 'feature', '機能'], QUALITY_CHECK: ['test', 'lint', 'typecheck', 'build', 'quality'], CODERABBIT_RESOLVE: ['coderabbit', 'resolve', '解決'], SECURITY_REVIEW: ['security', 'セキュリティ', '脆弱性', 'vulnerability'] }; const keywords = patternKeywords[pattern] || []; return keywords.some(keyword => lowerInput.includes(keyword)); } /** * 実行順序を決定する */ determineExecutionOrder(workflow) { const subagents = workflow.subagents; const levels = []; const completed = new Set(); while (completed.size < subagents.length) { const currentLevel = []; for (const subagent of subagents) { if (completed.has(subagent.name)) { continue; } // 依存関係がすべて満たされているかチェック const allDependenciesMet = !subagent.dependsOn || subagent.dependsOn.every(dep => completed.has(dep)); if (allDependenciesMet) { currentLevel.push(subagent.name); } } if (currentLevel.length === 0) { throw new Error(`Cannot determine execution order for workflow ${workflow.name}`); } levels.push(currentLevel); currentLevel.forEach(name => completed.add(name)); } return levels; } /** * 全ワークフロー設定を取得する */ getAllWorkflows() { return Array.from(this.workflows.values()); } /** * ワークフロー設定を追加する */ addWorkflow(workflow) { this.validateWorkflow(workflow); this.workflows.set(workflow.pattern, workflow); } /** * ワークフロー設定を削除する */ removeWorkflow(pattern) { return this.workflows.delete(pattern); } } exports.WorkflowManager = WorkflowManager; //# sourceMappingURL=workflow-manager.js.map