/** * ErrorBridge — translates footprintjs's STRUCTURAL `onRunFailed` (the * terminal run-boundary event fired when a run throws a non-pause error) * into agentfootprint's TYPED `agentfootprint.error.fatal` domain event. * * Pattern: Adapter (GoF) — same role as EmitBridge, different channel. * Role: Close the "failed run is invisible" gap. footprintjs fires * `onError` (stage-level) + `onRunFailed` (run-level) on the * FlowRecorder channel, but agentfootprint's typed consumers * (LiveStateRecorder clearing in-flight, monitors setting * status) listen on the DISPATCHER. Without a bridge, a thrown * LLM call left `isLLMInFlight()` stuck true ("Chatbot is * thinking…" forever) and downstream STATUS showed "ok". This * re-dispatches one terminal typed event so every consumer * reacts uniformly. * Emits: agentfootprint.error.fatal (once per failed top-level run). * * Fires at the TOP LEVEL only — footprintjs `onRunFailed` is a run * boundary, not a per-stage event. Subflow errors propagate up and * surface here once. */ import type { CombinedRecorder, FlowRunFailedEvent } from 'footprintjs'; import type { EventDispatcher } from '../../events/dispatcher.js'; import { type RunContext } from '../../bridge/eventMeta.js'; export interface ErrorBridgeOptions { readonly dispatcher: EventDispatcher; /** Recorder id — must be unique among attached recorders. */ readonly id?: string; readonly getRunContext: () => RunContext; } export declare class ErrorBridge implements CombinedRecorder { readonly id: string; private readonly dispatcher; private readonly getRunContext; constructor(options: ErrorBridgeOptions); onRunFailed(event: FlowRunFailedEvent): void; } export declare function errorBridge(options: ErrorBridgeOptions): ErrorBridge;