@aexhq/sdk 0.46.4-canary → 0.50.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.
- package/LICENSE +201 -0
- package/NOTICE +38 -0
- package/README.md +23 -31
- package/dist/client/aex.d.ts +33 -0
- package/dist/client/aex.js +98 -0
- package/dist/client/aex.js.map +1 -0
- package/dist/client/credentials.d.ts +25 -0
- package/dist/client/credentials.js +97 -0
- package/dist/client/credentials.js.map +1 -0
- package/dist/client/routing.d.ts +7 -0
- package/dist/client/routing.js +29 -0
- package/dist/client/routing.js.map +1 -0
- package/dist/downloads/download.d.ts +25 -0
- package/dist/downloads/download.js +53 -0
- package/dist/downloads/download.js.map +1 -0
- package/dist/generated/errors.d.ts +12 -0
- package/dist/generated/errors.js +81 -0
- package/dist/generated/errors.js.map +1 -0
- package/dist/generated/resources.d.ts +730 -0
- package/dist/generated/resources.js +606 -0
- package/dist/generated/resources.js.map +1 -0
- package/dist/generated/routes.d.ts +42 -0
- package/dist/generated/routes.js +2101 -0
- package/dist/generated/routes.js.map +1 -0
- package/dist/index.d.ts +20 -50
- package/dist/index.js +11 -62
- package/dist/index.js.map +1 -1
- package/dist/observations/stream.d.ts +1 -0
- package/dist/observations/stream.js +18 -0
- package/dist/observations/stream.js.map +1 -0
- package/dist/transport/errors.d.ts +60 -0
- package/dist/transport/errors.js +107 -0
- package/dist/transport/errors.js.map +1 -0
- package/dist/transport/pagination.d.ts +8 -0
- package/dist/transport/pagination.js +34 -0
- package/dist/transport/pagination.js.map +1 -0
- package/dist/transport/retry.d.ts +21 -0
- package/dist/transport/retry.js +37 -0
- package/dist/transport/retry.js.map +1 -0
- package/dist/transport/transport.d.ts +25 -0
- package/dist/transport/transport.js +28 -0
- package/dist/transport/transport.js.map +1 -0
- package/package.json +63 -30
- package/dist/_contracts/account-operations.d.ts +0 -101
- package/dist/_contracts/account-operations.js +0 -242
- package/dist/_contracts/account-types.d.ts +0 -461
- package/dist/_contracts/account-types.js +0 -1
- package/dist/_contracts/api-key.d.ts +0 -61
- package/dist/_contracts/api-key.js +0 -101
- package/dist/_contracts/api-routes.d.ts +0 -20
- package/dist/_contracts/api-routes.js +0 -109
- package/dist/_contracts/archive-limits.d.ts +0 -3
- package/dist/_contracts/archive-limits.js +0 -23
- package/dist/_contracts/asset-authoring.d.ts +0 -22
- package/dist/_contracts/asset-authoring.js +0 -106
- package/dist/_contracts/asset-bundle.d.ts +0 -64
- package/dist/_contracts/asset-bundle.js +0 -263
- package/dist/_contracts/asset-upload-helper.d.ts +0 -31
- package/dist/_contracts/asset-upload-helper.js +0 -84
- package/dist/_contracts/billing-admission.d.ts +0 -29
- package/dist/_contracts/billing-admission.js +0 -28
- package/dist/_contracts/bundle-manifest.d.ts +0 -89
- package/dist/_contracts/bundle-manifest.js +0 -158
- package/dist/_contracts/canonical-sha256.d.ts +0 -8
- package/dist/_contracts/canonical-sha256.js +0 -8
- package/dist/_contracts/connection-ticket.d.ts +0 -22
- package/dist/_contracts/connection-ticket.js +0 -54
- package/dist/_contracts/continuation-event.d.ts +0 -31
- package/dist/_contracts/continuation-event.js +0 -6
- package/dist/_contracts/contract-parse-error.d.ts +0 -12
- package/dist/_contracts/contract-parse-error.js +0 -51
- package/dist/_contracts/error-codes.d.ts +0 -26
- package/dist/_contracts/error-codes.js +0 -116
- package/dist/_contracts/error-factory.d.ts +0 -32
- package/dist/_contracts/error-factory.js +0 -174
- package/dist/_contracts/event-envelope.d.ts +0 -471
- package/dist/_contracts/event-envelope.js +0 -501
- package/dist/_contracts/event-stream-client.d.ts +0 -122
- package/dist/_contracts/event-stream-client.js +0 -445
- package/dist/_contracts/event-view.d.ts +0 -44
- package/dist/_contracts/event-view.js +0 -69
- package/dist/_contracts/failure-class.d.ts +0 -29
- package/dist/_contracts/failure-class.js +0 -73
- package/dist/_contracts/http.d.ts +0 -135
- package/dist/_contracts/http.js +0 -434
- package/dist/_contracts/ids.d.ts +0 -66
- package/dist/_contracts/ids.js +0 -119
- package/dist/_contracts/index.d.ts +0 -42
- package/dist/_contracts/index.js +0 -52
- package/dist/_contracts/internal.d.ts +0 -55
- package/dist/_contracts/internal.js +0 -113
- package/dist/_contracts/models.d.ts +0 -30
- package/dist/_contracts/models.js +0 -28
- package/dist/_contracts/operation-core.d.ts +0 -36
- package/dist/_contracts/operation-core.js +0 -70
- package/dist/_contracts/operations.d.ts +0 -218
- package/dist/_contracts/operations.js +0 -1496
- package/dist/_contracts/otlp-projection.d.ts +0 -78
- package/dist/_contracts/otlp-projection.js +0 -171
- package/dist/_contracts/post-hook.d.ts +0 -31
- package/dist/_contracts/post-hook.js +0 -61
- package/dist/_contracts/provider-fault.d.ts +0 -34
- package/dist/_contracts/provider-fault.js +0 -68
- package/dist/_contracts/retry-core.d.ts +0 -29
- package/dist/_contracts/retry-core.js +0 -79
- package/dist/_contracts/runner-event.d.ts +0 -117
- package/dist/_contracts/runner-event.js +0 -172
- package/dist/_contracts/runtime-kind.d.ts +0 -60
- package/dist/_contracts/runtime-kind.js +0 -70
- package/dist/_contracts/runtime-manifest.d.ts +0 -121
- package/dist/_contracts/runtime-manifest.js +0 -83
- package/dist/_contracts/runtime-security-profile.d.ts +0 -26
- package/dist/_contracts/runtime-security-profile.js +0 -73
- package/dist/_contracts/runtime-sizes.d.ts +0 -104
- package/dist/_contracts/runtime-sizes.js +0 -111
- package/dist/_contracts/runtime-types.d.ts +0 -618
- package/dist/_contracts/runtime-types.js +0 -58
- package/dist/_contracts/schemas/asset-bundle.d.ts +0 -70
- package/dist/_contracts/schemas/asset-bundle.js +0 -107
- package/dist/_contracts/schemas/asset-ref.d.ts +0 -61
- package/dist/_contracts/schemas/asset-ref.js +0 -118
- package/dist/_contracts/schemas/bundle-manifest.d.ts +0 -66
- package/dist/_contracts/schemas/bundle-manifest.js +0 -77
- package/dist/_contracts/schemas/index.d.ts +0 -32
- package/dist/_contracts/schemas/index.js +0 -30
- package/dist/_contracts/schemas/mcp-server.d.ts +0 -99
- package/dist/_contracts/schemas/mcp-server.js +0 -209
- package/dist/_contracts/schemas/models.d.ts +0 -29
- package/dist/_contracts/schemas/models.js +0 -51
- package/dist/_contracts/schemas/numeric.d.ts +0 -18
- package/dist/_contracts/schemas/numeric.js +0 -28
- package/dist/_contracts/schemas/post-hook.d.ts +0 -45
- package/dist/_contracts/schemas/post-hook.js +0 -68
- package/dist/_contracts/schemas/response-assets.d.ts +0 -75
- package/dist/_contracts/schemas/response-assets.js +0 -81
- package/dist/_contracts/schemas/response-billing.d.ts +0 -208
- package/dist/_contracts/schemas/response-billing.js +0 -139
- package/dist/_contracts/schemas/response-common.d.ts +0 -132
- package/dist/_contracts/schemas/response-common.js +0 -162
- package/dist/_contracts/schemas/response-identity.d.ts +0 -648
- package/dist/_contracts/schemas/response-identity.js +0 -131
- package/dist/_contracts/schemas/response-mcp-servers.d.ts +0 -51
- package/dist/_contracts/schemas/response-mcp-servers.js +0 -32
- package/dist/_contracts/schemas/response-secrets.d.ts +0 -50
- package/dist/_contracts/schemas/response-secrets.js +0 -32
- package/dist/_contracts/schemas/response-sessions-internal.d.ts +0 -200
- package/dist/_contracts/schemas/response-sessions-internal.js +0 -142
- package/dist/_contracts/schemas/response-sessions.d.ts +0 -1598
- package/dist/_contracts/schemas/response-sessions.js +0 -377
- package/dist/_contracts/schemas/response-webhooks.d.ts +0 -76
- package/dist/_contracts/schemas/response-webhooks.js +0 -42
- package/dist/_contracts/schemas/response-workspace.d.ts +0 -225
- package/dist/_contracts/schemas/response-workspace.js +0 -99
- package/dist/_contracts/schemas/runtime-kind.d.ts +0 -31
- package/dist/_contracts/schemas/runtime-kind.js +0 -29
- package/dist/_contracts/schemas/runtime-security-profile.d.ts +0 -28
- package/dist/_contracts/schemas/runtime-security-profile.js +0 -26
- package/dist/_contracts/schemas/runtime-sizes.d.ts +0 -70
- package/dist/_contracts/schemas/runtime-sizes.js +0 -127
- package/dist/_contracts/schemas/session-limits.d.ts +0 -34
- package/dist/_contracts/schemas/session-limits.js +0 -39
- package/dist/_contracts/schemas/session-machine.d.ts +0 -23
- package/dist/_contracts/schemas/session-machine.js +0 -24
- package/dist/_contracts/schemas/session-request-config.d.ts +0 -58
- package/dist/_contracts/schemas/session-request-config.js +0 -134
- package/dist/_contracts/schemas/session-webhook.d.ts +0 -11
- package/dist/_contracts/schemas/session-webhook.js +0 -38
- package/dist/_contracts/schemas/side-effect-audit.d.ts +0 -98
- package/dist/_contracts/schemas/side-effect-audit.js +0 -102
- package/dist/_contracts/schemas/submission-assets.d.ts +0 -117
- package/dist/_contracts/schemas/submission-assets.js +0 -147
- package/dist/_contracts/schemas/submission-body.d.ts +0 -251
- package/dist/_contracts/schemas/submission-body.js +0 -378
- package/dist/_contracts/schemas/submission-environment.d.ts +0 -79
- package/dist/_contracts/schemas/submission-environment.js +0 -179
- package/dist/_contracts/schemas/submission-request.d.ts +0 -158
- package/dist/_contracts/schemas/submission-request.js +0 -49
- package/dist/_contracts/schemas/submission-secrets.d.ts +0 -47
- package/dist/_contracts/schemas/submission-secrets.js +0 -108
- package/dist/_contracts/schemas/wire.d.ts +0 -118
- package/dist/_contracts/schemas/wire.js +0 -171
- package/dist/_contracts/schemas/workspace-resources.d.ts +0 -50
- package/dist/_contracts/schemas/workspace-resources.js +0 -87
- package/dist/_contracts/sdk-errors.d.ts +0 -212
- package/dist/_contracts/sdk-errors.js +0 -313
- package/dist/_contracts/sdk-secrets.d.ts +0 -67
- package/dist/_contracts/sdk-secrets.js +0 -427
- package/dist/_contracts/session-archive.d.ts +0 -16
- package/dist/_contracts/session-archive.js +0 -92
- package/dist/_contracts/session-artifacts.d.ts +0 -189
- package/dist/_contracts/session-artifacts.js +0 -264
- package/dist/_contracts/session-config.d.ts +0 -373
- package/dist/_contracts/session-config.js +0 -562
- package/dist/_contracts/session-cost-types.d.ts +0 -211
- package/dist/_contracts/session-cost-types.js +0 -69
- package/dist/_contracts/session-cost.d.ts +0 -8
- package/dist/_contracts/session-cost.js +0 -582
- package/dist/_contracts/session-custody.d.ts +0 -165
- package/dist/_contracts/session-custody.js +0 -345
- package/dist/_contracts/session-file-query.d.ts +0 -14
- package/dist/_contracts/session-file-query.js +0 -178
- package/dist/_contracts/session-record.d.ts +0 -112
- package/dist/_contracts/session-record.js +0 -165
- package/dist/_contracts/session-retention.d.ts +0 -201
- package/dist/_contracts/session-retention.js +0 -450
- package/dist/_contracts/side-effect-audit.d.ts +0 -126
- package/dist/_contracts/side-effect-audit.js +0 -520
- package/dist/_contracts/sse.d.ts +0 -74
- package/dist/_contracts/sse.js +0 -227
- package/dist/_contracts/stable.d.ts +0 -45
- package/dist/_contracts/stable.js +0 -62
- package/dist/_contracts/status.d.ts +0 -25
- package/dist/_contracts/status.js +0 -57
- package/dist/_contracts/submission-limits.d.ts +0 -61
- package/dist/_contracts/submission-limits.js +0 -60
- package/dist/_contracts/submission.d.ts +0 -547
- package/dist/_contracts/submission.js +0 -812
- package/dist/_contracts/suggest.d.ts +0 -15
- package/dist/_contracts/suggest.js +0 -53
- package/dist/_contracts/testing/response-bindings.d.ts +0 -45
- package/dist/_contracts/testing/response-bindings.js +0 -256
- package/dist/_contracts/testing/wire-conformance-entry.d.ts +0 -10
- package/dist/_contracts/testing/wire-conformance-entry.js +0 -8
- package/dist/_contracts/testing/wire-conformance.d.ts +0 -169
- package/dist/_contracts/testing/wire-conformance.js +0 -276
- package/dist/_contracts/turn-trace.d.ts +0 -28
- package/dist/_contracts/turn-trace.js +0 -1
- package/dist/_contracts/unknown-field-error.d.ts +0 -13
- package/dist/_contracts/unknown-field-error.js +0 -21
- package/dist/_contracts/value-guards.d.ts +0 -20
- package/dist/_contracts/value-guards.js +0 -34
- package/dist/_contracts/webhook-verify.d.ts +0 -34
- package/dist/_contracts/webhook-verify.js +0 -93
- package/dist/_contracts/wire-observer.d.ts +0 -49
- package/dist/_contracts/wire-observer.js +0 -34
- package/dist/_contracts/workflow-status.d.ts +0 -7
- package/dist/_contracts/workflow-status.js +0 -43
- package/dist/_contracts/workspace-resources.d.ts +0 -98
- package/dist/_contracts/workspace-resources.js +0 -39
- package/dist/archive-limits.d.ts +0 -1
- package/dist/archive-limits.js +0 -2
- package/dist/archive-limits.js.map +0 -1
- package/dist/asset-upload.d.ts +0 -47
- package/dist/asset-upload.js +0 -269
- package/dist/asset-upload.js.map +0 -1
- package/dist/bundle.d.ts +0 -9
- package/dist/bundle.js +0 -20
- package/dist/bundle.js.map +0 -1
- package/dist/canonical-zip.d.ts +0 -68
- package/dist/canonical-zip.js +0 -355
- package/dist/canonical-zip.js.map +0 -1
- package/dist/cli.mjs +0 -12048
- package/dist/cli.mjs.sha256 +0 -1
- package/dist/client-types.d.ts +0 -192
- package/dist/client-types.js +0 -2
- package/dist/client-types.js.map +0 -1
- package/dist/client.d.ts +0 -464
- package/dist/client.js +0 -1207
- package/dist/client.js.map +0 -1
- package/dist/event-projection.d.ts +0 -22
- package/dist/event-projection.js +0 -380
- package/dist/event-projection.js.map +0 -1
- package/dist/fetch-archive.d.ts +0 -16
- package/dist/fetch-archive.js +0 -252
- package/dist/fetch-archive.js.map +0 -1
- package/dist/file.d.ts +0 -96
- package/dist/file.js +0 -272
- package/dist/file.js.map +0 -1
- package/dist/instructions.d.ts +0 -20
- package/dist/instructions.js +0 -40
- package/dist/instructions.js.map +0 -1
- package/dist/legacy-session-provider-fault.d.ts +0 -7
- package/dist/legacy-session-provider-fault.js +0 -38
- package/dist/legacy-session-provider-fault.js.map +0 -1
- package/dist/mcp-server.d.ts +0 -84
- package/dist/mcp-server.js +0 -117
- package/dist/mcp-server.js.map +0 -1
- package/dist/node-fs.d.ts +0 -29
- package/dist/node-fs.js +0 -19
- package/dist/node-fs.js.map +0 -1
- package/dist/node-walk.d.ts +0 -69
- package/dist/node-walk.js +0 -151
- package/dist/node-walk.js.map +0 -1
- package/dist/path-basename.d.ts +0 -5
- package/dist/path-basename.js +0 -9
- package/dist/path-basename.js.map +0 -1
- package/dist/retry.d.ts +0 -70
- package/dist/retry.js +0 -155
- package/dist/retry.js.map +0 -1
- package/dist/secret.d.ts +0 -65
- package/dist/secret.js +0 -110
- package/dist/secret.js.map +0 -1
- package/dist/session-validate.d.ts +0 -100
- package/dist/session-validate.js +0 -303
- package/dist/session-validate.js.map +0 -1
- package/dist/skill.d.ts +0 -99
- package/dist/skill.js +0 -169
- package/dist/skill.js.map +0 -1
- package/dist/submission-wire.d.ts +0 -13
- package/dist/submission-wire.js +0 -69
- package/dist/submission-wire.js.map +0 -1
- package/dist/tool.d.ts +0 -41
- package/dist/tool.js +0 -76
- package/dist/tool.js.map +0 -1
- package/dist/version.d.ts +0 -9
- package/dist/version.js +0 -10
- package/dist/version.js.map +0 -1
- package/docs/authentication.md +0 -125
- package/docs/billing.md +0 -164
- package/docs/cleanup.md +0 -27
- package/docs/concepts/agent-tools.md +0 -47
- package/docs/concepts/composition.md +0 -60
- package/docs/concepts/providers-and-runtimes.md +0 -121
- package/docs/concepts/sessions.md +0 -51
- package/docs/concepts/subagents.md +0 -35
- package/docs/credentials.md +0 -116
- package/docs/defaults.md +0 -51
- package/docs/errors.md +0 -258
- package/docs/events.md +0 -143
- package/docs/files.md +0 -130
- package/docs/limits-and-quotas.md +0 -114
- package/docs/limits.md +0 -51
- package/docs/mcp.md +0 -47
- package/docs/networking.md +0 -114
- package/docs/provider-runtime-capabilities.md +0 -32
- package/docs/public-surface.json +0 -73
- package/docs/quickstart.md +0 -135
- package/docs/release.md +0 -44
- package/docs/retries.md +0 -108
- package/docs/secrets.md +0 -141
- package/docs/session-config.md +0 -51
- package/docs/session-record.md +0 -58
- package/docs/skills.md +0 -65
- package/docs/telemetry.md +0 -66
- package/docs/testing.md +0 -35
- package/docs/vision-skills.md +0 -94
- package/docs/webhooks.md +0 -143
|
@@ -1,501 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The unified aex event envelope.
|
|
3
|
-
*
|
|
4
|
-
* One versioned, self-describing record that every subscriber sees, derived
|
|
5
|
-
* from the unified {@link RunnerEvent}. Managed runtime adapters emit
|
|
6
|
-
* byte-identical envelopes for the same logical event by construction. This is
|
|
7
|
-
* the shape the coordinator (Phase 2) appends, broadcasts, and archives.
|
|
8
|
-
*
|
|
9
|
-
* - **CloudEvents-shaped** self-describing envelope: a stable `id`, the
|
|
10
|
-
* coarse `source`, the AG-UI-aligned `type`, the `subject` (session), a
|
|
11
|
-
* `time`, the `sequence` cursor, and the typed `data`.
|
|
12
|
-
* - **AG-UI vocabulary** for `type` where it maps; aex-specific events
|
|
13
|
-
* ride AG-UI's reserved `CUSTOM` carrier under an `aex.*` name, so an
|
|
14
|
-
* off-the-shelf AG-UI client reads an aex start with no glue.
|
|
15
|
-
* - Two aex extensions: a coarse `source` (filter first by origin) and
|
|
16
|
-
* an optional human `message` (log / CLI / dashboard rendering).
|
|
17
|
-
*
|
|
18
|
-
* Unified observability spine:
|
|
19
|
-
* the envelope additionally carries four ordering attributes so BOTH the typed
|
|
20
|
-
* event stream and the high-volume hosted-platform log stream ride one per-session
|
|
21
|
-
* coordinator:
|
|
22
|
-
* - `channel` — "event" (the typed AG-UI stream) or "log" (a verbose log
|
|
23
|
-
* line). The single axis a consumer splits the unified stream
|
|
24
|
-
* on.
|
|
25
|
-
* - `sourceSeq` — a per-SOURCE monotonic counter assigned AT the source. The
|
|
26
|
-
* DO's hard guarantee is that records of the same source are
|
|
27
|
-
* never reordered relative to their `sourceSeq`.
|
|
28
|
-
* - `emittedAt` — source wall-clock ms at emit. Carried, never trusted for
|
|
29
|
-
* cross-source ordering (clocks are independent; the coordinator gives
|
|
30
|
-
* no synchronized clock). A client may re-sort by it for a
|
|
31
|
-
* best-effort time view.
|
|
32
|
-
* The coordinator remains the single serial ordering authority: it assigns the global
|
|
33
|
-
* `sequence` on arrival, which is the canonical stream order. `sourceSeq` /
|
|
34
|
-
* `emittedAt` are CARRIED through broadcast + archive, not used to reorder.
|
|
35
|
-
*
|
|
36
|
-
* This module is a pure projection plus honest guards and a strict AG-UI
|
|
37
|
-
* projection for consumers.
|
|
38
|
-
*/
|
|
39
|
-
import { SESSION_TERMINAL_OUTCOMES } from "./status.js";
|
|
40
|
-
import { AEX_FAILURE_CLASSES, isAexFailureClass } from "./failure-class.js";
|
|
41
|
-
import { parseProviderFault } from "./provider-fault.js";
|
|
42
|
-
/** CloudEvents `specversion` the envelope conforms to. */
|
|
43
|
-
export const AEX_EVENT_SPECVERSION = "1.0";
|
|
44
|
-
/**
|
|
45
|
-
* Mapping version. Bump when the RunnerEvent → envelope projection changes
|
|
46
|
-
* shape (new `source`/`type`, renamed data field). Independent of
|
|
47
|
-
* {@link AEX_EVENT_SPECVERSION} (the CloudEvents version) and of
|
|
48
|
-
* `RUNNER_EVENT_VERSION` (the upstream wire version).
|
|
49
|
-
*/
|
|
50
|
-
export const AEX_EVENT_MAP_VERSION = 2;
|
|
51
|
-
/**
|
|
52
|
-
* Coarse origin classifier — the first axis a consumer filters on.
|
|
53
|
-
* - `agent` — the model: text, reasoning, builtin tool calls/results.
|
|
54
|
-
* - `api` — the hosted aex API path.
|
|
55
|
-
* - `runtime` — the execution runtime: lifecycle, diagnostics, non-fatal
|
|
56
|
-
* stream errors.
|
|
57
|
-
* - `mcp` — an MCP server (a tool call/result routed through MCP).
|
|
58
|
-
* - `aex` — the platform: skills, files, and other aex-native events.
|
|
59
|
-
* - `workflow`— the orchestration layer.
|
|
60
|
-
* - `host` — the managed host the runtime executes on; distinct from the
|
|
61
|
-
* runtime process itself.
|
|
62
|
-
*/
|
|
63
|
-
export const AEX_EVENT_SOURCES = ["agent", "api", "runtime", "mcp", "aex", "workflow", "host"];
|
|
64
|
-
/**
|
|
65
|
-
* The channel a record rides on the unified per-session stream:
|
|
66
|
-
* - `event` — the typed, low-volume, fully-replayed AG-UI event stream.
|
|
67
|
-
* - `log` — a high-volume verbose log line (level + message + fields). The
|
|
68
|
-
* coordinator prunes flushed log rows after evidence archival
|
|
69
|
-
* (logs are append-only, events are kept). Absent on the wire ⇒
|
|
70
|
-
* `event`.
|
|
71
|
-
*/
|
|
72
|
-
export const AEX_EVENT_CHANNELS = ["event", "log"];
|
|
73
|
-
/**
|
|
74
|
-
* Log severity carried by a `channel: "log"` record (the `LOG` event type).
|
|
75
|
-
* NOTE: the platform owner's canonical term for the middle level is "warning";
|
|
76
|
-
* we keep "warn" for consistency with the existing in-code vocabulary — the
|
|
77
|
-
* mapping is `warning ≡ warn`.
|
|
78
|
-
*/
|
|
79
|
-
export const AEX_LOG_LEVELS = ["info", "warn", "error"];
|
|
80
|
-
/**
|
|
81
|
-
* The AG-UI-aligned `type` vocabulary the envelope emits. A subset of the
|
|
82
|
-
* full AG-UI protocol — the events aex actually produces today — plus
|
|
83
|
-
* `CUSTOM`, AG-UI's reserved carrier for aex-native events.
|
|
84
|
-
*/
|
|
85
|
-
export const AEX_EVENT_TYPES = [
|
|
86
|
-
"RUN_STARTED",
|
|
87
|
-
"RUN_FINISHED",
|
|
88
|
-
"RUN_ERROR",
|
|
89
|
-
"TEXT_MESSAGE_CONTENT",
|
|
90
|
-
"TOOL_CALL_START",
|
|
91
|
-
"TOOL_CALL_RESULT",
|
|
92
|
-
"CUSTOM",
|
|
93
|
-
// The carrier type for a `channel: "log"` record. Kept out of the AG-UI
|
|
94
|
-
// typed-event vocabulary on purpose: a `LOG` is never a session-lifecycle signal,
|
|
95
|
-
// so terminal detection (RUN_FINISHED/RUN_ERROR) is unaffected and an
|
|
96
|
-
// off-the-shelf AG-UI client filters logs out by `channel`.
|
|
97
|
-
"LOG"
|
|
98
|
-
];
|
|
99
|
-
/** Explicit failure thrown when a malformed known event is projected. */
|
|
100
|
-
export class MalformedAexEventError extends Error {
|
|
101
|
-
code = "malformed_known_event";
|
|
102
|
-
issue;
|
|
103
|
-
constructor(issue) {
|
|
104
|
-
super(`Malformed ${issue.type} event: ${issue.path} must be ${issue.expected}`);
|
|
105
|
-
this.name = "MalformedAexEventError";
|
|
106
|
-
this.issue = issue;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
/** True only for a provisional frame outside the durable replay sequence. */
|
|
110
|
-
export function isAexLiveEvent(event) {
|
|
111
|
-
return event.replayable === false;
|
|
112
|
-
}
|
|
113
|
-
/** True only for a durable event carrying a replay cursor. */
|
|
114
|
-
export function isReplayableEvent(event) {
|
|
115
|
-
return event.replayable !== false && typeof event.sequence === "number";
|
|
116
|
-
}
|
|
117
|
-
/** Compatibility spelling used by the hosted platform. */
|
|
118
|
-
export const isReplayableAexEvent = isReplayableEvent;
|
|
119
|
-
/**
|
|
120
|
-
* Project a {@link RunnerEvent} onto the unified public envelope. Internal
|
|
121
|
-
* runtime completion has no public projection: only the platform-authored
|
|
122
|
-
* RUN_FINISHED/RUN_ERROR event is a completion boundary.
|
|
123
|
-
*/
|
|
124
|
-
export function runnerEventToAexEvent(evt, ctx) {
|
|
125
|
-
const projection = project(evt);
|
|
126
|
-
if (projection === null)
|
|
127
|
-
return null;
|
|
128
|
-
const event = {
|
|
129
|
-
specversion: AEX_EVENT_SPECVERSION,
|
|
130
|
-
id: `${ctx.sessionId}:${evt.seq}`,
|
|
131
|
-
source: projection.source,
|
|
132
|
-
type: projection.type,
|
|
133
|
-
subject: ctx.sessionId,
|
|
134
|
-
threadId: ctx.sessionId,
|
|
135
|
-
runId: ctx.runId,
|
|
136
|
-
time: new Date(ctx.baseMs + evt.tMs).toISOString(),
|
|
137
|
-
sequence: evt.seq,
|
|
138
|
-
...(evt.sourceSeq !== undefined ? { sourceSeq: evt.sourceSeq } : {}),
|
|
139
|
-
...(evt.emittedAt !== undefined ? { emittedAt: evt.emittedAt } : {}),
|
|
140
|
-
...(projection.message !== undefined ? { message: projection.message } : {}),
|
|
141
|
-
data: Object.freeze(projection.data)
|
|
142
|
-
};
|
|
143
|
-
const classified = classifyAexEvent(event);
|
|
144
|
-
if (classified.kind === "malformed_known") {
|
|
145
|
-
throw new MalformedAexEventError(classified.issue);
|
|
146
|
-
}
|
|
147
|
-
return event;
|
|
148
|
-
}
|
|
149
|
-
function project(evt) {
|
|
150
|
-
const data = evt.data;
|
|
151
|
-
switch (evt.kind) {
|
|
152
|
-
case "runtime_started":
|
|
153
|
-
return { type: "RUN_STARTED", source: "runtime", message: "turn started", data: { ...data } };
|
|
154
|
-
case "assistant_text": {
|
|
155
|
-
const text = typeof data.text === "string" ? data.text : undefined;
|
|
156
|
-
return {
|
|
157
|
-
type: "TEXT_MESSAGE_CONTENT",
|
|
158
|
-
source: "agent",
|
|
159
|
-
...(text ? { message: clip(text) } : {}),
|
|
160
|
-
data: { ...data }
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
case "tool_request": {
|
|
164
|
-
const name = typeof data.name === "string" ? data.name : undefined;
|
|
165
|
-
return {
|
|
166
|
-
type: "TOOL_CALL_START",
|
|
167
|
-
source: data.extension ? "mcp" : "agent",
|
|
168
|
-
...(name ? { message: `tool ${name}` } : {}),
|
|
169
|
-
data: { ...data }
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
case "tool_response":
|
|
173
|
-
return {
|
|
174
|
-
type: "TOOL_CALL_RESULT",
|
|
175
|
-
source: data.extension ? "mcp" : "agent",
|
|
176
|
-
data: { ...data }
|
|
177
|
-
};
|
|
178
|
-
case "skill_loaded":
|
|
179
|
-
return custom("aex.skill_loaded", "aex", data, "skill loaded");
|
|
180
|
-
case "file_uploaded":
|
|
181
|
-
return custom("aex.file_uploaded", "aex", data, "file uploaded");
|
|
182
|
-
case "notification":
|
|
183
|
-
return custom("aex.notification", "runtime", data, typeof data.reason === "string" && data.reason.length > 0 ? data.reason : undefined);
|
|
184
|
-
case "stream_error":
|
|
185
|
-
return custom("aex.stream_error", "runtime", data, typeof data.message === "string" && data.message.length > 0 ? data.message : "stream error");
|
|
186
|
-
case "runtime_terminal":
|
|
187
|
-
return null;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Project a log line onto an inbound coordinator envelope. The coordinator
|
|
192
|
-
* stamps `specversion`/`id`/`subject`/`sequence` on ingest (it is the ordering
|
|
193
|
-
* authority); everything else — `channel`, `source`, `sourceSeq`, `emittedAt`,
|
|
194
|
-
* and the `LOG` payload — is supplied here.
|
|
195
|
-
*/
|
|
196
|
-
export function logToInbound(source, line) {
|
|
197
|
-
return {
|
|
198
|
-
source,
|
|
199
|
-
type: "LOG",
|
|
200
|
-
channel: "log",
|
|
201
|
-
sourceSeq: line.sourceSeq,
|
|
202
|
-
emittedAt: line.emittedAt,
|
|
203
|
-
// First-class severity on the envelope (not only inside `data`). `data.level`
|
|
204
|
-
// is kept too so an existing `data`-reading consumer still works.
|
|
205
|
-
level: line.level,
|
|
206
|
-
time: new Date(line.emittedAt).toISOString(),
|
|
207
|
-
message: line.message,
|
|
208
|
-
data: {
|
|
209
|
-
level: line.level,
|
|
210
|
-
message: line.message,
|
|
211
|
-
...(line.fields ? { fields: { ...line.fields } } : {})
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
function custom(name, source, value, message) {
|
|
216
|
-
return {
|
|
217
|
-
type: "CUSTOM",
|
|
218
|
-
source,
|
|
219
|
-
...(message !== undefined ? { message } : {}),
|
|
220
|
-
data: { name, value: { ...value } }
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
// --- Known/unknown classification and honest guards ---------------------------
|
|
224
|
-
const TERMINAL_OUTCOMES = new Set(SESSION_TERMINAL_OUTCOMES);
|
|
225
|
-
const LOG_LEVELS = new Set(AEX_LOG_LEVELS);
|
|
226
|
-
function malformed(type, path, expected) {
|
|
227
|
-
return { code: "malformed_known_event", type, path, expected };
|
|
228
|
-
}
|
|
229
|
-
function optionalString(data, key) {
|
|
230
|
-
return data[key] === undefined || typeof data[key] === "string";
|
|
231
|
-
}
|
|
232
|
-
function optionalBoolean(data, key) {
|
|
233
|
-
return data[key] === undefined || typeof data[key] === "boolean";
|
|
234
|
-
}
|
|
235
|
-
function isJsonObjectShape(value) {
|
|
236
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
237
|
-
}
|
|
238
|
-
function knownIssue(e) {
|
|
239
|
-
const d = e.data;
|
|
240
|
-
switch (e.type) {
|
|
241
|
-
case "RUN_STARTED":
|
|
242
|
-
for (const key of ["source", "mode", "provider", "model"]) {
|
|
243
|
-
if (!optionalString(d, key)) {
|
|
244
|
-
return malformed("RUN_STARTED", `data.${key}`, "a string when present");
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
return d.turnSeq === undefined || (typeof d.turnSeq === "number" && Number.isInteger(d.turnSeq) && d.turnSeq >= 0)
|
|
248
|
-
? undefined
|
|
249
|
-
: malformed("RUN_STARTED", "data.turnSeq", "a non-negative integer when present");
|
|
250
|
-
case "RUN_FINISHED":
|
|
251
|
-
return typeof d.outcome === "string" && TERMINAL_OUTCOMES.has(d.outcome)
|
|
252
|
-
? undefined
|
|
253
|
-
: malformed("RUN_FINISHED", "data.outcome", `one of ${SESSION_TERMINAL_OUTCOMES.join(", ")}`);
|
|
254
|
-
case "RUN_ERROR":
|
|
255
|
-
if (typeof d.outcome !== "string" || !TERMINAL_OUTCOMES.has(d.outcome)) {
|
|
256
|
-
return malformed("RUN_ERROR", "data.outcome", `one of ${SESSION_TERMINAL_OUTCOMES.join(", ")}`);
|
|
257
|
-
}
|
|
258
|
-
if (!isAexFailureClass(d.failureClass))
|
|
259
|
-
return malformed("RUN_ERROR", "data.failureClass", `one of ${AEX_FAILURE_CLASSES.join(", ")}`);
|
|
260
|
-
if (typeof d.failureMessage !== "string" || d.failureMessage.length === 0) {
|
|
261
|
-
return malformed("RUN_ERROR", "data.failureMessage", "a non-empty string");
|
|
262
|
-
}
|
|
263
|
-
if (Object.hasOwn(d, "providerFault")) {
|
|
264
|
-
try {
|
|
265
|
-
parseProviderFault(d.providerFault);
|
|
266
|
-
}
|
|
267
|
-
catch {
|
|
268
|
-
return malformed("RUN_ERROR", "data.providerFault", "a canonical ProviderFault object when present");
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
return undefined;
|
|
272
|
-
case "TEXT_MESSAGE_CONTENT":
|
|
273
|
-
if (typeof d.text !== "string") {
|
|
274
|
-
return malformed("TEXT_MESSAGE_CONTENT", "data.text", "a string");
|
|
275
|
-
}
|
|
276
|
-
if (!optionalString(d, "messageId")) {
|
|
277
|
-
return malformed("TEXT_MESSAGE_CONTENT", "data.messageId", "a string when present");
|
|
278
|
-
}
|
|
279
|
-
if (!optionalString(d, "eventId")) {
|
|
280
|
-
return malformed("TEXT_MESSAGE_CONTENT", "data.eventId", "a string when present");
|
|
281
|
-
}
|
|
282
|
-
if (!optionalBoolean(d, "delta"))
|
|
283
|
-
return malformed("TEXT_MESSAGE_CONTENT", "data.delta", "a boolean when present");
|
|
284
|
-
return optionalBoolean(d, "truncated")
|
|
285
|
-
? undefined
|
|
286
|
-
: malformed("TEXT_MESSAGE_CONTENT", "data.truncated", "a boolean when present");
|
|
287
|
-
case "TOOL_CALL_START":
|
|
288
|
-
if (typeof d.id !== "string" || d.id.length === 0) {
|
|
289
|
-
return malformed("TOOL_CALL_START", "data.id", "a non-empty string");
|
|
290
|
-
}
|
|
291
|
-
if (typeof d.name !== "string" || d.name.length === 0) {
|
|
292
|
-
return malformed("TOOL_CALL_START", "data.name", "a non-empty string");
|
|
293
|
-
}
|
|
294
|
-
if (d.arguments !== undefined && !isJsonObjectShape(d.arguments)) {
|
|
295
|
-
return malformed("TOOL_CALL_START", "data.arguments", "a JSON object when present");
|
|
296
|
-
}
|
|
297
|
-
return optionalString(d, "messageId")
|
|
298
|
-
? undefined
|
|
299
|
-
: malformed("TOOL_CALL_START", "data.messageId", "a string when present");
|
|
300
|
-
case "TOOL_CALL_RESULT":
|
|
301
|
-
if (typeof d.id !== "string" || d.id.length === 0) {
|
|
302
|
-
return malformed("TOOL_CALL_RESULT", "data.id", "a non-empty string");
|
|
303
|
-
}
|
|
304
|
-
if (!Object.hasOwn(d, "content")) {
|
|
305
|
-
return malformed("TOOL_CALL_RESULT", "data.content", "present JSON data");
|
|
306
|
-
}
|
|
307
|
-
if (!optionalBoolean(d, "isError")) {
|
|
308
|
-
return malformed("TOOL_CALL_RESULT", "data.isError", "a boolean when present");
|
|
309
|
-
}
|
|
310
|
-
if (!optionalString(d, "messageId"))
|
|
311
|
-
return malformed("TOOL_CALL_RESULT", "data.messageId", "a string when present");
|
|
312
|
-
return optionalBoolean(d, "truncated") ? undefined : malformed("TOOL_CALL_RESULT", "data.truncated", "a boolean when present");
|
|
313
|
-
case "CUSTOM":
|
|
314
|
-
if (typeof d.name !== "string" || d.name.length === 0) {
|
|
315
|
-
return malformed("CUSTOM", "data.name", "a non-empty string");
|
|
316
|
-
}
|
|
317
|
-
return Object.hasOwn(d, "value")
|
|
318
|
-
? undefined
|
|
319
|
-
: malformed("CUSTOM", "data.value", "present JSON data");
|
|
320
|
-
case "LOG":
|
|
321
|
-
if (e.channel !== "log")
|
|
322
|
-
return malformed("LOG", "channel", '"log"');
|
|
323
|
-
if (typeof e.level !== "string" || !LOG_LEVELS.has(e.level)) {
|
|
324
|
-
return malformed("LOG", "level", `one of ${AEX_LOG_LEVELS.join(", ")}`);
|
|
325
|
-
}
|
|
326
|
-
if (d.level !== e.level)
|
|
327
|
-
return malformed("LOG", "data.level", "the first-class event level");
|
|
328
|
-
if (typeof d.message !== "string")
|
|
329
|
-
return malformed("LOG", "data.message", "a string");
|
|
330
|
-
if (d.fields !== undefined && !isJsonObjectShape(d.fields))
|
|
331
|
-
return malformed("LOG", "data.fields", "a JSON object when present");
|
|
332
|
-
return optionalBoolean(d, "truncated") ? undefined : malformed("LOG", "data.truncated", "a boolean when present");
|
|
333
|
-
default:
|
|
334
|
-
return null;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
/** Classify an open event without cloning or rewriting it. */
|
|
338
|
-
export function classifyAexEvent(event) {
|
|
339
|
-
const issue = knownIssue(event);
|
|
340
|
-
if (issue === null)
|
|
341
|
-
return { kind: "unknown", event };
|
|
342
|
-
if (issue !== undefined)
|
|
343
|
-
return { kind: "malformed_known", event, issue };
|
|
344
|
-
return { kind: "known", event: event };
|
|
345
|
-
}
|
|
346
|
-
/** True only for a currently understood event with a valid payload. */
|
|
347
|
-
export function isKnownAexEvent(e) {
|
|
348
|
-
return knownIssue(e) === undefined;
|
|
349
|
-
}
|
|
350
|
-
export function isRunStarted(e) {
|
|
351
|
-
return e.type === "RUN_STARTED" && knownIssue(e) === undefined;
|
|
352
|
-
}
|
|
353
|
-
export function isRunFinished(e) {
|
|
354
|
-
return e.type === "RUN_FINISHED" && knownIssue(e) === undefined;
|
|
355
|
-
}
|
|
356
|
-
export function isRunError(e) {
|
|
357
|
-
return e.type === "RUN_ERROR" && knownIssue(e) === undefined;
|
|
358
|
-
}
|
|
359
|
-
/** A valid terminal event of either flavour (finished or error). */
|
|
360
|
-
export function isRunTerminal(e) {
|
|
361
|
-
return (e.type === "RUN_FINISHED" || e.type === "RUN_ERROR") && knownIssue(e) === undefined;
|
|
362
|
-
}
|
|
363
|
-
export function isTextMessage(e) {
|
|
364
|
-
return e.type === "TEXT_MESSAGE_CONTENT" && knownIssue(e) === undefined;
|
|
365
|
-
}
|
|
366
|
-
export function isToolCallStart(e) {
|
|
367
|
-
return e.type === "TOOL_CALL_START" && knownIssue(e) === undefined;
|
|
368
|
-
}
|
|
369
|
-
export function isToolCallResult(e) {
|
|
370
|
-
return e.type === "TOOL_CALL_RESULT" && knownIssue(e) === undefined;
|
|
371
|
-
}
|
|
372
|
-
export function isCustom(e) {
|
|
373
|
-
return e.type === "CUSTOM" && knownIssue(e) === undefined;
|
|
374
|
-
}
|
|
375
|
-
/** The `aex.*` name of a valid CUSTOM event, or null otherwise. */
|
|
376
|
-
export function customName(e) {
|
|
377
|
-
return isCustom(e) ? e.data.name : null;
|
|
378
|
-
}
|
|
379
|
-
/**
|
|
380
|
-
* The CUSTOM `data.name` of the HITL write-gate park: the session has reached the
|
|
381
|
-
* `awaiting_approval` state before a gated action and is holding for an
|
|
382
|
-
* `approve()`/`deny()`. Structural (independent of model prose).
|
|
383
|
-
*/
|
|
384
|
-
export const AEX_SESSION_AWAITING_APPROVAL_NAME = "aex.session.awaiting_approval";
|
|
385
|
-
/** The CUSTOM `data.name` carrying a schema-decoded value (`{ value }`). */
|
|
386
|
-
export const AEX_RESULT_DECODED_NAME = "aex.result.decoded";
|
|
387
|
-
/** The CUSTOM `data.name` carrying a typed decode refusal (`{ reason, detail? }`). */
|
|
388
|
-
export const AEX_RESULT_REFUSED_NAME = "aex.result.refused";
|
|
389
|
-
/** True for the HITL `awaiting_approval` gate event. */
|
|
390
|
-
export function isAwaitingApproval(e) {
|
|
391
|
-
return isCustom(e) && e.data.name === AEX_SESSION_AWAITING_APPROVAL_NAME;
|
|
392
|
-
}
|
|
393
|
-
/** True for a schema-decoded terminal result event. */
|
|
394
|
-
export function isResultDecoded(e) {
|
|
395
|
-
return isCustom(e) && e.data.name === AEX_RESULT_DECODED_NAME;
|
|
396
|
-
}
|
|
397
|
-
/** True for a typed decode-refusal terminal result event. */
|
|
398
|
-
export function isResultRefused(e) {
|
|
399
|
-
return isCustom(e) && e.data.name === AEX_RESULT_REFUSED_NAME;
|
|
400
|
-
}
|
|
401
|
-
export function isFromSource(e, source) {
|
|
402
|
-
return e.source === source;
|
|
403
|
-
}
|
|
404
|
-
/** The channel a record rides, defaulting an absent value to `"event"`. */
|
|
405
|
-
export function channelOf(e) {
|
|
406
|
-
return e.channel ?? "event";
|
|
407
|
-
}
|
|
408
|
-
/** True when a record is a valid log line (the `log` channel / `LOG` type). */
|
|
409
|
-
export function isLog(e) {
|
|
410
|
-
return e.type === "LOG" && knownIssue(e) === undefined;
|
|
411
|
-
}
|
|
412
|
-
/** True when a record is a typed AG-UI event (the `event` channel). */
|
|
413
|
-
export function isEventChannel(e) {
|
|
414
|
-
return channelOf(e) === "event";
|
|
415
|
-
}
|
|
416
|
-
// --- Oversized-payload rule (2 MB SQLite row cap) -----------------------------
|
|
417
|
-
/**
|
|
418
|
-
* The coordinator's embedded store caps a
|
|
419
|
-
* single row at 2 MB. Events whose serialized form exceeds the budget must be
|
|
420
|
-
* split before insert (the coordinator's responsibility); the archive uses the
|
|
421
|
-
* same bound. A conservative margin under the hard 2 MiB leaves room for row
|
|
422
|
-
* overhead and column framing.
|
|
423
|
-
*/
|
|
424
|
-
export const EVENT_ROW_MAX_BYTES = 2_000_000;
|
|
425
|
-
/** Serialized UTF-8 byte length of an event (the size the row must hold). */
|
|
426
|
-
export function serializedEventBytes(e) {
|
|
427
|
-
return new TextEncoder().encode(JSON.stringify(e)).byteLength;
|
|
428
|
-
}
|
|
429
|
-
/** True when an event's serialized form exceeds the row budget and must be split. */
|
|
430
|
-
export function exceedsRowBudget(e, max = EVENT_ROW_MAX_BYTES) {
|
|
431
|
-
return serializedEventBytes(e) > max;
|
|
432
|
-
}
|
|
433
|
-
/**
|
|
434
|
-
* Project an aex envelope to a strict AG-UI event so an off-the-shelf
|
|
435
|
-
* AG-UI client can consume an aex start with no glue. This is the
|
|
436
|
-
* client-side projection the SDK exposes.
|
|
437
|
-
*/
|
|
438
|
-
export function toAGUI(e) {
|
|
439
|
-
const timestamp = Date.parse(e.time);
|
|
440
|
-
const classified = classifyAexEvent(e);
|
|
441
|
-
if (classified.kind === "malformed_known") {
|
|
442
|
-
throw new MalformedAexEventError(classified.issue);
|
|
443
|
-
}
|
|
444
|
-
if (classified.kind === "unknown") {
|
|
445
|
-
return { type: "CUSTOM", timestamp, name: e.type, value: { ...e.data } };
|
|
446
|
-
}
|
|
447
|
-
const known = classified.event;
|
|
448
|
-
switch (known.type) {
|
|
449
|
-
case "RUN_STARTED":
|
|
450
|
-
return { type: "RUN_STARTED", timestamp, threadId: known.threadId, runId: known.runId };
|
|
451
|
-
case "RUN_FINISHED": {
|
|
452
|
-
const result = known.data.result;
|
|
453
|
-
return {
|
|
454
|
-
type: "RUN_FINISHED",
|
|
455
|
-
timestamp,
|
|
456
|
-
threadId: known.threadId,
|
|
457
|
-
runId: known.runId,
|
|
458
|
-
...(result !== undefined ? { result } : {})
|
|
459
|
-
};
|
|
460
|
-
}
|
|
461
|
-
case "RUN_ERROR":
|
|
462
|
-
return {
|
|
463
|
-
type: "RUN_ERROR",
|
|
464
|
-
timestamp,
|
|
465
|
-
message: known.data.failureMessage,
|
|
466
|
-
code: known.data.failureClass
|
|
467
|
-
};
|
|
468
|
-
case "TEXT_MESSAGE_CONTENT":
|
|
469
|
-
return {
|
|
470
|
-
type: "TEXT_MESSAGE_CONTENT",
|
|
471
|
-
timestamp,
|
|
472
|
-
messageId: known.data.messageId ?? known.data.eventId ?? known.id,
|
|
473
|
-
delta: known.data.text
|
|
474
|
-
};
|
|
475
|
-
case "TOOL_CALL_START":
|
|
476
|
-
return {
|
|
477
|
-
type: "TOOL_CALL_START",
|
|
478
|
-
timestamp,
|
|
479
|
-
toolCallId: known.data.id,
|
|
480
|
-
toolCallName: known.data.name
|
|
481
|
-
};
|
|
482
|
-
case "TOOL_CALL_RESULT":
|
|
483
|
-
return {
|
|
484
|
-
type: "TOOL_CALL_RESULT",
|
|
485
|
-
timestamp,
|
|
486
|
-
messageId: known.data.messageId ?? known.id,
|
|
487
|
-
toolCallId: known.data.id,
|
|
488
|
-
content: known.data.content
|
|
489
|
-
};
|
|
490
|
-
case "CUSTOM":
|
|
491
|
-
return { type: "CUSTOM", timestamp, name: known.data.name, value: known.data.value };
|
|
492
|
-
case "LOG":
|
|
493
|
-
// Logs ride the `log` channel and are normally filtered out before
|
|
494
|
-
// projection. If a consumer projects one anyway, carry it under AG-UI's
|
|
495
|
-
// reserved CUSTOM so the client still receives a valid record.
|
|
496
|
-
return { type: "CUSTOM", timestamp, name: "aex.log", value: { ...known.data } };
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
function clip(s, max = 200) {
|
|
500
|
-
return s.length <= max ? s : `${s.slice(0, max - 1)}…`;
|
|
501
|
-
}
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Client-side consumer of the event coordinator's WebSocket stream.
|
|
3
|
-
*
|
|
4
|
-
* One mechanism for catch-up + resume + live: subscribe = read-from-cursor +
|
|
5
|
-
* tail. The consumer opens a WS to the coordinator with a connection ticket,
|
|
6
|
-
* replays from its cursor, and yields {@link AexStreamEvent}s as they arrive.
|
|
7
|
-
* On a transport drop it reconnects with backoff and resumes from the last
|
|
8
|
-
* durable sequence it saw — `from = lastSeq + 1`. Provisional
|
|
9
|
-
* {@link AexLiveEvent}s are deduplicated by stable `id` but never advance that
|
|
10
|
-
* replay cursor. It stops on a durable terminal event, on abort,
|
|
11
|
-
* or when the caller breaks the iterator.
|
|
12
|
-
*
|
|
13
|
-
* A silently half-open socket (no close/error, no frames) is the dangerous
|
|
14
|
-
* case: the read loop would block forever and MISS a terminal that was already
|
|
15
|
-
* persisted server-side. So the client sends a post-open replay trigger plus a
|
|
16
|
-
* tiny keep-alive ping the coordinator answers with a matching pong, and uses an idle
|
|
17
|
-
* watchdog: if no frame arrives within {@link CoordinatorStreamOptions.idleTimeoutMs},
|
|
18
|
-
* the socket is treated as dead and reconnected — resume-from-cursor then
|
|
19
|
-
* replays the terminal.
|
|
20
|
-
*
|
|
21
|
-
* Filtering and projection are the client's concern (the wire carries the
|
|
22
|
-
* whole session): compose {@link filterStream} with the envelope guards, and
|
|
23
|
-
* {@link mapStream} with {@link toAGUI}, on top of this stream.
|
|
24
|
-
*
|
|
25
|
-
* The WebSocket is injectable so the SDK/CLI use the global `WebSocket`
|
|
26
|
-
* (Bun and Node 22+ ship it; no dependency) and tests drive a fake. The timers
|
|
27
|
-
* are injectable the same way ({@link TimerPort}) so the watchdog/backoff
|
|
28
|
-
* clocks are deterministic under test.
|
|
29
|
-
*/
|
|
30
|
-
import { type AexEvent, type AexEventBase, type AexRunErrorEvent, type AexRunFinishedEvent, type AexStreamEvent } from "./event-envelope.js";
|
|
31
|
-
/** The slice of the WHATWG WebSocket this client depends on. */
|
|
32
|
-
export interface WebSocketLike {
|
|
33
|
-
close(code?: number, reason?: string): void;
|
|
34
|
-
addEventListener(type: "open" | "message" | "close" | "error", listener: (ev: {
|
|
35
|
-
data?: unknown;
|
|
36
|
-
}) => void): void;
|
|
37
|
-
/** Send a keep-alive ping. Optional: a transport without it just relies on real events to reset the watchdog. */
|
|
38
|
-
send?(data: string): void;
|
|
39
|
-
}
|
|
40
|
-
export type WebSocketFactory = (url: string) => WebSocketLike;
|
|
41
|
-
/**
|
|
42
|
-
* The four host timer functions the stream client schedules on. Injectable so
|
|
43
|
-
* tests drive the watchdog/ping/backoff timers deterministically without
|
|
44
|
-
* swapping globals; defaults to the host's own timers. Handles are opaque:
|
|
45
|
-
* whatever `setTimeout`/`setInterval` return is what the matching clear
|
|
46
|
-
* receives.
|
|
47
|
-
*/
|
|
48
|
-
export interface TimerPort {
|
|
49
|
-
setTimeout(callback: () => void, delayMs: number): unknown;
|
|
50
|
-
clearTimeout(handle: unknown): void;
|
|
51
|
-
setInterval(callback: () => void, delayMs: number): unknown;
|
|
52
|
-
clearInterval(handle: unknown): void;
|
|
53
|
-
}
|
|
54
|
-
export interface CoordinatorStreamOptions {
|
|
55
|
-
/** Base subscribe URL, e.g. `wss://coordinator/sessions/<id>/subscribe`. */
|
|
56
|
-
readonly wsUrl: string;
|
|
57
|
-
/** Starting cursor: events with `sequence >= from` are delivered. Default 0 (from start). */
|
|
58
|
-
readonly from?: number;
|
|
59
|
-
/** Mint/refresh a short-lived connection ticket (called before each connect). */
|
|
60
|
-
readonly fetchTicket: () => Promise<string>;
|
|
61
|
-
readonly signal?: AbortSignal;
|
|
62
|
-
/** Injected WebSocket constructor; defaults to the global `WebSocket`. */
|
|
63
|
-
readonly webSocketFactory?: WebSocketFactory;
|
|
64
|
-
/** Reconnect ceiling (default: unlimited until terminal/abort). */
|
|
65
|
-
readonly maxReconnects?: number;
|
|
66
|
-
/** Backoff between reconnect attempts (default 500 ms). */
|
|
67
|
-
readonly reconnectDelayMs?: number;
|
|
68
|
-
/**
|
|
69
|
-
* Predicate that decides which event ENDS the stream. Default: the AG-UI
|
|
70
|
-
* terminal events (RUN_FINISHED / RUN_ERROR). A terminal is emitted only
|
|
71
|
-
* after the run's checkpoint, accounting, and session state are committed.
|
|
72
|
-
*/
|
|
73
|
-
readonly isTerminal?: (event: AexEvent) => boolean;
|
|
74
|
-
/**
|
|
75
|
-
* Half-open watchdog window. If no frame (a real event OR a keep-alive pong)
|
|
76
|
-
* arrives within this many ms, the socket is treated as dead and reconnected
|
|
77
|
-
* (resume from cursor). Default 45s. Set 0 to disable.
|
|
78
|
-
*/
|
|
79
|
-
readonly idleTimeoutMs?: number;
|
|
80
|
-
/**
|
|
81
|
-
* Client keep-alive ping cadence. The client sends {@link COORDINATOR_PING},
|
|
82
|
-
* which the coordinator answers with a matching pong, so
|
|
83
|
-
* a legitimately quiet session keeps the socket measurably alive and does not trip
|
|
84
|
-
* the watchdog. Default 15s. Set 0 to disable (then only real events reset the
|
|
85
|
-
* watchdog → quiet sessions may reconnect).
|
|
86
|
-
*/
|
|
87
|
-
readonly pingIntervalMs?: number;
|
|
88
|
-
/**
|
|
89
|
-
* Event-quiet recheck window. A pong proves the SOCKET is alive, not the
|
|
90
|
-
* delivery pipeline behind it — a server-side subscription that died (reaped
|
|
91
|
-
* connection row, wedged fan-out) keeps answering pings while never delivering
|
|
92
|
-
* another event, so the idle watchdog alone would hang one frame short of the
|
|
93
|
-
* terminal forever. If no REAL event frame arrives within this many ms the
|
|
94
|
-
* client silently reconnects (resume from cursor) — the replay-on-connect path
|
|
95
|
-
* reads the event store directly, so a dead subscription self-heals. Default
|
|
96
|
-
* 90s. Set 0 to disable.
|
|
97
|
-
*/
|
|
98
|
-
readonly eventQuietRecheckMs?: number;
|
|
99
|
-
/**
|
|
100
|
-
* Injected timer functions for the idle watchdog, event-quiet recheck,
|
|
101
|
-
* keep-alive ping, and reconnect backoff. Default: the host's own timers.
|
|
102
|
-
*/
|
|
103
|
-
readonly timers?: TimerPort;
|
|
104
|
-
}
|
|
105
|
-
/** An open event narrowed only to a run-terminal discriminant, not a validated payload. */
|
|
106
|
-
export type RunTerminalTypeEvent<T extends AexEventBase = AexEventBase> = T & {
|
|
107
|
-
readonly type: AexRunFinishedEvent["type"] | AexRunErrorEvent["type"];
|
|
108
|
-
};
|
|
109
|
-
/**
|
|
110
|
-
* True for either run-terminal discriminant, including a malformed payload.
|
|
111
|
-
*
|
|
112
|
-
* Streaming uses this weaker boundary so a malformed terminal still ends the
|
|
113
|
-
* read loop and reaches the canonical payload validation/error path. Consumers
|
|
114
|
-
* that need validated terminal data must use `isRunTerminal` instead.
|
|
115
|
-
* Internal-only: intentionally omitted from the public contracts barrel.
|
|
116
|
-
*/
|
|
117
|
-
export declare function hasRunTerminalType<T extends AexEventBase>(event: T): event is RunTerminalTypeEvent<T>;
|
|
118
|
-
export declare function streamCoordinatorEvents(opts: CoordinatorStreamOptions): AsyncGenerator<AexStreamEvent, void, void>;
|
|
119
|
-
/** Async-iterable filter — keep only events matching the predicate. */
|
|
120
|
-
export declare function filterStream<T>(stream: AsyncIterable<T>, predicate: (event: T) => boolean): AsyncGenerator<T, void, void>;
|
|
121
|
-
/** Async-iterable map — project each event (e.g. with `toAGUI`). */
|
|
122
|
-
export declare function mapStream<T, U>(stream: AsyncIterable<T>, project: (event: T) => U): AsyncGenerator<U, void, void>;
|