c747d3e8be
---ci---
phase: 5
milestone: v0.10
status: execute
decisions:
- id: MULTI-03
decision: Parallel project execution via OrchestratorAgent.runForAllProjects
rationale: Sequential by default, parallel when parallelization.enabled with max_concurrent_projects limit
confidence: 0.85
alternatives: [single-project-only, manual-iteration]
- id: MULTI-05
decision: ideate --project all iterates all active_projects with deduplication
rationale: Each project gets its own IdeationEngine; ideas deduplicated by project:title key
confidence: 0.90
alternatives: [single-project-only, merge-all-ideas]
- id: MULTI-07
decision: project field in ---ci--- commit blocks and CommitScope for multi-project tracking
rationale: CIAgentMetadata.project and CommitScope.project fields propagated through all commit builders
confidence: 0.92
alternatives: [separate-repos-only, branch-prefix-only]
requirements:
covered: [MULTI-03, MULTI-05, MULTI-07]
partial: []
---/ci---
- Add max_concurrent_projects to ParallelizationConfig (default: 3)
- Add AgentContext.project_slug optional field for multi-project pipeline tracking
- Implement OrchestratorAgent.runForProject() for single-project execution
- Implement OrchestratorAgent.runForAllProjects() for multi-project iteration
- Sequential execution by default
- Parallel when parallelization.enabled with limitConcurrency batching
- Add --project flag to createRunCommand for targeted project execution
- --project all triggers multi-project pipeline
- --project slug1,slug2 for comma-separated projects
- Enhance createIdeateCommand --project all support
- Iterates all active projects from config
- Deduplicates findings by project:title key
- Per-project idea acceptance via separate IdeationEngine instances
- Markdown table output for multi-project results
- Propagate project slug through orchestrator pipeline commits
- Specify stage: project field in CIAgentMetadata init commit
- Ideate stage: project field in task commit via buildTaskCommit
- Orchestrator sets ciFiles with project slug for per-project .ciagent dirs
- 19 new tests covering MULTI-03, MULTI-05, MULTI-07 functionality
- All 561 tests pass, typecheck clean
81 lines
2.2 KiB
TypeScript
81 lines
2.2 KiB
TypeScript
import { IntelligenceBackend, BackendRequest, BackendResult, BackendUnavailableError, emptyBackendResult, validateBackendResult } from "../backends/types.js";
|
|
import { AgentName, AutonomyLevel } from "../types/config.js";
|
|
|
|
export interface AgentResult {
|
|
success: boolean;
|
|
output: string;
|
|
artifacts_created: string[] | number;
|
|
decisions: number;
|
|
escalations: number;
|
|
duration_ms: number;
|
|
error?: string;
|
|
}
|
|
|
|
export interface AgentContext {
|
|
project_path: string;
|
|
phase: number;
|
|
stage: string;
|
|
specification: string;
|
|
config_path: string;
|
|
backend?: IntelligenceBackend;
|
|
project_slug?: string;
|
|
}
|
|
|
|
export function backendResultToAgentResult(result: BackendResult): AgentResult {
|
|
const validation = validateBackendResult(result);
|
|
if (!validation.result) {
|
|
return {
|
|
success: false,
|
|
output: "",
|
|
artifacts_created: [],
|
|
decisions: 0,
|
|
escalations: 0,
|
|
duration_ms: 0,
|
|
error: `BackendResult validation failed: ${validation.errors.join("; ")}`,
|
|
};
|
|
}
|
|
return {
|
|
success: result.success,
|
|
output: result.output,
|
|
artifacts_created: result.artifacts.map((a) => a.path),
|
|
decisions: result.decisions.length,
|
|
escalations: result.escalations.length,
|
|
duration_ms: 0,
|
|
error: result.error,
|
|
};
|
|
}
|
|
|
|
export abstract class BaseAgent {
|
|
abstract readonly name: AgentName;
|
|
abstract readonly description: string;
|
|
abstract readonly workflow: string;
|
|
|
|
abstract execute(context: AgentContext): Promise<AgentResult>;
|
|
|
|
protected async executeViaBackend(context: AgentContext, task: string): Promise<AgentResult> {
|
|
if (!context.backend) {
|
|
throw new BackendUnavailableError("none", this.name);
|
|
}
|
|
const request: BackendRequest = {
|
|
persona: this.name,
|
|
workflow: this.workflow,
|
|
task,
|
|
context,
|
|
autonomy: "full",
|
|
};
|
|
const result = await context.backend.execute(request);
|
|
return backendResultToAgentResult(result);
|
|
}
|
|
|
|
protected log(message: string): void {
|
|
console.log(`[${this.name}] ${message}`);
|
|
}
|
|
|
|
protected warn(message: string): void {
|
|
console.warn(`[${this.name}] ⚠ ${message}`);
|
|
}
|
|
|
|
protected error(message: string): void {
|
|
console.error(`[${this.name}] ✗ ${message}`);
|
|
}
|
|
} |