/** * Orchestrator loop — drives a lifecycle instance through phases via a bare LLM endpoint. * * This module is optional (Req 19.12). It imports endpoint-clients and budget-packer * but does NOT import into the CLI unless the `aidlc run` command is invoked. * * Loop: * 1. Load instance state, resolve template, compute nextStep * 2. Pack context items into the budget using packContext * 3. Build the prompt (system message + context + task) * 4. Call the LLM endpoint * 5. Process the response (log; artifact processing is a future enhancement) * 6. If autoAdvance, attempt transition * 7. Repeat until complete or maxIterations reached * * Requirements: 19.1, 19.6, 19.12 */ import type { EndpointClient, InstanceState, PhaseState, WorkflowTemplate, NextStep } from '../core/types.js'; import type { ContextItem, PackResult } from './budget-packer.js'; /** Options for running the orchestrator loop. */ export interface OrchestratorOpts { /** Lifecycle instance name. */ instance: string; /** Endpoint client for LLM communication. */ client: EndpointClient; /** Model name to pass to the endpoint. */ model: string; /** Token budget for context packing per prompt. */ contextBudget: number; /** If true, automatically attempt transition after response. */ autoAdvance: boolean; /** Safety cap on iterations (default 50). */ maxIterations?: number; } /** Result returned when the orchestrator loop completes. */ export interface OrchestratorResult { /** Number of iterations executed. */ iterations: number; /** Phase the instance is in when the loop ended. */ finalPhase: string; /** Whether the lifecycle instance reached completion. */ completed: boolean; /** Error message if the loop ended due to an error. */ error?: string; } /** * Context loader interface — abstracts state and file reading so the loop * doesn't need direct filesystem access (enables testing without I/O). */ export interface ContextLoader { /** Load the instance state from the state store. */ loadInstanceState(instance: string): InstanceState; /** Load all phase states for an instance. */ loadPhaseStates(instance: string): Map; /** Load and resolve the workflow template for an instance. */ loadTemplate(templateName: string): WorkflowTemplate; /** Load the skill content for a given phase. Returns null if not found. */ loadPhaseSkill(phase: string): string | null; /** Load context items (guidance, context docs, state summaries). */ loadContextItems(instance: string, phase: string): ContextItem[]; /** Record that the loop produced a response (placeholder for artifact processing). */ processResponse(instance: string, phase: string, response: string): void; /** * Attempt a phase transition after the loop determines it should advance. * Returns the new phase name on success, or null if blocked. */ attemptTransition(instance: string, currentPhase: string): string | null; } /** * Build the system prompt from the current phase skill. * * The skill body forms the system message. If no skill is found, this is * a hard error (Req 19.5) — callers must handle null skill before calling. */ export declare function buildSystemPrompt(skillContent: string, phase: string): string; /** * Build the user message from packed context and the current task. */ export declare function buildUserMessage(packResult: PackResult, step: NextStep, instanceName: string): string; /** * Run the orchestrator loop for a lifecycle instance. * * The loop repeats until: * - The lifecycle instance reaches completion (nextStep returns 'complete') * - maxIterations is reached (safety cap) * - An error occurs (endpoint failure, missing skill, etc.) * * @param opts - Orchestrator configuration and endpoint client. * @param loader - Context loader for state, templates, and files. * @returns OrchestratorResult describing the outcome. */ export declare function runOrchestratorLoop(opts: OrchestratorOpts, loader: ContextLoader): Promise; //# sourceMappingURL=orchestrator-loop.d.ts.map