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; protected async executeViaBackend(context: AgentContext, task: string): Promise { 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}`); } }