/** * RunHandleImpl — concrete implementation of RunHandle. * * Implements: * - Typed EventEmitter dispatch with per-type handler maps * - AsyncIterator fan-out with shared replay buffer (high-water-mark bounded) * - State machine (via state-machine.ts) * - Thenable contract (lazy internal promise, resolves to RunResult) * - Control method guards (RUN_NOT_ACTIVE, INVALID_STATE_TRANSITION) * - Interaction channel wiring */ import type { AgentName } from './types.js'; import type { AgentEvent, AgentEventType, EventOfType } from './events.js'; import type { DeferredPromptOptions, RunHandle, RunResult } from './run-handle.js'; import type { InteractionResponse } from './interaction.js'; import { type RunState } from './state-machine.js'; import { InteractionChannelImpl } from './interaction-channel-impl.js'; /** Options for constructing a RunHandleImpl. */ export interface RunHandleImplOptions { readonly runId: string; readonly agent: AgentName; readonly model?: string; /** Approval mode for the interaction channel. */ readonly approvalMode?: 'yolo' | 'prompt' | 'deny'; /** Maximum number of events to buffer for late async iterators. */ readonly bufferHighWaterMark?: number; /** Whether to collect all events in RunResult.events. */ readonly collectEvents?: boolean; /** Tags echoed back in RunResult. */ readonly tags?: string[]; } export declare class RunHandleImpl implements RunHandle { readonly runId: string; readonly agent: AgentName; readonly model: string | undefined; private _state; /** Map from event type -> array of handlers. */ private readonly _handlers; /** Shared ordered buffer of all events emitted so far. */ private readonly _buffer; /** Per-iterator tracking state. */ private readonly _iterators; /** When true, the run has ended and all iterators should drain and stop. */ private _done; /** High-water mark for the buffer. */ private readonly _hwm; private _resultPromise; private _resolveResult; /** Queued result if complete() is called before the promise is created. */ private _pendingResult; private _text; private _sessionId; private _cost; private _startTime; private _tokenUsage; private _turnCount; private _exitCode; private _signal; private _runError; private _collectedEvents; private readonly _collectEvents; private readonly _tags; readonly interaction: InteractionChannelImpl; /** Logger instance for this run. */ private readonly logger; /** OpenTelemetry span for this run. */ private readonly _runSpan; /** Map of active tool call spans by toolCallId. */ private readonly _toolSpans; /** Map of active subagent spans by subagentId. */ private readonly _subagentSpans; /** Bound runtime input transport used by send()/queue()/steer(). */ private _inputTransport; /** Bound interaction response transport used by approval/input dispatch. */ private _interactionTransport; /** Deferred prompts waiting for a matching run boundary. */ private readonly _deferredPrompts; /** Serializes deferred prompt delivery. */ private _deferredDeliveryChain; /** Monotonic counter for deferred prompt bookkeeping. */ private _deferredPromptSeq; constructor(options: RunHandleImplOptions); /** Current run state. */ get state(): RunState; /** * Transition to a new state. * Validates the transition and updates the internal state. * Does NOT emit a state-change event — callers should emit the appropriate event then call this. */ transitionTo(next: RunState): void; /** * Emit an event. Called by the adapter or test harness. * * 1. Accumulates relevant fields (text, token usage, cost, session ID). * 2. Appends to the shared buffer (with HWM enforcement). * 3. Wakes up waiting async iterators. * 4. Dispatches to registered EventEmitter handlers. */ emit(event: AgentEvent): void; /** * Log important events for observability. */ private _logEvent; /** * Signal that the run has ended with the given exit information. * Resolves the result promise and terminates all async iterators. */ complete(exitReason: RunResult['exitReason'], exitCode: number | null, signal: string | null): void; [Symbol.asyncIterator](): AsyncIterator; on(type: T, handler: (event: EventOfType) => void): this; off(type: T, handler: (event: EventOfType) => void): this; once(type: T, handler: (event: EventOfType) => void): this; /** Lazily create the result promise per spec §2. */ private _ensureResultPromise; get then(): Promise['then']; get catch(): Promise['catch']; get finally(): Promise['finally']; result(): Promise; /** @internal Bind the active runtime input transport. */ bindInputTransport(writer: (text: string) => Promise): void; /** @internal Bind the active runtime interaction transport. */ bindInteractionTransport(writer: (id: string, response: InteractionResponse) => Promise): void; send(text: string): Promise; queue(prompt: string, options?: DeferredPromptOptions): Promise; approve(detail?: string): Promise; deny(reason?: string): Promise; continue(prompt: string): Promise; steer(prompt: string, options?: DeferredPromptOptions): Promise; interrupt(): Promise; abort(): Promise; pause(): Promise; resume(): Promise; private _assertActive; private _accumulate; private _dispatchHandlers; /** Emit a debug event without recursing through _dispatchHandlers for debug handlers. */ private _emitDebugEvent; private _buildResult; private _handleInteractionResponse; private _sendNow; private _enqueueDeferredPrompt; private _triggerDeferredPromptDelivery; private _boundariesForEvent; }