/** * Phase Pipeline — Multi-phase workflows with approval gates * * Defines ordered execution phases. Each phase can optionally require human * approval before proceeding. Phases may run their assigned agents in parallel * or sequentially. Inspired by Claude Code's multi-phase orchestration pattern. * * @module PhasePipeline * @version 1.0.0 */ import type { AgentPayload, AgentContext, AgentResult } from '../types/agent-adapter'; import type { AdapterRegistry } from '../adapters/adapter-registry'; /** Current execution status of a phase */ export type PhaseStatus = 'pending' | 'running' | 'awaiting_approval' | 'approved' | 'rejected' | 'completed' | 'failed' | 'skipped'; /** * Defines a single phase in the pipeline. */ export interface PhaseDefinition { /** Unique phase name */ name: string; /** Human-readable description */ description?: string; /** Agent IDs to execute in this phase */ agents: string[]; /** If true, pipeline pauses after this phase until approval is granted */ requiresApproval?: boolean; /** If true, agents within this phase run in parallel (default: sequential) */ parallel?: boolean; /** Payload factory — builds the payload for each agent in this phase */ payloadFactory?: (agentId: string, previousResults: PhaseResult[]) => AgentPayload; /** Maximum time (ms) allowed for this phase before timeout */ timeoutMs?: number; } /** * Result from a single phase execution. */ export interface PhaseResult { /** Phase name */ phaseName: string; /** Final status */ status: PhaseStatus; /** Agent results, keyed by agentId */ agentResults: Map; /** Phase execution time in milliseconds */ durationMs: number; /** Approval metadata (if phase required approval) */ approval?: { approvedBy?: string; reason?: string; timestamp: number; }; } /** * Result from the entire pipeline execution. */ export interface PipelineResult { /** Whether the entire pipeline completed successfully */ success: boolean; /** Results per phase */ phases: PhaseResult[]; /** Total execution time in milliseconds */ totalMs: number; /** Name of the phase that stopped the pipeline (if any) */ stoppedAt?: string; /** Reason the pipeline stopped (rejection, failure, timeout) */ stopReason?: string; } /** * Callback signature for approval gates. * Return `{ approved: true }` to proceed, `{ approved: false, reason }` to reject. */ export type ApprovalCallback = (phaseName: string, phaseResult: PhaseResult, pipelineContext: PipelineExecutionContext) => Promise<{ approved: boolean; approvedBy?: string; reason?: string; }>; /** * Options for trajectory compaction in long-running pipelines. * * When the cumulative serialised output of completed phases exceeds * `thresholdChars`, `summarize()` is called and the full history is replaced * with a single compact stub. This prevents the context window from growing * unboundedly during multi-hundred-phase pipelines. */ export interface CompactionOptions { /** * Cumulative serialised char count above which compaction triggers. * Default: 50 000 characters. */ thresholdChars?: number; /** * Async function that distils all completed phases into a single summary string. * The pipeline calls this every time the threshold is breached and replaces the * full phase history with the returned string. */ summarize: (completedPhases: PhaseResult[]) => Promise; /** * Optional callback fired after every successful compaction. * Receives the summary text, the running compaction count (1-based), and a * **read-only snapshot of all phase results before they were replaced**. Use * this to archive full phase history before the stub overwrites it. * * @param summary The summary produced by `summarize`. * @param compactionCount Running count of compactions (1-based). * @param archivedPhases Full phase results that were compacted away. */ onCompact?: (summary: string, compactionCount: number, archivedPhases: ReadonlyArray) => void; } /** * Options for creating a PhasePipeline. */ export interface PhasePipelineOptions { /** Ordered list of phase definitions */ phases: PhaseDefinition[]; /** Called when a phase requires approval */ onApproval?: ApprovalCallback; /** * Maximum milliseconds to wait for an `onApproval` callback to resolve. * If the callback does not settle within this window the phase is **denied** * (fail-closed) and the pipeline stops with `stopReason: 'Approval timeout'`. * Defaults to **300 000 ms (5 minutes)**. */ approvalTimeoutMs?: number; /** Called when each phase starts */ onPhaseStart?: (phaseName: string, index: number) => void; /** Called when each phase completes */ onPhaseComplete?: (result: PhaseResult, index: number) => void; /** If true, auto-approve all gates (useful for testing) */ autoApprove?: boolean; /** * Trajectory compaction settings. * When set, the pipeline monitors cumulative phase output size and * summarises the history whenever the threshold is breached. */ compaction?: CompactionOptions; /** * Path to a JSON checkpoint file for durable DAG execution. * When set, the pipeline saves a checkpoint after every completed phase. * On restart, if the file exists, already-completed phases are skipped and * execution resumes from the first non-completed phase. * Use `PhasePipeline.clearCheckpoint(path)` to delete after a successful run. */ checkpointPath?: string; } /** * Runtime context available during pipeline execution. */ export interface PipelineExecutionContext { /** Results from previously completed phases */ completedPhases: PhaseResult[]; /** Index of the current phase */ currentPhaseIndex: number; /** Total number of phases */ totalPhases: number; } /** * Orchestrates multi-phase workflows with optional approval gates. * * @example * ```typescript * const pipeline = new PhasePipeline(registry, baseContext, { * phases: [ * { name: 'research', agents: ['researcher'], parallel: false }, * { name: 'review', agents: ['reviewer-a', 'reviewer-b'], parallel: true, requiresApproval: true }, * { name: 'publish', agents: ['publisher'] }, * ], * onApproval: async (name, result) => { * // In production: prompt the user * return { approved: true, approvedBy: 'admin' }; * }, * }); * * const result = await pipeline.run(); * ``` */ export declare class PhasePipeline { private registry; private baseContext; private options; private phaseResults; private _status; /** Running count of compactions for this pipeline run. */ private _compactionCount; /** Summary produced by the most recent compaction, or null. */ private _lastCompactionSummary; constructor(registry: AdapterRegistry, baseContext: AgentContext, options: PhasePipelineOptions); /** Current pipeline status */ get status(): string; /** Results from all executed phases (even if pipeline was aborted) */ get results(): ReadonlyArray; /** Phase definitions */ get phases(): ReadonlyArray; /** * Execute the entire pipeline, phase by phase. * * For each phase: * 1. Run all assigned agents (parallel or sequential) * 2. If `requiresApproval`, call the approval callback and wait * 3. If rejected, stop the pipeline * 4. Otherwise move to the next phase */ run(defaultPayload?: AgentPayload): Promise; /** The summary produced by the last compaction, or `null` if none has occurred. */ get lastCompactionSummary(): string | null; /** Total number of compactions performed so far in this run. */ get compactionCount(): number; /** * Reset the pipeline for re-execution. */ reset(): void; /** * Save the current pipeline state to the checkpoint file. * Called automatically after each phase when `checkpointPath` is set. * @internal */ private _saveCheckpoint; /** * Load a checkpoint from disk and restore phase results + next phase index. * Returns the index of the next phase to run (0 if no checkpoint). * @internal */ private _loadCheckpoint; /** * Delete the checkpoint file for this pipeline (or any given path). * Call this after a successful pipeline run to clean up. * * @example * ```typescript * const result = await pipeline.run(); * if (result.success) PhasePipeline.clearCheckpoint('./data/my-pipeline.checkpoint.json'); * ``` */ static clearCheckpoint(checkpointPath: string): void; /** @internal */ private _maybeCompact; private buildPayload; private executeWithTimeout; } //# sourceMappingURL=phase-pipeline.d.ts.map