import type { PendingQuestion, TaskTypeName } from './task-state.js'; // --------------------------------------------------------------------------- // Supporting types for TaskHandle // --------------------------------------------------------------------------- /** * Result payload attached to a completed task. * Intentionally minimal — providers can extend via the `metadata` bag. */ export interface TaskResult { /** Short human-readable summary of what the task accomplished. */ summary?: string; /** Structured output from the provider (e.g., file diffs, test results). */ artifacts?: unknown[]; /** Arbitrary provider-specific metadata. */ metadata?: Record; } /** * Metrics captured during a provider session. * Used by adapters to report resource consumption. */ export interface SessionMetrics { /** Wall-clock duration in milliseconds. */ durationMs?: number; /** Tokens consumed (prompt + completion). */ tokensUsed?: number; /** Number of tool invocations within the session. */ toolCalls?: number; /** Number of turns / round-trips with the model. */ turns?: number; } // --------------------------------------------------------------------------- // TaskHandle — the provider-facing API // --------------------------------------------------------------------------- /** * Provider-blind interface for managing a single task's lifecycle. * * Providers (Codex, Copilot, Claude) interact exclusively through this * interface. It delegates to the TaskManager internally but exposes no * orchestration or store details. * * Spec reference: §3.2 */ export interface TaskHandle { /** Unique human-readable task identifier. */ readonly taskId: string; // -- State transitions ---------------------------------------------------- /** Transition to RUNNING. Optionally attach a provider session ID. */ markRunning(sessionId?: string): void; /** Transition to COMPLETED with optional result and metrics. */ markCompleted(result?: TaskResult, metrics?: SessionMetrics): void; /** Transition to FAILED with an error message and optional exit code. */ markFailed(error: string, exitCode?: number): void; /** Transition to CANCELLED with a reason string. */ markCancelled(reason: string): void; /** * Transition to WAITING_ANSWER (input required). * The pending question queue is managed separately via queue methods. */ markInputRequired(): void; /** Transition to RATE_LIMITED with a reason and optional retry hint. */ markRateLimited(reason: string, retryAfterMs?: number): void; // -- Output --------------------------------------------------------------- /** Append a line to both summary output and verbose log. */ writeOutput(line: string): void; /** Append a line to verbose log only (not the summary ring buffer). */ writeOutputFileOnly(line: string): void; // -- Lifecycle ------------------------------------------------------------ /** Register an AbortController so cancellation can propagate. */ registerAbort(controller: AbortController): void; /** Clear the registered AbortController. */ unregisterAbort(): void; /** Whether the task has reached a terminal status. */ isTerminal(): boolean; /** Whether the task is still active (not terminal). */ isAlive(): boolean; /** * Register a callback invoked when the task is aborted. * Returns an unsubscribe function. */ onAborted(cb: () => void): () => void; // -- Pending question queue (FIFO) ---------------------------------------- /** Push a question onto the pending queue. */ queuePendingQuestion(q: PendingQuestion): void; /** Shift the first question off the pending queue. */ dequeuePendingQuestion(): PendingQuestion | undefined; /** Snapshot of the current pending question queue. */ getPendingQuestions(): readonly PendingQuestion[]; // -- Read-only accessors -------------------------------------------------- /** The original prompt submitted with the task. */ getPrompt(): string; /** The working directory for the task. */ getCwd(): string; /** The timeout in milliseconds (0 means no timeout). */ getTimeout(): number; /** The model requested for this task, if any. */ getModel(): string | undefined; /** The task type (coder, planner, tester, etc.). */ getTaskType(): TaskTypeName; /** Update the latest token usage snapshot for this task. */ setTokenUsage(usage: { totalTokens: number; inputTokens: number; outputTokens: number; contextWindow: number | null }): void; }