import { MatrxRuntimeExecutionStatus, MatrxTransport, MatrxRuntimeOperationEvent, ServerJobStatus, MatrxRuntimeOperationView, ServerJobOutcome, ServerJobTarget, FollowServerJobOptions, Warmup, WarmItem, WarmReason } from '@ai-matrx/api'; import { MatrxStreamEnvelope } from '@ai-matrx/api/stream'; import * as react from 'react'; import { ReactNode } from 'react'; /** * `useFollowRuntimeOperation` — the reconnect follower as a hook: follow one * runtime operation's durable lifecycle stream * (`GET /runtime/executions/{id}/events/stream`, `@ai-matrx/api/stream` * under the hood) with the FULL production reconnect policy built in — * stall watchdog, bounded retry budget, `Last-Event-ID` cursor — via * `followRuntimeOperationToEnd`. Tuning knobs are typed and default to the * proven production values (45s stall, 60 × 2s budget). * * The host injects the transport and what each event MEANS (`onEvent`); * everything else is package policy. */ interface UseFollowRuntimeOperationOptions { /** The transport (typically the production `createMatrxTransport`). */ transport: MatrxTransport | (() => MatrxTransport); /** The execution to follow — null/undefined idles the hook. */ executionId: string | null | undefined; /** Resume cursor — the operation view's `last_event_seq` (0 = from start). */ lastEventSeq?: number; /** Gate — false tears the follow down (default true when an id is set). */ enabled?: boolean; /** Stall watchdog, ms. Default 45_000. */ stallTimeoutMs?: number; /** Consecutive-failure budget. Default 60. */ reconnectLimit?: number; /** Delay between attempts, ms. Default 2_000. */ reconnectDelayMs?: number; /** Fired per durable spine event (lifecycle transitions + notes). */ onEvent?: (event: MatrxRuntimeOperationEvent, seq: number | null) => void; /** Fired once when the follow settles (server `end`, exhausted budget, or teardown). */ onSettled?: (result: { ended: boolean; status: MatrxRuntimeExecutionStatus | null; }) => void; } interface UseFollowRuntimeOperation { /** True while a follow loop is live for the current execution. */ following: boolean; /** True once the server sent the terminal `end` frame. */ ended: boolean; /** The root status from the `end` frame, when ended. */ status: MatrxRuntimeExecutionStatus | null; } declare function useFollowRuntimeOperation(options: UseFollowRuntimeOperationOptions): UseFollowRuntimeOperation; /** * `useServerJob` — follow or reconnect to a server job from a component. * * Wraps `followServerJob` (`@ai-matrx/api`): give it a target (the * run's `X-Request-ID`, or the feature record it is linked to), what each * NDJSON frame means, and how to reload the saved result. It looks the run up * on mount, rejoins the live stream (replay deduped by `stream_id`/ * `stream_seq` across every reconnect on this page), falls back to the durable * lifecycle when there is no journal, and settles on the run's real status. * * When a follow ends without the run settling (the wire gave up, or the tab * was hidden), it reconnects when the tab becomes visible again and on * `reconnect()`. The hook never invents a status: `status` is null until the * server answers, then exactly what the server last said. */ interface UseServerJobOptions { /** The transport (typically the production `createMatrxTransport`). */ transport: MatrxTransport | (() => MatrxTransport); /** What to follow — null idles the hook. */ target: ServerJobTarget | null; /** Gate — false tears the follow down (default true). */ enabled?: boolean; /** Every NEW frame of the rejoined NDJSON response. */ onFrame?: (envelope: MatrxStreamEnvelope) => void; /** Re-read the feature's saved record once the job settles. */ reloadSavedResult: FollowServerJobOptions["reloadSavedResult"]; /** Fired once per follow with its outcome. */ onSettled?: (outcome: ServerJobOutcome) => void; /** Reconnect an unsettled job when the tab becomes visible. Default true. */ reconnectOnFocus?: boolean; /** THE RUN'S organization, when the transport is not already bound to it. */ organizationId?: string | null; /** Lifecycle follow tuning. */ follow?: FollowServerJobOptions["follow"]; /** Answer the first by-link identify from a read the host already holds (see `FollowServerJobOptions.identifyLink`). */ identifyLink?: FollowServerJobOptions["identifyLink"]; } interface UseServerJob { /** null until the server answers (or with no target); then the server's status. */ status: ServerJobStatus | null; /** The run as last read. */ operation: MatrxRuntimeOperationView | null; /** The last completed follow. */ outcome: ServerJobOutcome | null; /** The last follow could not reach the server at all. */ error: unknown; /** A follow is in progress. */ following: boolean; /** Look the job up again now (e.g. after starting a new run for the same record). */ reconnect: () => void; } declare function useServerJob(options: UseServerJobOptions): UseServerJob; declare function WarmupProvider(props: { warmup: Warmup; children?: ReactNode; }): react.JSX.Element; /** The provided warm-up, or null outside a `WarmupProvider`. */ declare function useWarmup(): Warmup | null; /** * Warm `items` when the component mounts and again whenever the item set * changes (pass `"agent_change"` / `"conversation_change"` when the change is * the person's switch, `"route"` for landing). Null/empty ids are skipped, so * `[{ key: "agent", id: maybeId }]` is safe before the id is known. * * A hard load mounts before the person's org is known: the warm is QUEUED by * the warm-up and goes out the moment the person and org are ready. When the * active org changes later the same items are re-issued with reason * `org_change` — a warm is per person and org. */ declare function useWarmOnMount(items: readonly WarmItem[], reason: WarmReason): void; export { WarmupProvider, useFollowRuntimeOperation, useServerJob, useWarmOnMount, useWarmup }; export type { UseFollowRuntimeOperation, UseFollowRuntimeOperationOptions, UseServerJob, UseServerJobOptions };