import type { ISessionClient } from "../../platform/ports/session-client.ts"; import type { DispatchTask, DispatchTaskStatus, DispatchManagerConfig, TaskEventState } from "../types.ts"; import { TaskWatchdogManager } from "../core/watchdog.ts"; import { SessionMonitor } from "./session-monitor.ts"; import { MetricsPersister } from "../persistence/metrics-persister.ts"; import { BudgetTracker } from "../budget/budget-tracker.ts"; import { TaskStateStore } from "../persistence/task-store.ts"; import type { CheckpointStore } from "../types.checkpoint.ts"; import type { ProgressStore } from "../types.progress.ts"; import type { ParentTasksIndex } from "../core/lifecycle-shared.ts"; export interface CompletionOrchestratorDeps { tasks: Map; eventState: Map; client: ISessionClient; watchdog: TaskWatchdogManager; config: DispatchManagerConfig; sessionToTask: Map; notifyOutbox: Set; cleanupTimers: Map>; sidecarGCTimers: Map>; cleanedUpTasks: Map; deferredIdleTimers: Map>; pendingNotifications: Set; sessionMonitor: SessionMonitor; budgetTracker: BudgetTracker; store: TaskStateStore; metricsPersister: MetricsPersister; directory: string; checkpointStore: CheckpointStore; progressStore: ProgressStore; clearEmittedThresholds: (taskId: string) => void; /** Internal mutable state shared with persist-helpers. */ _dirtyInternal?: boolean; _persistTimerInternal?: ReturnType | undefined; /** Timer handle set by budget sampler — cleared in flushPersistSync. */ _budgetSamplerTimer?: ReturnType | undefined; /** Timer handle set by sweeper — cleared in flushPersistSync. */ _sweeperTimerInternal?: ReturnType | undefined; /** Transition function injected by the orchestrator for recovery use. */ _transition?: (taskId: string, from: DispatchTaskStatus[], to: DispatchTaskStatus, fields?: Partial>) => boolean; /** Callback to get inflight count for the sweeper. */ getInflightCount: (parentSessionId: string) => number; /** Callback for sending completion notifications (routes through DispatchManager.notifyCompletion). */ sendNotification: (task: DispatchTask, remainingTasks: number, resultText?: string) => Promise; /** Callback to cancel a task from the budget sampler. */ cancelTask: (taskId: string) => Promise; /** Parent→taskIds index for O(1) getTasksByParent lookups. */ parentTasksIndex: ParentTasksIndex; /** Inflight running task count per parentSessionId — shared with TaskLifecycleDeps for O(1) getInflightCount. */ inflightByParent: Map; /** Oldest startedAt timestamp per parentSessionId — shared with TaskLifecycleDeps for O(1) getOldestInflightChildStartedAt. */ oldestStartedAtByParent: Map; } /** * Owns all completion-orchestration responsibilities that were formerly * private methods of DispatchManager: persistence, sweeper, budget sampler, * recovery, and the shared-state cleanup / transition primitives. * * All Map/Set references are shared with the owning DispatchManager and * TaskLifecycleManager — mutations are visible across all three. */ /** * Bridge interface for private methods/fields accessed by DispatchManager via `(this.orchestrator as any)`. * Provides type-safe access without exposing the full internal API. */ export interface OrchestratorBridge { readonly _dirty: boolean; readonly _persistTimer: ReturnType | undefined; readonly sweeperTimer: ReturnType | undefined; transition(taskId: string, from: DispatchTaskStatus[], to: DispatchTaskStatus, fields?: Partial>): boolean; setStore(store: TaskStateStore): void; setMetricsPersister(persister: MetricsPersister): void; setDirectory(directory: string): void; } export declare class CompletionOrchestrator implements OrchestratorBridge { private d; private _recovered; get _dirty(): boolean; get _persistTimer(): ReturnType | undefined; get sweeperTimer(): ReturnType | undefined; constructor(deps: CompletionOrchestratorDeps); dispose(): void; /** * True while the periodic pipelines that keep the manager operational are * armed: the outbox sweeper, plus the budget sampler whenever a budget limit * is configured (startBudgetSampler legitimately returns no timer when no * limit is set — that absence must not read as a stopped pipeline). * The persist timer is deliberately excluded: it is undefined whenever state * is clean. */ isRunning(): boolean; /** True while the budget sampler timer is armed. */ isBudgetSamplerArmed(): boolean; /** True when any of the five budget limits is configured (mirrors startBudgetSampler's gate). */ hasBudgetLimits(): boolean; cleanupTask(taskId: string): void; scheduleCleanup(taskId: string): void; persistState(): void; addToOutbox(taskId: string): void; flushPersist(): Promise; flushPersistSync(): void; startSweeper(): void; startBudgetSampler(): void; recover(): Promise; transition(taskId: string, from: DispatchTaskStatus[], to: DispatchTaskStatus, fields?: Partial>): boolean; setStore(store: TaskStateStore): void; setMetricsPersister(persister: MetricsPersister): void; setDirectory(directory: string): void; } //# sourceMappingURL=completion-orchestrator.d.ts.map