@ai-matrx/agents 0.24.2 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { B as MatrxTransport, A as MatrxStreamCallOptions, w as MatrxRuntimeOperationEvent, a as FollowRuntimeOperationToEndOptions, v as MatrxRuntimeExecutionStatus, c as MatrxApiError, u as MatrxRunHandle, m as MatrxJsonValue, l as MatrxJsonObject } from '../operations--f5ko9Su.cjs';
1
+ import { B as MatrxTransport, w as MatrxRuntimeOperationEvent, a as FollowRuntimeOperationToEndOptions, v as MatrxRuntimeExecutionStatus, c as MatrxApiError, A as MatrxStreamCallOptions, u as MatrxRunHandle, m as MatrxJsonValue, l as MatrxJsonObject } from '../operations--f5ko9Su.cjs';
2
2
  export { F as FollowRuntimeOperationOptions, b as FollowRuntimeOperationToEndResult, M as MatrxAgentStartRequest, d as MatrxCancelResponse, e as MatrxChatMessage, f as MatrxCompletedRun, g as MatrxContextAnchor, h as MatrxConversationContinueRequest, i as MatrxConversationResumeRequest, j as MatrxConversationStart, k as MatrxEphemeralConversation, n as MatrxMandateStartRequest, o as MatrxOperationEventsPage, p as MatrxOperationFollowEvent, q as MatrxOperationStatusResponse, r as MatrxOperationsByLinkResponse, s as MatrxRequestScope, t as MatrxRunError, x as MatrxRuntimeOperationView, y as MatrxStoredConversationContinue, z as MatrxStoredConversationCreate, C as MatrxTransportRequest, D as MatrxTurnFields, R as RunAgentToCompletionOptions, T as TERMINAL_MATRX_RUNTIME_STATUSES, E as cancelAgentRun, G as continueAgentConversation, H as continueEphemeralConversationStart, I as continueStoredConversationStart, J as extractMatrxErrorCode, K as extractMatrxErrorMessage, L as followRuntimeOperationEvents, N as followRuntimeOperationToEnd, O as getRuntimeOperationStatus, P as getRuntimeOperationsByLink, Q as listRuntimeOperationEvents, S as mintMatrxConversationId, U as newEphemeralConversationStart, V as newStoredConversationStart, W as rejoinRuntimeOperation, X as resumeAgentConversation, Y as runAgentToCompletion, Z as startAgentRun, _ as startMandateRun } from '../operations--f5ko9Su.cjs';
3
3
  import { CredentialsPort } from '@ai-matrx/data';
4
4
  import { ResilientFetchOptions } from '@ai-matrx/data/net';
@@ -319,10 +319,12 @@ declare function assertQueryOrganizationMatchesContext(queryParams: Record<strin
319
319
  * `arm`, `analysis_id`). The client follows `rejoin_path` — never a URL it
320
320
  * builds — because a door outside the spine (SEO collections) answers
321
321
  * `live_request_id: null` with its own `/seo/collections/{run_id}/rejoin`.
322
- * - Chat/conversation resume keeps `code: "resume_conflict"` for older clients
323
- * but ALSO carries `live_request_id` + `rejoin_path` (+
324
- * `details.live_request_id`) when the run is live — then rejoin, never the
325
- * retry loop. A bare `resume_conflict` (no rejoin target) stays host retry.
322
+ * - Chat/conversation resume answers `code: "resume_conflict"` — even when the
323
+ * body ALSO names `live_request_id` + `rejoin_path` — and it is ALWAYS host
324
+ * retry, never a rejoin: the claim holder is usually the turn that is still
325
+ * SUSPENDING, and rejoining it replays that turn from frame one (duplicate
326
+ * text) while the person's continuation never runs. Only
327
+ * `code: run_in_progress` rejoins.
326
328
  * - The envelope RESERVES `request_id` for the refusing call's own id — the
327
329
  * live run is read from `live_request_id`, never `request_id` (reading it
328
330
  * rejoined a request that did not exist: 404, 2026-10-01).
@@ -360,15 +362,16 @@ interface MatrxLiveRunRejoin {
360
362
  rejoinPath: string;
361
363
  /** `run_id` extra (workflow / SEO / comparison), when present. */
362
364
  runId: string | null;
363
- /** The refusal's code: `run_in_progress`, or chat's `resume_conflict` carrying a rejoin target. */
365
+ /** The refusal's code — always `run_in_progress` (chat's `resume_conflict` is retried, never rejoined). */
364
366
  code: string;
365
367
  /** The refusal body (root of the envelope), for door-specific extras (`arm_index`, `analysis_id`, …). */
366
368
  body: Record<string, unknown>;
367
369
  }
368
370
  /**
369
- * The rejoin target of a live-run refusal: `409` with `code: run_in_progress`,
370
- * or chat's `409 resume_conflict` that names a live run. Null for every other
371
- * error (a genuine failure is never mistaken for a live run). Reads
371
+ * The rejoin target of a live-run refusal: `409` with `code: run_in_progress`.
372
+ * Null for every other error — a genuine failure is never mistaken for a live
373
+ * run, and chat's `resume_conflict` is never a rejoin even when its body names
374
+ * one (the host retries the resume so the continuation runs). Reads
372
375
  * `rejoin_path` from the body first; derives the runtime rejoin from
373
376
  * `live_request_id` only when the body names no path. Never reads
374
377
  * `request_id`.
@@ -382,9 +385,9 @@ declare function readLiveRunRejoin(error: unknown): MatrxLiveRunRejoin | null;
382
385
  */
383
386
  declare function readLiveRunRequestId(error: unknown): string | null;
384
387
  /**
385
- * A bare `409 resume_conflict` — another resume holds the claim and NO live
386
- * run is named; retry is host policy. (A `resume_conflict` that names a live
387
- * run is a rejoin — `readLiveRunRejoin`.)
388
+ * `409 resume_conflict` — another run holds the conversation's claim (usually
389
+ * the turn still suspending); retry the resume with the host's backoff so the
390
+ * continuation runs. Never a rejoin, even when the body names a live run.
388
391
  */
389
392
  declare function isResumeConflict(error: unknown): boolean;
390
393
  /** `409 live_stream_unavailable` — the rejoin journal is gone; follow the durable lifecycle instead. */
@@ -464,7 +467,7 @@ type ResumeOrRejoinOutcome =
464
467
  runId: string;
465
468
  ended: boolean;
466
469
  }
467
- /** A bare `409 resume_conflict` (no live run named) — retry with the host's backoff policy. */
470
+ /** `409 resume_conflict` (named live run or not) — retry with the host's backoff policy. */
468
471
  | {
469
472
  kind: "resume_conflict";
470
473
  error: MatrxApiError;
@@ -488,15 +491,106 @@ interface ResumeOrRejoinOptions extends Omit<MatrxStreamCallOptions, "signal"> {
488
491
  * Resume a run — or, when the server says it is still live, REJOIN it.
489
492
  *
490
493
  * Calls `resumeCall` (the feature's resume door) and pipes its stream into
491
- * `onEnvelope`. On a live-run refusal (`run_in_progress`, or chat's
492
- * `resume_conflict` naming a live run) it follows the body's `rejoin_path`
494
+ * `onEnvelope`. On a live-run refusal (`run_in_progress`) it follows the body's `rejoin_path`
493
495
  * into the SAME handler under the same organization; when the rejoin has no
494
496
  * journal (`live_stream_unavailable`) it follows the workflow run SSE (body
495
497
  * names a workflow `run_id`) or the durable lifecycle. Never runs a live run a
496
- * second time. A bare `resume_conflict` comes back as an outcome; any other
498
+ * second time. Every `resume_conflict` comes back as an outcome; any other
497
499
  * error is thrown.
498
500
  */
499
501
  declare function resumeOrRejoin(transport: MatrxTransport, resumeCall: (transport: MatrxTransport, options: MatrxStreamCallOptions) => Promise<MatrxRunHandle>, options: ResumeOrRejoinOptions): Promise<ResumeOrRejoinOutcome>;
502
+ /** What a `409 live_stream_unavailable` rejoin answer names: a workflow `run_id`, when it has one. */
503
+ interface MatrxLiveStreamUnavailable {
504
+ runId: string | null;
505
+ }
506
+ /**
507
+ * Read a rejoin's `409 live_stream_unavailable` (the journal is gone). Null
508
+ * for every other error. For hosts that open the rejoin stream themselves —
509
+ * hand the result to `followUnavailableRejoin`.
510
+ */
511
+ declare function readLiveStreamUnavailable(error: unknown): MatrxLiveStreamUnavailable | null;
512
+ type MatrxFollowedOutcome = Extract<ResumeOrRejoinOutcome, {
513
+ kind: "followed" | "followed_workflow";
514
+ }>;
515
+ interface FollowUnavailableRejoinOptions {
516
+ /** THE RUN'S organization; omit when `transport` is already bound to it. */
517
+ organizationId?: string | null;
518
+ signal?: AbortSignal;
519
+ onOperationEvent?: (event: MatrxRuntimeOperationEvent) => void;
520
+ onWorkflowEvent?: (event: Record<string, unknown>, seq: number | null) => void;
521
+ follow?: Omit<FollowRuntimeOperationToEndOptions, "onEvent" | "signal" | "lastEventSeq">;
522
+ }
523
+ /**
524
+ * The no-journal fallback of a rejoin — the SAME branch `resumeOrRejoin`
525
+ * takes, exported for hosts whose rejoin stream rides their own wire (the
526
+ * extension's offscreen fetch, the desktop's request loop). A workflow
527
+ * `run_id` (from the unavailable body, else the refusal) on a runtime rejoin
528
+ * → follow the workflow run SSE; otherwise read the live operation and
529
+ * follow it to its end. Settle the result with `settleRunPickup`.
530
+ */
531
+ declare function followUnavailableRejoin(transport: MatrxTransport, rejoin: MatrxLiveRunRejoin, unavailable: MatrxLiveStreamUnavailable, options?: FollowUnavailableRejoinOptions): Promise<MatrxFollowedOutcome>;
532
+ /**
533
+ * The parts of a pick-up result `settleRunPickup` reads — every
534
+ * `ResumeOrRejoinOutcome` is one, and so is a host's own follow result.
535
+ */
536
+ type MatrxRunPickup = {
537
+ kind: "resumed" | "rejoined";
538
+ } | {
539
+ kind: "resume_conflict";
540
+ } | {
541
+ kind: "followed";
542
+ executionId: string | null;
543
+ ended: boolean;
544
+ status: MatrxRuntimeExecutionStatus | null;
545
+ } | {
546
+ kind: "followed_workflow";
547
+ ended: boolean;
548
+ };
549
+ type MatrxRunPickupSettlement =
550
+ /** The turn arrived on a stream the host already rendered — nothing to reload. */
551
+ {
552
+ state: "streamed";
553
+ }
554
+ /** Bare `resume_conflict` — retry with the host's backoff. */
555
+ | {
556
+ state: "retry";
557
+ }
558
+ /**
559
+ * The run is over (or no live operation remains): the SAVED turn was
560
+ * reloaded — that is the answer to show, never an empty bubble and never a
561
+ * failure the run did not have. `status` null = unknown (workflow / none
562
+ * found); `reloaded: false` = the reload itself threw (`error`).
563
+ */
564
+ | {
565
+ state: "settled";
566
+ status: MatrxRuntimeExecutionStatus | null;
567
+ reloaded: boolean;
568
+ error?: unknown;
569
+ }
570
+ /** The follow gave up while the run may still be live; `onStillRunning` (default: reload what is saved) ran. */
571
+ | {
572
+ state: "still_running";
573
+ reloaded: boolean;
574
+ error?: unknown;
575
+ };
576
+ interface SettleRunPickupOptions {
577
+ /** Re-read the feature's saved record (the conversation's messages) into the screen. */
578
+ reloadSavedTurn: () => Promise<void> | void;
579
+ /**
580
+ * The follow gave up on a run that may still be live. Default: reload what
581
+ * is saved now. A host with its own patient recovery (the web app's
582
+ * dropped-stream poll) passes it here instead.
583
+ */
584
+ onStillRunning?: () => Promise<void> | void;
585
+ }
586
+ /**
587
+ * THE one mapping from a pick-up result to what the screen does, shared by
588
+ * every chat client so a live run that cannot replay ends the same way
589
+ * everywhere: streamed → done; bare conflict → retry; followed to its end
590
+ * (or nothing live left to follow) → reload the saved turn and report the
591
+ * run's real status; follow gave up → still running (never "failed").
592
+ */
593
+ declare function settleRunPickup(pickup: MatrxRunPickup, options: SettleRunPickupOptions): Promise<MatrxRunPickupSettlement>;
500
594
 
501
595
  /**
502
596
  * Browser-held provider sessions report their failures through the server.
@@ -637,4 +731,4 @@ declare function listUserPendingToolCalls(transport: MatrxTransport, options?: {
637
731
  signal?: AbortSignal;
638
732
  }): Promise<MatrxPendingCallSummary[]>;
639
733
 
640
- export { type CreateMatrxTransportOptions, FollowRuntimeOperationToEndOptions, MATRX_AI_API_VERSION_DEFAULT, MATRX_LIVE_STREAM_UNAVAILABLE, MATRX_RESUME_CONFLICT, MATRX_RUN_IN_PROGRESS, type MatrxAiApiVersion, MatrxApiError, type MatrxCallError, type MatrxClientSessionProvider, type MatrxClientToolResult, type MatrxHttpErrorLike, MatrxJsonObject, MatrxJsonValue, type MatrxLiveRunRejoin, type MatrxPendingCallSummary, type MatrxProtocolDowngrade, type MatrxProtocolFallbackOptions, type MatrxRequestInfo, MatrxRunHandle, MatrxRuntimeExecutionStatus, MatrxRuntimeOperationEvent, MatrxStreamCallOptions, type MatrxToolResultsResponse, MatrxTransport, type MatrxTransportDiagnostics, type MatrxTransportTarget, OrganizationContextError, type OrganizationContextErrorCode, type OrganizationOperation, type ProviderSessionFailure, type ProviderSessionFailureVerdict, type ResumeOrRejoinOptions, type ResumeOrRejoinOutcome, V2_COVERED_AI_PATH_TEMPLATES, applyAiApiVersion, applyOrganizationContextHeader, assertOrganizationMatchesOperation, assertQueryOrganizationMatchesContext, createMatrxTransport, createOrganizationOperation, fetchWithMatrxProtocolFallback, followWorkflowRunEvents, isCoveredAiPath, isLiveStreamUnavailable, isResumeConflict, isV2Path, listConversationPendingToolCalls, listUserPendingToolCalls, normalizeMatrxError, openMatrxStream, providerSessionFailureBody, readLiveRunRejoin, readLiveRunRequestId, readMatrxErrorCode, reportProviderSessionFailure, requireOrganizationContext, resumeOrRejoin, runtimeOperationRejoinPath, streamErrorText, submitAgentToolResults, toV1FallbackUrl, toV2Path, withRunOrganization };
734
+ export { type CreateMatrxTransportOptions, FollowRuntimeOperationToEndOptions, type FollowUnavailableRejoinOptions, MATRX_AI_API_VERSION_DEFAULT, MATRX_LIVE_STREAM_UNAVAILABLE, MATRX_RESUME_CONFLICT, MATRX_RUN_IN_PROGRESS, type MatrxAiApiVersion, MatrxApiError, type MatrxCallError, type MatrxClientSessionProvider, type MatrxClientToolResult, type MatrxFollowedOutcome, type MatrxHttpErrorLike, MatrxJsonObject, MatrxJsonValue, type MatrxLiveRunRejoin, type MatrxLiveStreamUnavailable, type MatrxPendingCallSummary, type MatrxProtocolDowngrade, type MatrxProtocolFallbackOptions, type MatrxRequestInfo, MatrxRunHandle, type MatrxRunPickup, type MatrxRunPickupSettlement, MatrxRuntimeExecutionStatus, MatrxRuntimeOperationEvent, MatrxStreamCallOptions, type MatrxToolResultsResponse, MatrxTransport, type MatrxTransportDiagnostics, type MatrxTransportTarget, OrganizationContextError, type OrganizationContextErrorCode, type OrganizationOperation, type ProviderSessionFailure, type ProviderSessionFailureVerdict, type ResumeOrRejoinOptions, type ResumeOrRejoinOutcome, type SettleRunPickupOptions, V2_COVERED_AI_PATH_TEMPLATES, applyAiApiVersion, applyOrganizationContextHeader, assertOrganizationMatchesOperation, assertQueryOrganizationMatchesContext, createMatrxTransport, createOrganizationOperation, fetchWithMatrxProtocolFallback, followUnavailableRejoin, followWorkflowRunEvents, isCoveredAiPath, isLiveStreamUnavailable, isResumeConflict, isV2Path, listConversationPendingToolCalls, listUserPendingToolCalls, normalizeMatrxError, openMatrxStream, providerSessionFailureBody, readLiveRunRejoin, readLiveRunRequestId, readLiveStreamUnavailable, readMatrxErrorCode, reportProviderSessionFailure, requireOrganizationContext, resumeOrRejoin, runtimeOperationRejoinPath, settleRunPickup, streamErrorText, submitAgentToolResults, toV1FallbackUrl, toV2Path, withRunOrganization };
@@ -1,4 +1,4 @@
1
- import { B as MatrxTransport, A as MatrxStreamCallOptions, w as MatrxRuntimeOperationEvent, a as FollowRuntimeOperationToEndOptions, v as MatrxRuntimeExecutionStatus, c as MatrxApiError, u as MatrxRunHandle, m as MatrxJsonValue, l as MatrxJsonObject } from '../operations-Dp4ut-ac.js';
1
+ import { B as MatrxTransport, w as MatrxRuntimeOperationEvent, a as FollowRuntimeOperationToEndOptions, v as MatrxRuntimeExecutionStatus, c as MatrxApiError, A as MatrxStreamCallOptions, u as MatrxRunHandle, m as MatrxJsonValue, l as MatrxJsonObject } from '../operations-Dp4ut-ac.js';
2
2
  export { F as FollowRuntimeOperationOptions, b as FollowRuntimeOperationToEndResult, M as MatrxAgentStartRequest, d as MatrxCancelResponse, e as MatrxChatMessage, f as MatrxCompletedRun, g as MatrxContextAnchor, h as MatrxConversationContinueRequest, i as MatrxConversationResumeRequest, j as MatrxConversationStart, k as MatrxEphemeralConversation, n as MatrxMandateStartRequest, o as MatrxOperationEventsPage, p as MatrxOperationFollowEvent, q as MatrxOperationStatusResponse, r as MatrxOperationsByLinkResponse, s as MatrxRequestScope, t as MatrxRunError, x as MatrxRuntimeOperationView, y as MatrxStoredConversationContinue, z as MatrxStoredConversationCreate, C as MatrxTransportRequest, D as MatrxTurnFields, R as RunAgentToCompletionOptions, T as TERMINAL_MATRX_RUNTIME_STATUSES, E as cancelAgentRun, G as continueAgentConversation, H as continueEphemeralConversationStart, I as continueStoredConversationStart, J as extractMatrxErrorCode, K as extractMatrxErrorMessage, L as followRuntimeOperationEvents, N as followRuntimeOperationToEnd, O as getRuntimeOperationStatus, P as getRuntimeOperationsByLink, Q as listRuntimeOperationEvents, S as mintMatrxConversationId, U as newEphemeralConversationStart, V as newStoredConversationStart, W as rejoinRuntimeOperation, X as resumeAgentConversation, Y as runAgentToCompletion, Z as startAgentRun, _ as startMandateRun } from '../operations-Dp4ut-ac.js';
3
3
  import { CredentialsPort } from '@ai-matrx/data';
4
4
  import { ResilientFetchOptions } from '@ai-matrx/data/net';
@@ -319,10 +319,12 @@ declare function assertQueryOrganizationMatchesContext(queryParams: Record<strin
319
319
  * `arm`, `analysis_id`). The client follows `rejoin_path` — never a URL it
320
320
  * builds — because a door outside the spine (SEO collections) answers
321
321
  * `live_request_id: null` with its own `/seo/collections/{run_id}/rejoin`.
322
- * - Chat/conversation resume keeps `code: "resume_conflict"` for older clients
323
- * but ALSO carries `live_request_id` + `rejoin_path` (+
324
- * `details.live_request_id`) when the run is live — then rejoin, never the
325
- * retry loop. A bare `resume_conflict` (no rejoin target) stays host retry.
322
+ * - Chat/conversation resume answers `code: "resume_conflict"` — even when the
323
+ * body ALSO names `live_request_id` + `rejoin_path` — and it is ALWAYS host
324
+ * retry, never a rejoin: the claim holder is usually the turn that is still
325
+ * SUSPENDING, and rejoining it replays that turn from frame one (duplicate
326
+ * text) while the person's continuation never runs. Only
327
+ * `code: run_in_progress` rejoins.
326
328
  * - The envelope RESERVES `request_id` for the refusing call's own id — the
327
329
  * live run is read from `live_request_id`, never `request_id` (reading it
328
330
  * rejoined a request that did not exist: 404, 2026-10-01).
@@ -360,15 +362,16 @@ interface MatrxLiveRunRejoin {
360
362
  rejoinPath: string;
361
363
  /** `run_id` extra (workflow / SEO / comparison), when present. */
362
364
  runId: string | null;
363
- /** The refusal's code: `run_in_progress`, or chat's `resume_conflict` carrying a rejoin target. */
365
+ /** The refusal's code — always `run_in_progress` (chat's `resume_conflict` is retried, never rejoined). */
364
366
  code: string;
365
367
  /** The refusal body (root of the envelope), for door-specific extras (`arm_index`, `analysis_id`, …). */
366
368
  body: Record<string, unknown>;
367
369
  }
368
370
  /**
369
- * The rejoin target of a live-run refusal: `409` with `code: run_in_progress`,
370
- * or chat's `409 resume_conflict` that names a live run. Null for every other
371
- * error (a genuine failure is never mistaken for a live run). Reads
371
+ * The rejoin target of a live-run refusal: `409` with `code: run_in_progress`.
372
+ * Null for every other error — a genuine failure is never mistaken for a live
373
+ * run, and chat's `resume_conflict` is never a rejoin even when its body names
374
+ * one (the host retries the resume so the continuation runs). Reads
372
375
  * `rejoin_path` from the body first; derives the runtime rejoin from
373
376
  * `live_request_id` only when the body names no path. Never reads
374
377
  * `request_id`.
@@ -382,9 +385,9 @@ declare function readLiveRunRejoin(error: unknown): MatrxLiveRunRejoin | null;
382
385
  */
383
386
  declare function readLiveRunRequestId(error: unknown): string | null;
384
387
  /**
385
- * A bare `409 resume_conflict` — another resume holds the claim and NO live
386
- * run is named; retry is host policy. (A `resume_conflict` that names a live
387
- * run is a rejoin — `readLiveRunRejoin`.)
388
+ * `409 resume_conflict` — another run holds the conversation's claim (usually
389
+ * the turn still suspending); retry the resume with the host's backoff so the
390
+ * continuation runs. Never a rejoin, even when the body names a live run.
388
391
  */
389
392
  declare function isResumeConflict(error: unknown): boolean;
390
393
  /** `409 live_stream_unavailable` — the rejoin journal is gone; follow the durable lifecycle instead. */
@@ -464,7 +467,7 @@ type ResumeOrRejoinOutcome =
464
467
  runId: string;
465
468
  ended: boolean;
466
469
  }
467
- /** A bare `409 resume_conflict` (no live run named) — retry with the host's backoff policy. */
470
+ /** `409 resume_conflict` (named live run or not) — retry with the host's backoff policy. */
468
471
  | {
469
472
  kind: "resume_conflict";
470
473
  error: MatrxApiError;
@@ -488,15 +491,106 @@ interface ResumeOrRejoinOptions extends Omit<MatrxStreamCallOptions, "signal"> {
488
491
  * Resume a run — or, when the server says it is still live, REJOIN it.
489
492
  *
490
493
  * Calls `resumeCall` (the feature's resume door) and pipes its stream into
491
- * `onEnvelope`. On a live-run refusal (`run_in_progress`, or chat's
492
- * `resume_conflict` naming a live run) it follows the body's `rejoin_path`
494
+ * `onEnvelope`. On a live-run refusal (`run_in_progress`) it follows the body's `rejoin_path`
493
495
  * into the SAME handler under the same organization; when the rejoin has no
494
496
  * journal (`live_stream_unavailable`) it follows the workflow run SSE (body
495
497
  * names a workflow `run_id`) or the durable lifecycle. Never runs a live run a
496
- * second time. A bare `resume_conflict` comes back as an outcome; any other
498
+ * second time. Every `resume_conflict` comes back as an outcome; any other
497
499
  * error is thrown.
498
500
  */
499
501
  declare function resumeOrRejoin(transport: MatrxTransport, resumeCall: (transport: MatrxTransport, options: MatrxStreamCallOptions) => Promise<MatrxRunHandle>, options: ResumeOrRejoinOptions): Promise<ResumeOrRejoinOutcome>;
502
+ /** What a `409 live_stream_unavailable` rejoin answer names: a workflow `run_id`, when it has one. */
503
+ interface MatrxLiveStreamUnavailable {
504
+ runId: string | null;
505
+ }
506
+ /**
507
+ * Read a rejoin's `409 live_stream_unavailable` (the journal is gone). Null
508
+ * for every other error. For hosts that open the rejoin stream themselves —
509
+ * hand the result to `followUnavailableRejoin`.
510
+ */
511
+ declare function readLiveStreamUnavailable(error: unknown): MatrxLiveStreamUnavailable | null;
512
+ type MatrxFollowedOutcome = Extract<ResumeOrRejoinOutcome, {
513
+ kind: "followed" | "followed_workflow";
514
+ }>;
515
+ interface FollowUnavailableRejoinOptions {
516
+ /** THE RUN'S organization; omit when `transport` is already bound to it. */
517
+ organizationId?: string | null;
518
+ signal?: AbortSignal;
519
+ onOperationEvent?: (event: MatrxRuntimeOperationEvent) => void;
520
+ onWorkflowEvent?: (event: Record<string, unknown>, seq: number | null) => void;
521
+ follow?: Omit<FollowRuntimeOperationToEndOptions, "onEvent" | "signal" | "lastEventSeq">;
522
+ }
523
+ /**
524
+ * The no-journal fallback of a rejoin — the SAME branch `resumeOrRejoin`
525
+ * takes, exported for hosts whose rejoin stream rides their own wire (the
526
+ * extension's offscreen fetch, the desktop's request loop). A workflow
527
+ * `run_id` (from the unavailable body, else the refusal) on a runtime rejoin
528
+ * → follow the workflow run SSE; otherwise read the live operation and
529
+ * follow it to its end. Settle the result with `settleRunPickup`.
530
+ */
531
+ declare function followUnavailableRejoin(transport: MatrxTransport, rejoin: MatrxLiveRunRejoin, unavailable: MatrxLiveStreamUnavailable, options?: FollowUnavailableRejoinOptions): Promise<MatrxFollowedOutcome>;
532
+ /**
533
+ * The parts of a pick-up result `settleRunPickup` reads — every
534
+ * `ResumeOrRejoinOutcome` is one, and so is a host's own follow result.
535
+ */
536
+ type MatrxRunPickup = {
537
+ kind: "resumed" | "rejoined";
538
+ } | {
539
+ kind: "resume_conflict";
540
+ } | {
541
+ kind: "followed";
542
+ executionId: string | null;
543
+ ended: boolean;
544
+ status: MatrxRuntimeExecutionStatus | null;
545
+ } | {
546
+ kind: "followed_workflow";
547
+ ended: boolean;
548
+ };
549
+ type MatrxRunPickupSettlement =
550
+ /** The turn arrived on a stream the host already rendered — nothing to reload. */
551
+ {
552
+ state: "streamed";
553
+ }
554
+ /** Bare `resume_conflict` — retry with the host's backoff. */
555
+ | {
556
+ state: "retry";
557
+ }
558
+ /**
559
+ * The run is over (or no live operation remains): the SAVED turn was
560
+ * reloaded — that is the answer to show, never an empty bubble and never a
561
+ * failure the run did not have. `status` null = unknown (workflow / none
562
+ * found); `reloaded: false` = the reload itself threw (`error`).
563
+ */
564
+ | {
565
+ state: "settled";
566
+ status: MatrxRuntimeExecutionStatus | null;
567
+ reloaded: boolean;
568
+ error?: unknown;
569
+ }
570
+ /** The follow gave up while the run may still be live; `onStillRunning` (default: reload what is saved) ran. */
571
+ | {
572
+ state: "still_running";
573
+ reloaded: boolean;
574
+ error?: unknown;
575
+ };
576
+ interface SettleRunPickupOptions {
577
+ /** Re-read the feature's saved record (the conversation's messages) into the screen. */
578
+ reloadSavedTurn: () => Promise<void> | void;
579
+ /**
580
+ * The follow gave up on a run that may still be live. Default: reload what
581
+ * is saved now. A host with its own patient recovery (the web app's
582
+ * dropped-stream poll) passes it here instead.
583
+ */
584
+ onStillRunning?: () => Promise<void> | void;
585
+ }
586
+ /**
587
+ * THE one mapping from a pick-up result to what the screen does, shared by
588
+ * every chat client so a live run that cannot replay ends the same way
589
+ * everywhere: streamed → done; bare conflict → retry; followed to its end
590
+ * (or nothing live left to follow) → reload the saved turn and report the
591
+ * run's real status; follow gave up → still running (never "failed").
592
+ */
593
+ declare function settleRunPickup(pickup: MatrxRunPickup, options: SettleRunPickupOptions): Promise<MatrxRunPickupSettlement>;
500
594
 
501
595
  /**
502
596
  * Browser-held provider sessions report their failures through the server.
@@ -637,4 +731,4 @@ declare function listUserPendingToolCalls(transport: MatrxTransport, options?: {
637
731
  signal?: AbortSignal;
638
732
  }): Promise<MatrxPendingCallSummary[]>;
639
733
 
640
- export { type CreateMatrxTransportOptions, FollowRuntimeOperationToEndOptions, MATRX_AI_API_VERSION_DEFAULT, MATRX_LIVE_STREAM_UNAVAILABLE, MATRX_RESUME_CONFLICT, MATRX_RUN_IN_PROGRESS, type MatrxAiApiVersion, MatrxApiError, type MatrxCallError, type MatrxClientSessionProvider, type MatrxClientToolResult, type MatrxHttpErrorLike, MatrxJsonObject, MatrxJsonValue, type MatrxLiveRunRejoin, type MatrxPendingCallSummary, type MatrxProtocolDowngrade, type MatrxProtocolFallbackOptions, type MatrxRequestInfo, MatrxRunHandle, MatrxRuntimeExecutionStatus, MatrxRuntimeOperationEvent, MatrxStreamCallOptions, type MatrxToolResultsResponse, MatrxTransport, type MatrxTransportDiagnostics, type MatrxTransportTarget, OrganizationContextError, type OrganizationContextErrorCode, type OrganizationOperation, type ProviderSessionFailure, type ProviderSessionFailureVerdict, type ResumeOrRejoinOptions, type ResumeOrRejoinOutcome, V2_COVERED_AI_PATH_TEMPLATES, applyAiApiVersion, applyOrganizationContextHeader, assertOrganizationMatchesOperation, assertQueryOrganizationMatchesContext, createMatrxTransport, createOrganizationOperation, fetchWithMatrxProtocolFallback, followWorkflowRunEvents, isCoveredAiPath, isLiveStreamUnavailable, isResumeConflict, isV2Path, listConversationPendingToolCalls, listUserPendingToolCalls, normalizeMatrxError, openMatrxStream, providerSessionFailureBody, readLiveRunRejoin, readLiveRunRequestId, readMatrxErrorCode, reportProviderSessionFailure, requireOrganizationContext, resumeOrRejoin, runtimeOperationRejoinPath, streamErrorText, submitAgentToolResults, toV1FallbackUrl, toV2Path, withRunOrganization };
734
+ export { type CreateMatrxTransportOptions, FollowRuntimeOperationToEndOptions, type FollowUnavailableRejoinOptions, MATRX_AI_API_VERSION_DEFAULT, MATRX_LIVE_STREAM_UNAVAILABLE, MATRX_RESUME_CONFLICT, MATRX_RUN_IN_PROGRESS, type MatrxAiApiVersion, MatrxApiError, type MatrxCallError, type MatrxClientSessionProvider, type MatrxClientToolResult, type MatrxFollowedOutcome, type MatrxHttpErrorLike, MatrxJsonObject, MatrxJsonValue, type MatrxLiveRunRejoin, type MatrxLiveStreamUnavailable, type MatrxPendingCallSummary, type MatrxProtocolDowngrade, type MatrxProtocolFallbackOptions, type MatrxRequestInfo, MatrxRunHandle, type MatrxRunPickup, type MatrxRunPickupSettlement, MatrxRuntimeExecutionStatus, MatrxRuntimeOperationEvent, MatrxStreamCallOptions, type MatrxToolResultsResponse, MatrxTransport, type MatrxTransportDiagnostics, type MatrxTransportTarget, OrganizationContextError, type OrganizationContextErrorCode, type OrganizationOperation, type ProviderSessionFailure, type ProviderSessionFailureVerdict, type ResumeOrRejoinOptions, type ResumeOrRejoinOutcome, type SettleRunPickupOptions, V2_COVERED_AI_PATH_TEMPLATES, applyAiApiVersion, applyOrganizationContextHeader, assertOrganizationMatchesOperation, assertQueryOrganizationMatchesContext, createMatrxTransport, createOrganizationOperation, fetchWithMatrxProtocolFallback, followUnavailableRejoin, followWorkflowRunEvents, isCoveredAiPath, isLiveStreamUnavailable, isResumeConflict, isV2Path, listConversationPendingToolCalls, listUserPendingToolCalls, normalizeMatrxError, openMatrxStream, providerSessionFailureBody, readLiveRunRejoin, readLiveRunRequestId, readLiveStreamUnavailable, readMatrxErrorCode, reportProviderSessionFailure, requireOrganizationContext, resumeOrRejoin, runtimeOperationRejoinPath, settleRunPickup, streamErrorText, submitAgentToolResults, toV1FallbackUrl, toV2Path, withRunOrganization };
@@ -871,18 +871,18 @@ async function followRuntimeOperationToEnd(transport, executionId, options) {
871
871
  let cursor = options.lastEventSeq ?? 0;
872
872
  let failures = 0;
873
873
  while (!outer?.aborted && failures < reconnectLimit) {
874
- const attempt = new AbortController();
875
- const onOuterAbort = () => attempt.abort();
874
+ const attempt2 = new AbortController();
875
+ const onOuterAbort = () => attempt2.abort();
876
876
  outer?.addEventListener("abort", onOuterAbort, { once: true });
877
877
  let stallTimer = null;
878
878
  const armStall = () => {
879
879
  if (stallTimer !== null) clearTimeout(stallTimer);
880
- stallTimer = setTimeout(() => attempt.abort(), stallTimeoutMs);
880
+ stallTimer = setTimeout(() => attempt2.abort(), stallTimeoutMs);
881
881
  };
882
882
  try {
883
883
  const items = followRuntimeOperationEvents(transport, executionId, {
884
884
  lastEventSeq: cursor,
885
- signal: attempt.signal,
885
+ signal: attempt2.signal,
886
886
  ...options.onMalformedFrame ? { onMalformedFrame: options.onMalformedFrame } : {}
887
887
  });
888
888
  armStall();
@@ -977,7 +977,7 @@ function readLiveRunRejoin(error) {
977
977
  const candidates = detailCandidates(bodyOf(error));
978
978
  if (candidates.length === 0) return null;
979
979
  const code = readMatrxErrorCode(error);
980
- if (code !== MATRX_RUN_IN_PROGRESS && code !== MATRX_RESUME_CONFLICT) return null;
980
+ if (code !== MATRX_RUN_IN_PROGRESS) return null;
981
981
  const liveRequestId = firstString(candidates, "live_request_id");
982
982
  const pathFromBody = firstString(candidates, "rejoin_path");
983
983
  const rejoinPath = pathFromBody && pathFromBody.startsWith("/") ? pathFromBody : liveRequestId ? runtimeOperationRejoinPath(liveRequestId) : null;
@@ -995,7 +995,7 @@ function readLiveRunRequestId(error) {
995
995
  return readLiveRunRejoin(error)?.liveRequestId ?? null;
996
996
  }
997
997
  function isResumeConflict(error) {
998
- return statusOf(error) === 409 && readMatrxErrorCode(error) === MATRX_RESUME_CONFLICT && readLiveRunRejoin(error) === null;
998
+ return statusOf(error) === 409 && readMatrxErrorCode(error) === MATRX_RESUME_CONFLICT;
999
999
  }
1000
1000
  function isLiveStreamUnavailable(error) {
1001
1001
  return statusOf(error) === 409 && readMatrxErrorCode(error) === MATRX_LIVE_STREAM_UNAVAILABLE;
@@ -1098,7 +1098,7 @@ async function resumeOrRejoin(transport, resumeCall, options) {
1098
1098
  rejoin = target;
1099
1099
  }
1100
1100
  onRejoin?.(rejoin);
1101
- let unavailableBody;
1101
+ let unavailable;
1102
1102
  try {
1103
1103
  const handle = await openMatrxStream(bound, rejoin.rejoinPath, {
1104
1104
  ...streamOptions,
@@ -1108,14 +1108,29 @@ async function resumeOrRejoin(transport, resumeCall, options) {
1108
1108
  await drain(handle, onEnvelope);
1109
1109
  return { kind: "rejoined", rejoin };
1110
1110
  } catch (error) {
1111
- if (!isLiveStreamUnavailable(error)) throw error;
1112
- unavailableBody = bodyOf(error);
1111
+ const read = readLiveStreamUnavailable(error);
1112
+ if (!read) throw error;
1113
+ unavailable = read;
1113
1114
  }
1114
- const runId = firstString(detailCandidates(unavailableBody), "run_id") ?? rejoin.runId;
1115
+ return followUnavailableRejoin(bound, rejoin, unavailable, {
1116
+ ...signalOnly,
1117
+ ...onOperationEvent ? { onOperationEvent } : {},
1118
+ ...onWorkflowEvent ? { onWorkflowEvent } : {},
1119
+ ...follow ? { follow } : {}
1120
+ });
1121
+ }
1122
+ function readLiveStreamUnavailable(error) {
1123
+ if (!isLiveStreamUnavailable(error)) return null;
1124
+ return { runId: firstString(detailCandidates(bodyOf(error)), "run_id") };
1125
+ }
1126
+ async function followUnavailableRejoin(transport, rejoin, unavailable, options = {}) {
1127
+ const bound = options.organizationId ? withRunOrganization(transport, options.organizationId) : transport;
1128
+ const signalOnly = options.signal ? { signal: options.signal } : {};
1129
+ const runId = unavailable.runId ?? rejoin.runId;
1115
1130
  if (runId && rejoin.rejoinPath.startsWith("/runtime/operations/")) {
1116
1131
  const result2 = await followWorkflowRunEvents(bound, runId, {
1117
1132
  ...signalOnly,
1118
- onEvent: (event, seq) => onWorkflowEvent?.(event, seq)
1133
+ onEvent: (event, seq) => options.onWorkflowEvent?.(event, seq)
1119
1134
  });
1120
1135
  return { kind: "followed_workflow", rejoin, runId, ended: result2.ended };
1121
1136
  }
@@ -1135,10 +1150,10 @@ async function resumeOrRejoin(transport, resumeCall, options) {
1135
1150
  };
1136
1151
  }
1137
1152
  const result = await followRuntimeOperationToEnd(bound, operation.execution_id, {
1138
- ...follow,
1153
+ ...options.follow,
1139
1154
  lastEventSeq: operation.last_event_seq,
1140
1155
  ...signalOnly,
1141
- onEvent: (event) => onOperationEvent?.(event)
1156
+ onEvent: (event) => options.onOperationEvent?.(event)
1142
1157
  });
1143
1158
  return {
1144
1159
  kind: "followed",
@@ -1148,6 +1163,35 @@ async function resumeOrRejoin(transport, resumeCall, options) {
1148
1163
  status: result.status
1149
1164
  };
1150
1165
  }
1166
+ async function attempt(run) {
1167
+ try {
1168
+ await run();
1169
+ return { reloaded: true };
1170
+ } catch (error) {
1171
+ return { reloaded: false, error };
1172
+ }
1173
+ }
1174
+ async function settleRunPickup(pickup, options) {
1175
+ switch (pickup.kind) {
1176
+ case "resumed":
1177
+ case "rejoined":
1178
+ return { state: "streamed" };
1179
+ case "resume_conflict":
1180
+ return { state: "retry" };
1181
+ case "followed_workflow":
1182
+ case "followed": {
1183
+ const status = pickup.kind === "followed" ? pickup.status : null;
1184
+ const nothingLive = pickup.kind === "followed" && pickup.executionId === null;
1185
+ if (pickup.ended || nothingLive) {
1186
+ return { state: "settled", status, ...await attempt(options.reloadSavedTurn) };
1187
+ }
1188
+ return {
1189
+ state: "still_running",
1190
+ ...await attempt(options.onStillRunning ?? options.reloadSavedTurn)
1191
+ };
1192
+ }
1193
+ }
1194
+ }
1151
1195
 
1152
1196
  // matrx/run.ts
1153
1197
  async function streamCall(transport, path, body, options) {
@@ -1377,6 +1421,7 @@ export {
1377
1421
  fetchWithMatrxProtocolFallback,
1378
1422
  followRuntimeOperationEvents,
1379
1423
  followRuntimeOperationToEnd,
1424
+ followUnavailableRejoin,
1380
1425
  followWorkflowRunEvents,
1381
1426
  getRuntimeOperationStatus,
1382
1427
  getRuntimeOperationsByLink,
@@ -1395,6 +1440,7 @@ export {
1395
1440
  providerSessionFailureBody,
1396
1441
  readLiveRunRejoin,
1397
1442
  readLiveRunRequestId,
1443
+ readLiveStreamUnavailable,
1398
1444
  readMatrxErrorCode,
1399
1445
  rejoinRuntimeOperation,
1400
1446
  reportProviderSessionFailure,
@@ -1403,6 +1449,7 @@ export {
1403
1449
  resumeOrRejoin,
1404
1450
  runAgentToCompletion,
1405
1451
  runtimeOperationRejoinPath,
1452
+ settleRunPickup,
1406
1453
  startAgentRun,
1407
1454
  startMandateRun,
1408
1455
  streamErrorText,