@ai-matrx/agents 0.23.0 → 0.24.1
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.
- package/CHANGELOG.md +11 -0
- package/dist/content-transfer/index.cjs.map +1 -1
- package/dist/content-transfer/index.js.map +1 -1
- package/dist/content-transfer/react/index.cjs.map +1 -1
- package/dist/content-transfer/react/index.js.map +1 -1
- package/dist/index.cjs +108 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +108 -30
- package/dist/index.js.map +1 -1
- package/dist/mandates/index.cjs +2 -2
- package/dist/mandates/index.cjs.map +1 -1
- package/dist/mandates/index.d.cts +4 -4
- package/dist/mandates/index.d.ts +4 -4
- package/dist/mandates/index.js +2 -2
- package/dist/mandates/index.js.map +1 -1
- package/dist/matrx/index.cjs +108 -30
- package/dist/matrx/index.cjs.map +1 -1
- package/dist/matrx/index.d.cts +96 -39
- package/dist/matrx/index.d.ts +96 -39
- package/dist/matrx/index.js +108 -30
- package/dist/matrx/index.js.map +1 -1
- package/mandates/snapshots/keys.0.24.0.json +652 -0
- package/mandates/snapshots/keys.0.24.1.json +652 -0
- package/package.json +4 -4
package/dist/matrx/index.d.cts
CHANGED
|
@@ -310,22 +310,27 @@ declare function assertQueryOrganizationMatchesContext(queryParams: Record<strin
|
|
|
310
310
|
/**
|
|
311
311
|
* Resume-or-rejoin — the ONE client behavior for "pick a run back up".
|
|
312
312
|
*
|
|
313
|
-
* Server truth (
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
* (`
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
* `
|
|
322
|
-
* -
|
|
323
|
-
*
|
|
324
|
-
* when the
|
|
325
|
-
*
|
|
326
|
-
* -
|
|
327
|
-
*
|
|
328
|
-
*
|
|
313
|
+
* Server truth (aidream `services/runtime/FEATURE.md` § "A live run is
|
|
314
|
+
* REJOINED, never resumed beside itself"; `reconnect.run_in_progress_error`):
|
|
315
|
+
* - Every resume / retry / continue door asked to resume a run that is STILL
|
|
316
|
+
* LIVE answers `409` with, at the ROOT of the error body,
|
|
317
|
+
* `{error, code: "run_in_progress", live_request_id, rejoin_path, message,
|
|
318
|
+
* …extras}` (extras: `run_id` for workflow / SEO / comparison, `arm_index` /
|
|
319
|
+
* `arm`, `analysis_id`). The client follows `rejoin_path` — never a URL it
|
|
320
|
+
* builds — because a door outside the spine (SEO collections) answers
|
|
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.
|
|
326
|
+
* - The envelope RESERVES `request_id` for the refusing call's own id — the
|
|
327
|
+
* live run is read from `live_request_id`, never `request_id` (reading it
|
|
328
|
+
* rejoined a request that did not exist: 404, 2026-10-01).
|
|
329
|
+
* - A rejoin answers `409 live_stream_unavailable` when there is no journal to
|
|
330
|
+
* replay (resumed workflow legs, comparison arms). Then: a body naming a
|
|
331
|
+
* workflow `run_id` → follow `GET /runs/{run_id}/events/stream` (the workflow
|
|
332
|
+
* SSE, which also carries the node_stream media frames); otherwise follow the
|
|
333
|
+
* durable lifecycle (`followRuntimeOperationToEnd`).
|
|
329
334
|
*
|
|
330
335
|
* Resume and rejoin are work on an EXISTING run, so they carry THAT run's
|
|
331
336
|
* organization (`organizationId`), never whatever the session has selected.
|
|
@@ -347,14 +352,40 @@ interface MatrxHttpErrorLike {
|
|
|
347
352
|
* `error`) from `detail`, `details`, or the top level. Null when absent.
|
|
348
353
|
*/
|
|
349
354
|
declare function readMatrxErrorCode(error: unknown): string | null;
|
|
355
|
+
/** Where to rejoin a live run, read from a resume door's 409. */
|
|
356
|
+
interface MatrxLiveRunRejoin {
|
|
357
|
+
/** The live request (`GET /runtime/operations/{id}`); null for doors outside the spine (SEO). */
|
|
358
|
+
liveRequestId: string | null;
|
|
359
|
+
/** Server-relative path to `POST` for the NDJSON replay-then-follow. Always from the body when present. */
|
|
360
|
+
rejoinPath: string;
|
|
361
|
+
/** `run_id` extra (workflow / SEO / comparison), when present. */
|
|
362
|
+
runId: string | null;
|
|
363
|
+
/** The refusal's code: `run_in_progress`, or chat's `resume_conflict` carrying a rejoin target. */
|
|
364
|
+
code: string;
|
|
365
|
+
/** The refusal body (root of the envelope), for door-specific extras (`arm_index`, `analysis_id`, …). */
|
|
366
|
+
body: Record<string, unknown>;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
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
|
|
372
|
+
* `rejoin_path` from the body first; derives the runtime rejoin from
|
|
373
|
+
* `live_request_id` only when the body names no path. Never reads
|
|
374
|
+
* `request_id`.
|
|
375
|
+
*/
|
|
376
|
+
declare function readLiveRunRejoin(error: unknown): MatrxLiveRunRejoin | null;
|
|
350
377
|
/**
|
|
351
|
-
* The request id of a run that is STILL
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
378
|
+
* The request id of a run that is STILL LIVE, read from a resume door's
|
|
379
|
+
* refusal (`live_request_id` — never the envelope's own `request_id`). Null
|
|
380
|
+
* for every other error, and for a live refusal outside the spine (SEO) —
|
|
381
|
+
* follow `readLiveRunRejoin(error).rejoinPath` instead.
|
|
355
382
|
*/
|
|
356
383
|
declare function readLiveRunRequestId(error: unknown): string | null;
|
|
357
|
-
/**
|
|
384
|
+
/**
|
|
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
|
+
*/
|
|
358
389
|
declare function isResumeConflict(error: unknown): boolean;
|
|
359
390
|
/** `409 live_stream_unavailable` — the rejoin journal is gone; follow the durable lifecycle instead. */
|
|
360
391
|
declare function isLiveStreamUnavailable(error: unknown): boolean;
|
|
@@ -388,30 +419,52 @@ declare function openMatrxStream(transport: MatrxTransport, path: string, option
|
|
|
388
419
|
* resume/rejoin transport.
|
|
389
420
|
*/
|
|
390
421
|
declare function withRunOrganization(transport: MatrxTransport, organizationId: string): MatrxTransport;
|
|
422
|
+
/**
|
|
423
|
+
* Follow a workflow run's SSE (`GET /runs/{run_id}/events/stream`) — the
|
|
424
|
+
* rejoin fallback for workflow legs with no stream journal. Delivers every
|
|
425
|
+
* parsed event (durable run events with their seq; ephemeral `node_stream`
|
|
426
|
+
* frames — including `kind: "media"` — with seq null). One connection, no
|
|
427
|
+
* reconnect policy: resolves `{ended: true}` on the server's `end` frame,
|
|
428
|
+
* `{ended: false}` when the wire closes or the caller aborts.
|
|
429
|
+
*/
|
|
430
|
+
declare function followWorkflowRunEvents(transport: MatrxTransport, runId: string, options: {
|
|
431
|
+
onEvent: (event: Record<string, unknown>, seq: number | null) => void;
|
|
432
|
+
lastEventId?: number | null;
|
|
433
|
+
signal?: AbortSignal;
|
|
434
|
+
}): Promise<{
|
|
435
|
+
ended: boolean;
|
|
436
|
+
}>;
|
|
391
437
|
type ResumeOrRejoinOutcome =
|
|
392
438
|
/** The resume door ran the run; its stream was delivered to `onEnvelope`. */
|
|
393
439
|
{
|
|
394
440
|
kind: "resumed";
|
|
395
441
|
requestId: string | null;
|
|
396
442
|
}
|
|
397
|
-
/** The run was
|
|
443
|
+
/** The run was live; its stream (from `rejoin_path`) was replayed + followed into `onEnvelope`. */
|
|
398
444
|
| {
|
|
399
445
|
kind: "rejoined";
|
|
400
|
-
|
|
446
|
+
rejoin: MatrxLiveRunRejoin;
|
|
401
447
|
}
|
|
402
448
|
/**
|
|
403
|
-
* The run was
|
|
404
|
-
*
|
|
405
|
-
*
|
|
449
|
+
* The run was live but had no journal to replay; the durable lifecycle was
|
|
450
|
+
* followed instead. Re-query the feature's record for the result.
|
|
451
|
+
* `ended: false` = the follow gave up (or no operation was found).
|
|
406
452
|
*/
|
|
407
453
|
| {
|
|
408
454
|
kind: "followed";
|
|
409
|
-
|
|
455
|
+
rejoin: MatrxLiveRunRejoin;
|
|
410
456
|
executionId: string | null;
|
|
411
457
|
ended: boolean;
|
|
412
458
|
status: MatrxRuntimeExecutionStatus | null;
|
|
413
459
|
}
|
|
414
|
-
/**
|
|
460
|
+
/** No journal, and the run is a workflow: its run SSE was followed into `onWorkflowEvent`. */
|
|
461
|
+
| {
|
|
462
|
+
kind: "followed_workflow";
|
|
463
|
+
rejoin: MatrxLiveRunRejoin;
|
|
464
|
+
runId: string;
|
|
465
|
+
ended: boolean;
|
|
466
|
+
}
|
|
467
|
+
/** A bare `409 resume_conflict` (no live run named) — retry with the host's backoff policy. */
|
|
415
468
|
| {
|
|
416
469
|
kind: "resume_conflict";
|
|
417
470
|
error: MatrxApiError;
|
|
@@ -422,22 +475,26 @@ interface ResumeOrRejoinOptions extends Omit<MatrxStreamCallOptions, "signal"> {
|
|
|
422
475
|
/** THE RUN'S organization (from its durable record) — bound on every call. */
|
|
423
476
|
organizationId?: string | null;
|
|
424
477
|
signal?: AbortSignal;
|
|
425
|
-
/** Fired the moment a live run is detected, before the rejoin opens. */
|
|
426
|
-
onRejoin?: (
|
|
427
|
-
/** Durable lifecycle events while following (the no-
|
|
478
|
+
/** Fired the moment a live run is detected, before the rejoin opens (reset replay-sensitive state). */
|
|
479
|
+
onRejoin?: (rejoin: MatrxLiveRunRejoin) => void;
|
|
480
|
+
/** Durable lifecycle events while following (the no-journal fallback). */
|
|
428
481
|
onOperationEvent?: (event: MatrxRuntimeOperationEvent) => void;
|
|
429
|
-
/**
|
|
482
|
+
/** Workflow run SSE events (the no-journal fallback for a workflow `run_id`). */
|
|
483
|
+
onWorkflowEvent?: (event: Record<string, unknown>, seq: number | null) => void;
|
|
484
|
+
/** Tuning for the durable follow (stall / reconnect policy). */
|
|
430
485
|
follow?: Omit<FollowRuntimeOperationToEndOptions, "onEvent" | "signal" | "lastEventSeq">;
|
|
431
486
|
}
|
|
432
487
|
/**
|
|
433
|
-
* Resume a run — or, when the server says it is still
|
|
488
|
+
* Resume a run — or, when the server says it is still live, REJOIN it.
|
|
434
489
|
*
|
|
435
490
|
* Calls `resumeCall` (the feature's resume door) and pipes its stream into
|
|
436
|
-
* `onEnvelope`. On `
|
|
437
|
-
* `
|
|
438
|
-
* under the same organization; when
|
|
439
|
-
*
|
|
440
|
-
* `
|
|
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`
|
|
493
|
+
* into the SAME handler under the same organization; when the rejoin has no
|
|
494
|
+
* journal (`live_stream_unavailable`) it follows the workflow run SSE (body
|
|
495
|
+
* 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
|
|
497
|
+
* error is thrown.
|
|
441
498
|
*/
|
|
442
499
|
declare function resumeOrRejoin(transport: MatrxTransport, resumeCall: (transport: MatrxTransport, options: MatrxStreamCallOptions) => Promise<MatrxRunHandle>, options: ResumeOrRejoinOptions): Promise<ResumeOrRejoinOutcome>;
|
|
443
500
|
|
|
@@ -580,4 +637,4 @@ declare function listUserPendingToolCalls(transport: MatrxTransport, options?: {
|
|
|
580
637
|
signal?: AbortSignal;
|
|
581
638
|
}): Promise<MatrxPendingCallSummary[]>;
|
|
582
639
|
|
|
583
|
-
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 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, isCoveredAiPath, isLiveStreamUnavailable, isResumeConflict, isV2Path, listConversationPendingToolCalls, listUserPendingToolCalls, normalizeMatrxError, openMatrxStream, providerSessionFailureBody, readLiveRunRequestId, readMatrxErrorCode, reportProviderSessionFailure, requireOrganizationContext, resumeOrRejoin, runtimeOperationRejoinPath, streamErrorText, submitAgentToolResults, toV1FallbackUrl, toV2Path, withRunOrganization };
|
|
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 };
|
package/dist/matrx/index.d.ts
CHANGED
|
@@ -310,22 +310,27 @@ declare function assertQueryOrganizationMatchesContext(queryParams: Record<strin
|
|
|
310
310
|
/**
|
|
311
311
|
* Resume-or-rejoin — the ONE client behavior for "pick a run back up".
|
|
312
312
|
*
|
|
313
|
-
* Server truth (
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
* (`
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
* `
|
|
322
|
-
* -
|
|
323
|
-
*
|
|
324
|
-
* when the
|
|
325
|
-
*
|
|
326
|
-
* -
|
|
327
|
-
*
|
|
328
|
-
*
|
|
313
|
+
* Server truth (aidream `services/runtime/FEATURE.md` § "A live run is
|
|
314
|
+
* REJOINED, never resumed beside itself"; `reconnect.run_in_progress_error`):
|
|
315
|
+
* - Every resume / retry / continue door asked to resume a run that is STILL
|
|
316
|
+
* LIVE answers `409` with, at the ROOT of the error body,
|
|
317
|
+
* `{error, code: "run_in_progress", live_request_id, rejoin_path, message,
|
|
318
|
+
* …extras}` (extras: `run_id` for workflow / SEO / comparison, `arm_index` /
|
|
319
|
+
* `arm`, `analysis_id`). The client follows `rejoin_path` — never a URL it
|
|
320
|
+
* builds — because a door outside the spine (SEO collections) answers
|
|
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.
|
|
326
|
+
* - The envelope RESERVES `request_id` for the refusing call's own id — the
|
|
327
|
+
* live run is read from `live_request_id`, never `request_id` (reading it
|
|
328
|
+
* rejoined a request that did not exist: 404, 2026-10-01).
|
|
329
|
+
* - A rejoin answers `409 live_stream_unavailable` when there is no journal to
|
|
330
|
+
* replay (resumed workflow legs, comparison arms). Then: a body naming a
|
|
331
|
+
* workflow `run_id` → follow `GET /runs/{run_id}/events/stream` (the workflow
|
|
332
|
+
* SSE, which also carries the node_stream media frames); otherwise follow the
|
|
333
|
+
* durable lifecycle (`followRuntimeOperationToEnd`).
|
|
329
334
|
*
|
|
330
335
|
* Resume and rejoin are work on an EXISTING run, so they carry THAT run's
|
|
331
336
|
* organization (`organizationId`), never whatever the session has selected.
|
|
@@ -347,14 +352,40 @@ interface MatrxHttpErrorLike {
|
|
|
347
352
|
* `error`) from `detail`, `details`, or the top level. Null when absent.
|
|
348
353
|
*/
|
|
349
354
|
declare function readMatrxErrorCode(error: unknown): string | null;
|
|
355
|
+
/** Where to rejoin a live run, read from a resume door's 409. */
|
|
356
|
+
interface MatrxLiveRunRejoin {
|
|
357
|
+
/** The live request (`GET /runtime/operations/{id}`); null for doors outside the spine (SEO). */
|
|
358
|
+
liveRequestId: string | null;
|
|
359
|
+
/** Server-relative path to `POST` for the NDJSON replay-then-follow. Always from the body when present. */
|
|
360
|
+
rejoinPath: string;
|
|
361
|
+
/** `run_id` extra (workflow / SEO / comparison), when present. */
|
|
362
|
+
runId: string | null;
|
|
363
|
+
/** The refusal's code: `run_in_progress`, or chat's `resume_conflict` carrying a rejoin target. */
|
|
364
|
+
code: string;
|
|
365
|
+
/** The refusal body (root of the envelope), for door-specific extras (`arm_index`, `analysis_id`, …). */
|
|
366
|
+
body: Record<string, unknown>;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
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
|
|
372
|
+
* `rejoin_path` from the body first; derives the runtime rejoin from
|
|
373
|
+
* `live_request_id` only when the body names no path. Never reads
|
|
374
|
+
* `request_id`.
|
|
375
|
+
*/
|
|
376
|
+
declare function readLiveRunRejoin(error: unknown): MatrxLiveRunRejoin | null;
|
|
350
377
|
/**
|
|
351
|
-
* The request id of a run that is STILL
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
378
|
+
* The request id of a run that is STILL LIVE, read from a resume door's
|
|
379
|
+
* refusal (`live_request_id` — never the envelope's own `request_id`). Null
|
|
380
|
+
* for every other error, and for a live refusal outside the spine (SEO) —
|
|
381
|
+
* follow `readLiveRunRejoin(error).rejoinPath` instead.
|
|
355
382
|
*/
|
|
356
383
|
declare function readLiveRunRequestId(error: unknown): string | null;
|
|
357
|
-
/**
|
|
384
|
+
/**
|
|
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
|
+
*/
|
|
358
389
|
declare function isResumeConflict(error: unknown): boolean;
|
|
359
390
|
/** `409 live_stream_unavailable` — the rejoin journal is gone; follow the durable lifecycle instead. */
|
|
360
391
|
declare function isLiveStreamUnavailable(error: unknown): boolean;
|
|
@@ -388,30 +419,52 @@ declare function openMatrxStream(transport: MatrxTransport, path: string, option
|
|
|
388
419
|
* resume/rejoin transport.
|
|
389
420
|
*/
|
|
390
421
|
declare function withRunOrganization(transport: MatrxTransport, organizationId: string): MatrxTransport;
|
|
422
|
+
/**
|
|
423
|
+
* Follow a workflow run's SSE (`GET /runs/{run_id}/events/stream`) — the
|
|
424
|
+
* rejoin fallback for workflow legs with no stream journal. Delivers every
|
|
425
|
+
* parsed event (durable run events with their seq; ephemeral `node_stream`
|
|
426
|
+
* frames — including `kind: "media"` — with seq null). One connection, no
|
|
427
|
+
* reconnect policy: resolves `{ended: true}` on the server's `end` frame,
|
|
428
|
+
* `{ended: false}` when the wire closes or the caller aborts.
|
|
429
|
+
*/
|
|
430
|
+
declare function followWorkflowRunEvents(transport: MatrxTransport, runId: string, options: {
|
|
431
|
+
onEvent: (event: Record<string, unknown>, seq: number | null) => void;
|
|
432
|
+
lastEventId?: number | null;
|
|
433
|
+
signal?: AbortSignal;
|
|
434
|
+
}): Promise<{
|
|
435
|
+
ended: boolean;
|
|
436
|
+
}>;
|
|
391
437
|
type ResumeOrRejoinOutcome =
|
|
392
438
|
/** The resume door ran the run; its stream was delivered to `onEnvelope`. */
|
|
393
439
|
{
|
|
394
440
|
kind: "resumed";
|
|
395
441
|
requestId: string | null;
|
|
396
442
|
}
|
|
397
|
-
/** The run was
|
|
443
|
+
/** The run was live; its stream (from `rejoin_path`) was replayed + followed into `onEnvelope`. */
|
|
398
444
|
| {
|
|
399
445
|
kind: "rejoined";
|
|
400
|
-
|
|
446
|
+
rejoin: MatrxLiveRunRejoin;
|
|
401
447
|
}
|
|
402
448
|
/**
|
|
403
|
-
* The run was
|
|
404
|
-
*
|
|
405
|
-
*
|
|
449
|
+
* The run was live but had no journal to replay; the durable lifecycle was
|
|
450
|
+
* followed instead. Re-query the feature's record for the result.
|
|
451
|
+
* `ended: false` = the follow gave up (or no operation was found).
|
|
406
452
|
*/
|
|
407
453
|
| {
|
|
408
454
|
kind: "followed";
|
|
409
|
-
|
|
455
|
+
rejoin: MatrxLiveRunRejoin;
|
|
410
456
|
executionId: string | null;
|
|
411
457
|
ended: boolean;
|
|
412
458
|
status: MatrxRuntimeExecutionStatus | null;
|
|
413
459
|
}
|
|
414
|
-
/**
|
|
460
|
+
/** No journal, and the run is a workflow: its run SSE was followed into `onWorkflowEvent`. */
|
|
461
|
+
| {
|
|
462
|
+
kind: "followed_workflow";
|
|
463
|
+
rejoin: MatrxLiveRunRejoin;
|
|
464
|
+
runId: string;
|
|
465
|
+
ended: boolean;
|
|
466
|
+
}
|
|
467
|
+
/** A bare `409 resume_conflict` (no live run named) — retry with the host's backoff policy. */
|
|
415
468
|
| {
|
|
416
469
|
kind: "resume_conflict";
|
|
417
470
|
error: MatrxApiError;
|
|
@@ -422,22 +475,26 @@ interface ResumeOrRejoinOptions extends Omit<MatrxStreamCallOptions, "signal"> {
|
|
|
422
475
|
/** THE RUN'S organization (from its durable record) — bound on every call. */
|
|
423
476
|
organizationId?: string | null;
|
|
424
477
|
signal?: AbortSignal;
|
|
425
|
-
/** Fired the moment a live run is detected, before the rejoin opens. */
|
|
426
|
-
onRejoin?: (
|
|
427
|
-
/** Durable lifecycle events while following (the no-
|
|
478
|
+
/** Fired the moment a live run is detected, before the rejoin opens (reset replay-sensitive state). */
|
|
479
|
+
onRejoin?: (rejoin: MatrxLiveRunRejoin) => void;
|
|
480
|
+
/** Durable lifecycle events while following (the no-journal fallback). */
|
|
428
481
|
onOperationEvent?: (event: MatrxRuntimeOperationEvent) => void;
|
|
429
|
-
/**
|
|
482
|
+
/** Workflow run SSE events (the no-journal fallback for a workflow `run_id`). */
|
|
483
|
+
onWorkflowEvent?: (event: Record<string, unknown>, seq: number | null) => void;
|
|
484
|
+
/** Tuning for the durable follow (stall / reconnect policy). */
|
|
430
485
|
follow?: Omit<FollowRuntimeOperationToEndOptions, "onEvent" | "signal" | "lastEventSeq">;
|
|
431
486
|
}
|
|
432
487
|
/**
|
|
433
|
-
* Resume a run — or, when the server says it is still
|
|
488
|
+
* Resume a run — or, when the server says it is still live, REJOIN it.
|
|
434
489
|
*
|
|
435
490
|
* Calls `resumeCall` (the feature's resume door) and pipes its stream into
|
|
436
|
-
* `onEnvelope`. On `
|
|
437
|
-
* `
|
|
438
|
-
* under the same organization; when
|
|
439
|
-
*
|
|
440
|
-
* `
|
|
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`
|
|
493
|
+
* into the SAME handler under the same organization; when the rejoin has no
|
|
494
|
+
* journal (`live_stream_unavailable`) it follows the workflow run SSE (body
|
|
495
|
+
* 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
|
|
497
|
+
* error is thrown.
|
|
441
498
|
*/
|
|
442
499
|
declare function resumeOrRejoin(transport: MatrxTransport, resumeCall: (transport: MatrxTransport, options: MatrxStreamCallOptions) => Promise<MatrxRunHandle>, options: ResumeOrRejoinOptions): Promise<ResumeOrRejoinOutcome>;
|
|
443
500
|
|
|
@@ -580,4 +637,4 @@ declare function listUserPendingToolCalls(transport: MatrxTransport, options?: {
|
|
|
580
637
|
signal?: AbortSignal;
|
|
581
638
|
}): Promise<MatrxPendingCallSummary[]>;
|
|
582
639
|
|
|
583
|
-
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 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, isCoveredAiPath, isLiveStreamUnavailable, isResumeConflict, isV2Path, listConversationPendingToolCalls, listUserPendingToolCalls, normalizeMatrxError, openMatrxStream, providerSessionFailureBody, readLiveRunRequestId, readMatrxErrorCode, reportProviderSessionFailure, requireOrganizationContext, resumeOrRejoin, runtimeOperationRejoinPath, streamErrorText, submitAgentToolResults, toV1FallbackUrl, toV2Path, withRunOrganization };
|
|
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 };
|
package/dist/matrx/index.js
CHANGED
|
@@ -965,17 +965,37 @@ function readMatrxErrorCode(error) {
|
|
|
965
965
|
}
|
|
966
966
|
return null;
|
|
967
967
|
}
|
|
968
|
-
function
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
if (
|
|
972
|
-
const live = nonBlank(candidate.live_request_id);
|
|
973
|
-
if (live) return live.trim();
|
|
968
|
+
function firstString(candidates, key) {
|
|
969
|
+
for (const candidate of candidates) {
|
|
970
|
+
const value = nonBlank(candidate[key]);
|
|
971
|
+
if (value) return value.trim();
|
|
974
972
|
}
|
|
975
973
|
return null;
|
|
976
974
|
}
|
|
975
|
+
function readLiveRunRejoin(error) {
|
|
976
|
+
if (statusOf(error) !== 409) return null;
|
|
977
|
+
const candidates = detailCandidates(bodyOf(error));
|
|
978
|
+
if (candidates.length === 0) return null;
|
|
979
|
+
const code = readMatrxErrorCode(error);
|
|
980
|
+
if (code !== MATRX_RUN_IN_PROGRESS && code !== MATRX_RESUME_CONFLICT) return null;
|
|
981
|
+
const liveRequestId = firstString(candidates, "live_request_id");
|
|
982
|
+
const pathFromBody = firstString(candidates, "rejoin_path");
|
|
983
|
+
const rejoinPath = pathFromBody && pathFromBody.startsWith("/") ? pathFromBody : liveRequestId ? runtimeOperationRejoinPath(liveRequestId) : null;
|
|
984
|
+
if (!rejoinPath) return null;
|
|
985
|
+
const root = bodyOf(error);
|
|
986
|
+
return {
|
|
987
|
+
liveRequestId,
|
|
988
|
+
rejoinPath,
|
|
989
|
+
runId: firstString(candidates, "run_id"),
|
|
990
|
+
code,
|
|
991
|
+
body: isRecord3(root) ? root : {}
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
function readLiveRunRequestId(error) {
|
|
995
|
+
return readLiveRunRejoin(error)?.liveRequestId ?? null;
|
|
996
|
+
}
|
|
977
997
|
function isResumeConflict(error) {
|
|
978
|
-
return statusOf(error) === 409 && readMatrxErrorCode(error) === MATRX_RESUME_CONFLICT;
|
|
998
|
+
return statusOf(error) === 409 && readMatrxErrorCode(error) === MATRX_RESUME_CONFLICT && readLiveRunRejoin(error) === null;
|
|
979
999
|
}
|
|
980
1000
|
function isLiveStreamUnavailable(error) {
|
|
981
1001
|
return statusOf(error) === 409 && readMatrxErrorCode(error) === MATRX_LIVE_STREAM_UNAVAILABLE;
|
|
@@ -1005,54 +1025,110 @@ function withRunOrganization(transport, organizationId) {
|
|
|
1005
1025
|
})
|
|
1006
1026
|
};
|
|
1007
1027
|
}
|
|
1028
|
+
async function followWorkflowRunEvents(transport, runId, options) {
|
|
1029
|
+
const headers = { Accept: "text/event-stream" };
|
|
1030
|
+
if (options.lastEventId) headers["Last-Event-ID"] = String(options.lastEventId);
|
|
1031
|
+
let response;
|
|
1032
|
+
try {
|
|
1033
|
+
response = await requestStream(
|
|
1034
|
+
transport,
|
|
1035
|
+
`/runs/${encodePathSegment(runId)}/events/stream`,
|
|
1036
|
+
{
|
|
1037
|
+
method: "GET",
|
|
1038
|
+
headers,
|
|
1039
|
+
...options.signal ? { signal: options.signal } : {}
|
|
1040
|
+
}
|
|
1041
|
+
);
|
|
1042
|
+
} catch (error) {
|
|
1043
|
+
if (options.signal?.aborted) return { ended: false };
|
|
1044
|
+
throw error;
|
|
1045
|
+
}
|
|
1046
|
+
try {
|
|
1047
|
+
for await (const frame of readMatrxSseStream(
|
|
1048
|
+
response.body
|
|
1049
|
+
)) {
|
|
1050
|
+
if (frame.event === "end") return { ended: true };
|
|
1051
|
+
if (frame.data === null) continue;
|
|
1052
|
+
let parsed;
|
|
1053
|
+
try {
|
|
1054
|
+
parsed = JSON.parse(frame.data);
|
|
1055
|
+
} catch {
|
|
1056
|
+
continue;
|
|
1057
|
+
}
|
|
1058
|
+
if (!isRecord3(parsed)) continue;
|
|
1059
|
+
options.onEvent(parsed, parsed.event === "node_stream" ? null : frame.seq);
|
|
1060
|
+
}
|
|
1061
|
+
} catch (error) {
|
|
1062
|
+
if (!options.signal?.aborted) throw error;
|
|
1063
|
+
}
|
|
1064
|
+
return { ended: false };
|
|
1065
|
+
}
|
|
1008
1066
|
async function drain(handle, onEnvelope) {
|
|
1009
1067
|
for await (const envelope of handle.events) onEnvelope(envelope);
|
|
1010
1068
|
}
|
|
1011
1069
|
async function resumeOrRejoin(transport, resumeCall, options) {
|
|
1012
|
-
const {
|
|
1070
|
+
const {
|
|
1071
|
+
onEnvelope,
|
|
1072
|
+
organizationId,
|
|
1073
|
+
onRejoin,
|
|
1074
|
+
onOperationEvent,
|
|
1075
|
+
onWorkflowEvent,
|
|
1076
|
+
follow,
|
|
1077
|
+
...rest
|
|
1078
|
+
} = options;
|
|
1013
1079
|
const bound = organizationId ? withRunOrganization(transport, organizationId) : transport;
|
|
1014
1080
|
const streamOptions = {
|
|
1015
1081
|
...rest,
|
|
1016
1082
|
...options.signal ? { signal: options.signal } : {}
|
|
1017
1083
|
};
|
|
1018
|
-
|
|
1084
|
+
const signalOnly = options.signal ? { signal: options.signal } : {};
|
|
1085
|
+
let rejoin;
|
|
1019
1086
|
try {
|
|
1020
1087
|
const handle = await resumeCall(bound, streamOptions);
|
|
1021
1088
|
await drain(handle, onEnvelope);
|
|
1022
1089
|
return { kind: "resumed", requestId: handle.requestId };
|
|
1023
1090
|
} catch (error) {
|
|
1024
|
-
|
|
1025
|
-
|
|
1091
|
+
const target = readLiveRunRejoin(error);
|
|
1092
|
+
if (!target) {
|
|
1093
|
+
if (error instanceof MatrxApiError && isResumeConflict(error)) {
|
|
1094
|
+
return { kind: "resume_conflict", error };
|
|
1095
|
+
}
|
|
1096
|
+
throw error;
|
|
1026
1097
|
}
|
|
1027
|
-
|
|
1028
|
-
if (!live) throw error;
|
|
1029
|
-
liveRequestId = live;
|
|
1098
|
+
rejoin = target;
|
|
1030
1099
|
}
|
|
1031
|
-
onRejoin?.(
|
|
1100
|
+
onRejoin?.(rejoin);
|
|
1101
|
+
let unavailableBody;
|
|
1032
1102
|
try {
|
|
1033
|
-
const handle = await
|
|
1103
|
+
const handle = await openMatrxStream(bound, rejoin.rejoinPath, {
|
|
1104
|
+
...streamOptions,
|
|
1105
|
+
// The rejoin routes take no body model; the reference client posts {}.
|
|
1106
|
+
body: {}
|
|
1107
|
+
});
|
|
1034
1108
|
await drain(handle, onEnvelope);
|
|
1035
|
-
return { kind: "rejoined",
|
|
1109
|
+
return { kind: "rejoined", rejoin };
|
|
1036
1110
|
} catch (error) {
|
|
1037
1111
|
if (!isLiveStreamUnavailable(error)) throw error;
|
|
1112
|
+
unavailableBody = bodyOf(error);
|
|
1038
1113
|
}
|
|
1039
|
-
const
|
|
1040
|
-
|
|
1041
|
-
|
|
1114
|
+
const runId = firstString(detailCandidates(unavailableBody), "run_id") ?? rejoin.runId;
|
|
1115
|
+
if (runId && rejoin.rejoinPath.startsWith("/runtime/operations/")) {
|
|
1116
|
+
const result2 = await followWorkflowRunEvents(bound, runId, {
|
|
1117
|
+
...signalOnly,
|
|
1118
|
+
onEvent: (event, seq) => onWorkflowEvent?.(event, seq)
|
|
1119
|
+
});
|
|
1120
|
+
return { kind: "followed_workflow", rejoin, runId, ended: result2.ended };
|
|
1121
|
+
}
|
|
1122
|
+
const liveRequestId = rejoin.liveRequestId;
|
|
1123
|
+
const statusView = liveRequestId ? await getRuntimeOperationStatus(bound, liveRequestId, signalOnly) : null;
|
|
1042
1124
|
const operation = statusView?.operations.find((op) => !op.is_terminal) ?? statusView?.operations[0] ?? null;
|
|
1043
1125
|
if (!operation) {
|
|
1044
|
-
return {
|
|
1045
|
-
kind: "followed",
|
|
1046
|
-
liveRequestId,
|
|
1047
|
-
executionId: null,
|
|
1048
|
-
ended: false,
|
|
1049
|
-
status: null
|
|
1050
|
-
};
|
|
1126
|
+
return { kind: "followed", rejoin, executionId: null, ended: false, status: null };
|
|
1051
1127
|
}
|
|
1052
1128
|
if (operation.is_terminal) {
|
|
1053
1129
|
return {
|
|
1054
1130
|
kind: "followed",
|
|
1055
|
-
|
|
1131
|
+
rejoin,
|
|
1056
1132
|
executionId: operation.execution_id,
|
|
1057
1133
|
ended: true,
|
|
1058
1134
|
status: operation.status
|
|
@@ -1061,12 +1137,12 @@ async function resumeOrRejoin(transport, resumeCall, options) {
|
|
|
1061
1137
|
const result = await followRuntimeOperationToEnd(bound, operation.execution_id, {
|
|
1062
1138
|
...follow,
|
|
1063
1139
|
lastEventSeq: operation.last_event_seq,
|
|
1064
|
-
...
|
|
1140
|
+
...signalOnly,
|
|
1065
1141
|
onEvent: (event) => onOperationEvent?.(event)
|
|
1066
1142
|
});
|
|
1067
1143
|
return {
|
|
1068
1144
|
kind: "followed",
|
|
1069
|
-
|
|
1145
|
+
rejoin,
|
|
1070
1146
|
executionId: operation.execution_id,
|
|
1071
1147
|
ended: result.ended,
|
|
1072
1148
|
status: result.status
|
|
@@ -1301,6 +1377,7 @@ export {
|
|
|
1301
1377
|
fetchWithMatrxProtocolFallback,
|
|
1302
1378
|
followRuntimeOperationEvents,
|
|
1303
1379
|
followRuntimeOperationToEnd,
|
|
1380
|
+
followWorkflowRunEvents,
|
|
1304
1381
|
getRuntimeOperationStatus,
|
|
1305
1382
|
getRuntimeOperationsByLink,
|
|
1306
1383
|
isCoveredAiPath,
|
|
@@ -1316,6 +1393,7 @@ export {
|
|
|
1316
1393
|
normalizeMatrxError,
|
|
1317
1394
|
openMatrxStream,
|
|
1318
1395
|
providerSessionFailureBody,
|
|
1396
|
+
readLiveRunRejoin,
|
|
1319
1397
|
readLiveRunRequestId,
|
|
1320
1398
|
readMatrxErrorCode,
|
|
1321
1399
|
rejoinRuntimeOperation,
|