@aexhq/sdk 0.46.5-canary → 0.51.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 +54 -29
- package/dist/client/aex.d.ts +33 -0
- package/dist/client/aex.js +108 -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 +18 -0
- package/dist/downloads/download.js +67 -0
- package/dist/downloads/download.js.map +1 -0
- package/dist/generated/errors.d.ts +12 -0
- package/dist/generated/errors.js +82 -0
- package/dist/generated/errors.js.map +1 -0
- package/dist/generated/models.d.ts +1392 -0
- package/dist/generated/models.js +62 -0
- package/dist/generated/models.js.map +1 -0
- package/dist/generated/resources.d.ts +710 -0
- package/dist/generated/resources.js +582 -0
- package/dist/generated/resources.js.map +1 -0
- package/dist/generated/routes.d.ts +44 -0
- package/dist/generated/routes.js +1905 -0
- package/dist/generated/routes.js.map +1 -0
- package/dist/index.d.ts +21 -50
- package/dist/index.js +14 -62
- package/dist/index.js.map +1 -1
- package/dist/node/session-file-limits.d.ts +4 -0
- package/dist/node/session-file-limits.js +7 -0
- package/dist/node/session-file-limits.js.map +1 -0
- package/dist/node/session-files.d.ts +80 -0
- package/dist/node/session-files.js +254 -0
- package/dist/node/session-files.js.map +1 -0
- 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 +33 -0
- package/dist/transport/transport.js.map +1 -0
- package/package.json +67 -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,445 +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 { isReplayableEvent } from "./event-envelope.js";
|
|
31
|
-
/**
|
|
32
|
-
* True for either run-terminal discriminant, including a malformed payload.
|
|
33
|
-
*
|
|
34
|
-
* Streaming uses this weaker boundary so a malformed terminal still ends the
|
|
35
|
-
* read loop and reaches the canonical payload validation/error path. Consumers
|
|
36
|
-
* that need validated terminal data must use `isRunTerminal` instead.
|
|
37
|
-
* Internal-only: intentionally omitted from the public contracts barrel.
|
|
38
|
-
*/
|
|
39
|
-
export function hasRunTerminalType(event) {
|
|
40
|
-
return event.type === "RUN_FINISHED" || event.type === "RUN_ERROR";
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Keep-alive ping the client sends; the coordinator answers it with the matching
|
|
44
|
-
* pong in its WebSocket message handler. Must stay byte-identical to
|
|
45
|
-
* the coordinator's pair (platform `packages/shared/src/event-stream-client.ts`).
|
|
46
|
-
*/
|
|
47
|
-
const COORDINATOR_PING = "aex:ping";
|
|
48
|
-
/**
|
|
49
|
-
* Pull request for everything from `nextSequence` onward.
|
|
50
|
-
*
|
|
51
|
-
* Sent on open ($connect cannot safely PostToConnection before the handshake
|
|
52
|
-
* completes) and again whenever a frame declares a predecessor this client has
|
|
53
|
-
* not reached. Catch-up is PULL-based because the connection row holds only the
|
|
54
|
-
* server's BELIEF about what reached the socket: a frame that was posted but
|
|
55
|
-
* never arrived leaves the client behind that belief with no way for the server
|
|
56
|
-
* to notice. Naming the cursor makes the client authoritative about what it
|
|
57
|
-
* actually holds. An older coordinator ignores the extra field and falls back to
|
|
58
|
-
* its own high-water, so sending it is safe against any deployed server.
|
|
59
|
-
*/
|
|
60
|
-
const replayFrom = (nextSequence) => JSON.stringify({ action: "replay", from: nextSequence });
|
|
61
|
-
/** Default half-open watchdog window — 3× the ping cadence, so 2 pongs can be lost. */
|
|
62
|
-
const DEFAULT_IDLE_TIMEOUT_MS = 45_000;
|
|
63
|
-
/** Default client keep-alive ping cadence. */
|
|
64
|
-
const DEFAULT_PING_INTERVAL_MS = 15_000;
|
|
65
|
-
/** Default event-quiet recheck window (a silent reconnect, so the cost of a false positive is small). */
|
|
66
|
-
const DEFAULT_EVENT_QUIET_RECHECK_MS = 90_000;
|
|
67
|
-
/** Recent best-effort frames retained across reconnects for duplicate suppression. */
|
|
68
|
-
const MAX_SEEN_LIVE_IDS = 4096;
|
|
69
|
-
/** Host timers, resolved at call time so environment-level fakes still apply. */
|
|
70
|
-
const HOST_TIMERS = {
|
|
71
|
-
setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
|
|
72
|
-
clearTimeout: (handle) => clearTimeout(handle),
|
|
73
|
-
setInterval: (callback, delayMs) => setInterval(callback, delayMs),
|
|
74
|
-
clearInterval: (handle) => clearInterval(handle)
|
|
75
|
-
};
|
|
76
|
-
export async function* streamCoordinatorEvents(opts) {
|
|
77
|
-
const makeWs = opts.webSocketFactory ?? ((url) => new WebSocket(url));
|
|
78
|
-
const isTerminal = opts.isTerminal ?? hasRunTerminalType;
|
|
79
|
-
const reconnectDelayMs = opts.reconnectDelayMs ?? 500;
|
|
80
|
-
const maxReconnects = opts.maxReconnects ?? Number.POSITIVE_INFINITY;
|
|
81
|
-
const idleTimeoutMs = opts.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;
|
|
82
|
-
const pingIntervalMs = opts.pingIntervalMs ?? DEFAULT_PING_INTERVAL_MS;
|
|
83
|
-
const eventQuietRecheckMs = opts.eventQuietRecheckMs ?? DEFAULT_EVENT_QUIET_RECHECK_MS;
|
|
84
|
-
const timerPort = opts.timers ?? HOST_TIMERS;
|
|
85
|
-
let cursor = (opts.from ?? 0) - 1;
|
|
86
|
-
let attempts = 0;
|
|
87
|
-
let done = false;
|
|
88
|
-
// Live frames have no replay cursor. Retain a bounded reconnect window of
|
|
89
|
-
// stable ids; durable frames remain exactly deduplicated by their cursor.
|
|
90
|
-
const seenLiveIds = new Map();
|
|
91
|
-
const rememberLiveId = (id) => {
|
|
92
|
-
if (seenLiveIds.delete(id)) {
|
|
93
|
-
seenLiveIds.set(id, true);
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
seenLiveIds.set(id, true);
|
|
97
|
-
if (seenLiveIds.size > MAX_SEEN_LIVE_IDS) {
|
|
98
|
-
const oldest = seenLiveIds.keys().next().value;
|
|
99
|
-
if (oldest !== undefined)
|
|
100
|
-
seenLiveIds.delete(oldest);
|
|
101
|
-
}
|
|
102
|
-
return true;
|
|
103
|
-
};
|
|
104
|
-
while (!done && !opts.signal?.aborted) {
|
|
105
|
-
const ticket = await opts.fetchTicket();
|
|
106
|
-
const url = new URL(opts.wsUrl);
|
|
107
|
-
url.searchParams.set("ticket", ticket);
|
|
108
|
-
url.searchParams.set("from", String(cursor + 1));
|
|
109
|
-
const ws = makeWs(url.toString());
|
|
110
|
-
const pending = [];
|
|
111
|
-
const seenSequences = new Set();
|
|
112
|
-
const catchUp = createCatchUp(ws, cursor);
|
|
113
|
-
let closed = false;
|
|
114
|
-
let disconnectReason = "";
|
|
115
|
-
let resolveNext = null;
|
|
116
|
-
const wake = () => {
|
|
117
|
-
if (resolveNext) {
|
|
118
|
-
const r = resolveNext;
|
|
119
|
-
resolveNext = null;
|
|
120
|
-
r();
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
const waitForWake = (timeoutMs) => new Promise((resolve) => {
|
|
124
|
-
let timer = null;
|
|
125
|
-
const finish = () => {
|
|
126
|
-
if (timer !== null) {
|
|
127
|
-
timerPort.clearTimeout(timer);
|
|
128
|
-
timer = null;
|
|
129
|
-
}
|
|
130
|
-
if (resolveNext === finish)
|
|
131
|
-
resolveNext = null;
|
|
132
|
-
resolve();
|
|
133
|
-
};
|
|
134
|
-
resolveNext = finish;
|
|
135
|
-
if (typeof timeoutMs === "number")
|
|
136
|
-
timer = timerPort.setTimeout(finish, timeoutMs);
|
|
137
|
-
});
|
|
138
|
-
const takeNextPending = () => {
|
|
139
|
-
const first = pending[0];
|
|
140
|
-
if (!isReplayableEvent(first))
|
|
141
|
-
return pending.shift();
|
|
142
|
-
// A live frame does not participate in the durable cursor. Select the
|
|
143
|
-
// lowest durable sequence for this durable slot without moving live
|
|
144
|
-
// frames, so a higher sequence cannot advance the cursor past a pending
|
|
145
|
-
// lower sequence merely because a live frame separated their arrival.
|
|
146
|
-
let lowestIndex = 0;
|
|
147
|
-
let lowestSequence = first.sequence;
|
|
148
|
-
for (let index = 1; index < pending.length; index += 1) {
|
|
149
|
-
const candidate = pending[index];
|
|
150
|
-
if (isReplayableEvent(candidate) && candidate.sequence < lowestSequence) {
|
|
151
|
-
lowestIndex = index;
|
|
152
|
-
lowestSequence = candidate.sequence;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
if (lowestIndex > 0) {
|
|
156
|
-
pending[0] = pending[lowestIndex];
|
|
157
|
-
pending[lowestIndex] = first;
|
|
158
|
-
}
|
|
159
|
-
return pending.shift();
|
|
160
|
-
};
|
|
161
|
-
let idleTimer = null;
|
|
162
|
-
let pingTimer = null;
|
|
163
|
-
let quietTimer = null;
|
|
164
|
-
const stopTimers = () => {
|
|
165
|
-
if (idleTimer !== null) {
|
|
166
|
-
timerPort.clearTimeout(idleTimer);
|
|
167
|
-
idleTimer = null;
|
|
168
|
-
}
|
|
169
|
-
if (pingTimer !== null) {
|
|
170
|
-
timerPort.clearInterval(pingTimer);
|
|
171
|
-
pingTimer = null;
|
|
172
|
-
}
|
|
173
|
-
if (quietTimer !== null) {
|
|
174
|
-
timerPort.clearTimeout(quietTimer);
|
|
175
|
-
quietTimer = null;
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
// Re-arm on every inbound frame. On expiry the socket is presumed half-open
|
|
179
|
-
// → close it and let the loop fall through to reconnect (resume from cursor).
|
|
180
|
-
const armIdle = () => {
|
|
181
|
-
if (idleTimeoutMs <= 0)
|
|
182
|
-
return;
|
|
183
|
-
if (idleTimer !== null)
|
|
184
|
-
timerPort.clearTimeout(idleTimer);
|
|
185
|
-
idleTimer = timerPort.setTimeout(() => {
|
|
186
|
-
idleTimer = null;
|
|
187
|
-
if (closed)
|
|
188
|
-
return;
|
|
189
|
-
closed = true;
|
|
190
|
-
disconnectReason = "idle";
|
|
191
|
-
closeQuietly(ws);
|
|
192
|
-
wake();
|
|
193
|
-
}, idleTimeoutMs);
|
|
194
|
-
};
|
|
195
|
-
// Re-arm only on REAL event frames. On expiry: silent reconnect (resume from
|
|
196
|
-
// cursor) — self-heals a dead server-side subscription a pong can't expose.
|
|
197
|
-
const armQuiet = () => {
|
|
198
|
-
if (eventQuietRecheckMs <= 0)
|
|
199
|
-
return;
|
|
200
|
-
if (quietTimer !== null)
|
|
201
|
-
timerPort.clearTimeout(quietTimer);
|
|
202
|
-
quietTimer = timerPort.setTimeout(() => {
|
|
203
|
-
quietTimer = null;
|
|
204
|
-
if (closed)
|
|
205
|
-
return;
|
|
206
|
-
closed = true;
|
|
207
|
-
disconnectReason = "quiet_recheck";
|
|
208
|
-
closeQuietly(ws);
|
|
209
|
-
wake();
|
|
210
|
-
}, eventQuietRecheckMs);
|
|
211
|
-
};
|
|
212
|
-
ws.addEventListener("open", () => {
|
|
213
|
-
armIdle();
|
|
214
|
-
catchUp.request();
|
|
215
|
-
if (pingIntervalMs > 0 && typeof ws.send === "function") {
|
|
216
|
-
pingTimer = timerPort.setInterval(() => {
|
|
217
|
-
try {
|
|
218
|
-
ws.send(COORDINATOR_PING);
|
|
219
|
-
}
|
|
220
|
-
catch {
|
|
221
|
-
// socket not open / send unsupported — the idle watchdog still covers it
|
|
222
|
-
}
|
|
223
|
-
}, pingIntervalMs);
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
ws.addEventListener("message", (ev) => {
|
|
227
|
-
armIdle();
|
|
228
|
-
const data = typeof ev.data === "string" ? ev.data : "";
|
|
229
|
-
if (!data)
|
|
230
|
-
return;
|
|
231
|
-
try {
|
|
232
|
-
const evt = JSON.parse(data);
|
|
233
|
-
if (!isCoordinatorStreamEvent(evt))
|
|
234
|
-
return;
|
|
235
|
-
armQuiet(); // a real event frame proves the delivery pipeline, not just the socket
|
|
236
|
-
if (isReplayableEvent(evt)) {
|
|
237
|
-
if (evt.sequence <= cursor || seenSequences.has(evt.sequence))
|
|
238
|
-
return;
|
|
239
|
-
// A frame the client cannot chain is refused, leaving both the cursor
|
|
240
|
-
// and `seenSequences` untouched so the pull's copy of it is not later
|
|
241
|
-
// suppressed as a duplicate.
|
|
242
|
-
if (!catchUp.chains(evt))
|
|
243
|
-
return;
|
|
244
|
-
seenSequences.add(evt.sequence);
|
|
245
|
-
}
|
|
246
|
-
else if (!rememberLiveId(evt.id)) {
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
pending.push(evt);
|
|
250
|
-
wake();
|
|
251
|
-
}
|
|
252
|
-
catch {
|
|
253
|
-
// ignore a non-JSON frame
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
ws.addEventListener("close", (ev) => {
|
|
257
|
-
stopTimers();
|
|
258
|
-
// Don't clobber a reason already decided (idle/abort closes the socket too).
|
|
259
|
-
if (!closed) {
|
|
260
|
-
closed = true;
|
|
261
|
-
const code = ev?.code;
|
|
262
|
-
disconnectReason = `close${typeof code === "number" ? ` code=${code}` : ""}`;
|
|
263
|
-
}
|
|
264
|
-
wake();
|
|
265
|
-
});
|
|
266
|
-
ws.addEventListener("error", () => {
|
|
267
|
-
stopTimers();
|
|
268
|
-
if (!closed) {
|
|
269
|
-
closed = true;
|
|
270
|
-
disconnectReason = "error";
|
|
271
|
-
}
|
|
272
|
-
wake();
|
|
273
|
-
});
|
|
274
|
-
const onAbort = () => {
|
|
275
|
-
closeQuietly(ws);
|
|
276
|
-
closed = true;
|
|
277
|
-
stopTimers();
|
|
278
|
-
wake();
|
|
279
|
-
};
|
|
280
|
-
opts.signal?.addEventListener("abort", onAbort, { once: true });
|
|
281
|
-
// Arm immediately: a connect that never reaches "open" (and fakes that
|
|
282
|
-
// never emit it) must still time out rather than hang forever. The quiet
|
|
283
|
-
// recheck arms here too so a socket fed only by pongs still recycles.
|
|
284
|
-
armIdle();
|
|
285
|
-
armQuiet();
|
|
286
|
-
try {
|
|
287
|
-
while (true) {
|
|
288
|
-
while (pending.length > 0) {
|
|
289
|
-
const evt = takeNextPending();
|
|
290
|
-
if (isReplayableEvent(evt)) {
|
|
291
|
-
seenSequences.delete(evt.sequence);
|
|
292
|
-
if (evt.sequence <= cursor)
|
|
293
|
-
continue;
|
|
294
|
-
cursor = evt.sequence;
|
|
295
|
-
}
|
|
296
|
-
yield evt;
|
|
297
|
-
if (isReplayableEvent(evt) && isTerminal(evt))
|
|
298
|
-
done = true;
|
|
299
|
-
}
|
|
300
|
-
if (done || opts.signal?.aborted) {
|
|
301
|
-
closeQuietly(ws);
|
|
302
|
-
break;
|
|
303
|
-
}
|
|
304
|
-
if (closed)
|
|
305
|
-
break; // transport ended → fall through to reconnect
|
|
306
|
-
await waitForWake();
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
finally {
|
|
310
|
-
stopTimers();
|
|
311
|
-
opts.signal?.removeEventListener("abort", onAbort);
|
|
312
|
-
// A caller that `break`s the iterator triggers the generator's `return()`,
|
|
313
|
-
// which lands here with the socket still OPEN (the yield was suspended, no
|
|
314
|
-
// terminal/abort/transport-close ran). Close it so an early break never
|
|
315
|
-
// leaks a live WebSocket. Idempotent: the terminal/abort/reconnect paths
|
|
316
|
-
// have already closed it, and closeQuietly swallows a double close.
|
|
317
|
-
closeQuietly(ws);
|
|
318
|
-
}
|
|
319
|
-
if (done || opts.signal?.aborted)
|
|
320
|
-
return;
|
|
321
|
-
attempts += 1;
|
|
322
|
-
// Don't let the stream die silently — a give-up before the terminal event
|
|
323
|
-
// is exactly the case a caller needs to see (it looks like a clean end
|
|
324
|
-
// otherwise). Reconnects are rare, so the warn volume is bounded.
|
|
325
|
-
if (attempts > maxReconnects) {
|
|
326
|
-
console.warn(`[aex] event stream gave up after ${maxReconnects} reconnect attempt(s) (last: ${disconnectReason || "unknown"}); ended before a terminal event at seq ${cursor + 1}`);
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
// The quiet recheck is a routine self-heal on a legitimately quiet stream —
|
|
330
|
-
// reconnecting silently keeps a long tool call from spamming the console.
|
|
331
|
-
if (disconnectReason !== "quiet_recheck") {
|
|
332
|
-
console.warn(`[aex] event stream disconnected (${disconnectReason || "unknown"}); reconnecting attempt ${attempts} from seq ${cursor + 1}`);
|
|
333
|
-
}
|
|
334
|
-
await sleep(reconnectDelayMs, timerPort, opts.signal);
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* The exclusive lower bound the coordinator declared for a durable frame: the
|
|
339
|
-
* sequence of the public event immediately preceding it in journal projection
|
|
340
|
-
* order (`-1` when the frame opens the session).
|
|
341
|
-
*
|
|
342
|
-
* Transport-only — it describes this frame's position in the stream, not the
|
|
343
|
-
* event, so it is never part of the durable {@link AexEvent} the archive returns.
|
|
344
|
-
* Absent means the producer made no claim (an older coordinator, or a path that
|
|
345
|
-
* cannot prove what came before it), and an unproven link is not a gap: the
|
|
346
|
-
* frame is accepted exactly as it was before this check existed.
|
|
347
|
-
*/
|
|
348
|
-
function declaredPredecessor(frame) {
|
|
349
|
-
const value = frame.prevSequence;
|
|
350
|
-
return typeof value === "number" && Number.isSafeInteger(value) ? value : undefined;
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* Per-connection catch-up bookkeeping.
|
|
354
|
-
*
|
|
355
|
-
* The high-water is RECEIPT-side — the highest durable sequence admitted on this
|
|
356
|
-
* connection, including frames still queued for the consumer. The gap check has
|
|
357
|
-
* to run against that and not against the yield-side cursor, which lags while
|
|
358
|
-
* the consumer drains: a contiguous burst landing in one turn would otherwise
|
|
359
|
-
* report every frame after the first as a hole.
|
|
360
|
-
*
|
|
361
|
-
* One pull is outstanding per high-water position, so a run of unchainable
|
|
362
|
-
* frames costs one request rather than one per frame; it re-arms by
|
|
363
|
-
* construction, since the next gap at a moved position names a different one.
|
|
364
|
-
*/
|
|
365
|
-
function createCatchUp(ws, cursor) {
|
|
366
|
-
let accepted = cursor;
|
|
367
|
-
let pulledFrom = null;
|
|
368
|
-
const request = () => {
|
|
369
|
-
const from = accepted + 1;
|
|
370
|
-
if (pulledFrom === from || typeof ws.send !== "function")
|
|
371
|
-
return;
|
|
372
|
-
pulledFrom = from;
|
|
373
|
-
try {
|
|
374
|
-
ws.send(replayFrom(from));
|
|
375
|
-
}
|
|
376
|
-
catch {
|
|
377
|
-
// socket not open / send unsupported — the idle + quiet watchdogs still
|
|
378
|
-
// reconnect, and a reconnect resumes from the cursor anyway.
|
|
379
|
-
}
|
|
380
|
-
};
|
|
381
|
-
return {
|
|
382
|
-
request,
|
|
383
|
-
chains: (frame) => {
|
|
384
|
-
const predecessor = declaredPredecessor(frame);
|
|
385
|
-
if (predecessor !== undefined && predecessor > accepted) {
|
|
386
|
-
request();
|
|
387
|
-
return false;
|
|
388
|
-
}
|
|
389
|
-
if (frame.sequence > accepted)
|
|
390
|
-
accepted = frame.sequence;
|
|
391
|
-
return true;
|
|
392
|
-
}
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
function isCoordinatorStreamEvent(value) {
|
|
396
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
397
|
-
return false;
|
|
398
|
-
const event = value;
|
|
399
|
-
if (typeof event.id !== "string" ||
|
|
400
|
-
typeof event.type !== "string" ||
|
|
401
|
-
typeof event.runId !== "string" ||
|
|
402
|
-
!event.data ||
|
|
403
|
-
typeof event.data !== "object" ||
|
|
404
|
-
Array.isArray(event.data)) {
|
|
405
|
-
return false;
|
|
406
|
-
}
|
|
407
|
-
if (event.replayable === false) {
|
|
408
|
-
return event.sequence === undefined && Number.isSafeInteger(event.liveSequence) && event.liveSequence >= 0;
|
|
409
|
-
}
|
|
410
|
-
return Number.isSafeInteger(event.sequence) && event.sequence >= 0;
|
|
411
|
-
}
|
|
412
|
-
/** Async-iterable filter — keep only events matching the predicate. */
|
|
413
|
-
export async function* filterStream(stream, predicate) {
|
|
414
|
-
for await (const event of stream) {
|
|
415
|
-
if (predicate(event))
|
|
416
|
-
yield event;
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
/** Async-iterable map — project each event (e.g. with `toAGUI`). */
|
|
420
|
-
export async function* mapStream(stream, project) {
|
|
421
|
-
for await (const event of stream) {
|
|
422
|
-
yield project(event);
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
function closeQuietly(ws) {
|
|
426
|
-
try {
|
|
427
|
-
ws.close();
|
|
428
|
-
}
|
|
429
|
-
catch {
|
|
430
|
-
// already closed
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
function sleep(ms, timerPort, signal) {
|
|
434
|
-
return new Promise((resolve) => {
|
|
435
|
-
const onAbort = () => {
|
|
436
|
-
timerPort.clearTimeout(timer);
|
|
437
|
-
resolve();
|
|
438
|
-
};
|
|
439
|
-
const timer = timerPort.setTimeout(() => {
|
|
440
|
-
signal?.removeEventListener("abort", onAbort);
|
|
441
|
-
resolve();
|
|
442
|
-
}, ms);
|
|
443
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
444
|
-
});
|
|
445
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/** Guard-bearing views over durable and provisional coordinator events. */
|
|
2
|
-
import type { AexCustomEvent, AexEvent, AexEventBase, AexEventSource, AexLiveEvent, AexLogEvent, AexRunErrorEvent, AexRunFinishedEvent, AexRunStartedEvent, AexStreamEvent, AexTextMessageEvent, AexToolCallResultEvent, AexToolCallStartEvent } from "./event-envelope.js";
|
|
3
|
-
import { AEX_RESULT_DECODED_NAME, AEX_RESULT_REFUSED_NAME, AEX_SESSION_AWAITING_APPROVAL_NAME } from "./event-envelope.js";
|
|
4
|
-
type ToolCallIdMethod = {
|
|
5
|
-
toolCallId(): string;
|
|
6
|
-
};
|
|
7
|
-
/** Shared methods mixed into both durable and live-only event views. */
|
|
8
|
-
declare class EventViewPrototype {
|
|
9
|
-
isRunStarted(): this is EventViewPrototype & AexRunStartedEvent;
|
|
10
|
-
isRunFinished(): this is EventViewPrototype & AexRunFinishedEvent;
|
|
11
|
-
isRunError(): this is EventViewPrototype & AexRunErrorEvent;
|
|
12
|
-
isRunTerminal(): this is EventViewPrototype & (AexRunFinishedEvent | AexRunErrorEvent);
|
|
13
|
-
isTextMessage(): this is EventViewPrototype & AexTextMessageEvent;
|
|
14
|
-
isToolCallStart(): this is EventViewPrototype & AexToolCallStartEvent & ToolCallIdMethod;
|
|
15
|
-
isToolCallResult(): this is EventViewPrototype & AexToolCallResultEvent & ToolCallIdMethod;
|
|
16
|
-
toolCallId(): string | undefined;
|
|
17
|
-
isCustom(): this is EventViewPrototype & AexCustomEvent;
|
|
18
|
-
isAwaitingApproval(): this is EventViewPrototype & AexCustomEvent<typeof AEX_SESSION_AWAITING_APPROVAL_NAME>;
|
|
19
|
-
isResultDecoded(): this is EventViewPrototype & AexCustomEvent<typeof AEX_RESULT_DECODED_NAME>;
|
|
20
|
-
isResultRefused(): this is EventViewPrototype & AexCustomEvent<typeof AEX_RESULT_REFUSED_NAME>;
|
|
21
|
-
isLog(): this is EventViewPrototype & AexLogEvent;
|
|
22
|
-
isEventChannel(): boolean;
|
|
23
|
-
isFromSource(source: AexEventSource): boolean;
|
|
24
|
-
}
|
|
25
|
-
interface EventViewPrototype extends AexEventBase {
|
|
26
|
-
}
|
|
27
|
-
/** A durable event view. List, archive, and finished-result APIs return this. */
|
|
28
|
-
export type AexEventView = EventViewPrototype & AexEvent;
|
|
29
|
-
/** A provisional live-only event view with no durable `sequence`. */
|
|
30
|
-
export type AexLiveEventView = EventViewPrototype & AexLiveEvent;
|
|
31
|
-
/** A view yielded by live coordinator streams. */
|
|
32
|
-
export type AexStreamEventView = AexEventView | AexLiveEventView;
|
|
33
|
-
export type TextMessageEventView = AexStreamEventView & AexTextMessageEvent;
|
|
34
|
-
export type ToolCallStartEventView = AexStreamEventView & AexToolCallStartEvent & ToolCallIdMethod;
|
|
35
|
-
export type ToolCallResultEventView = AexStreamEventView & AexToolCallResultEvent & ToolCallIdMethod;
|
|
36
|
-
/** Constructor value for `instanceof`; event fields are mixed in. */
|
|
37
|
-
export declare const AexEventView: typeof EventViewPrototype;
|
|
38
|
-
/** Wrap a durable coordinator event while preserving its precise replayable type. */
|
|
39
|
-
export declare function asAexEventView(event: AexEvent): AexEventView;
|
|
40
|
-
/** Wrap a live stream event while preserving durable-vs-live discrimination. */
|
|
41
|
-
export declare function asAexStreamEventView(event: AexStreamEvent): AexStreamEventView;
|
|
42
|
-
/** Wrap each durable event in a list. */
|
|
43
|
-
export declare function asAexEventViews(events: readonly AexEvent[]): AexEventView[];
|
|
44
|
-
export {};
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/** Guard-bearing views over durable and provisional coordinator events. */
|
|
2
|
-
import { isAwaitingApproval as canonicalIsAwaitingApproval, isCustom as canonicalIsCustom, isEventChannel as canonicalIsEventChannel, isFromSource as canonicalIsFromSource, isLog as canonicalIsLog, isResultDecoded as canonicalIsResultDecoded, isResultRefused as canonicalIsResultRefused, isRunError as canonicalIsRunError, isRunFinished as canonicalIsRunFinished, isRunStarted as canonicalIsRunStarted, isRunTerminal as canonicalIsRunTerminal, isTextMessage as canonicalIsTextMessage, isToolCallResult as canonicalIsToolCallResult, isToolCallStart as canonicalIsToolCallStart } from "./event-envelope.js";
|
|
3
|
-
/** Shared methods mixed into both durable and live-only event views. */
|
|
4
|
-
class EventViewPrototype {
|
|
5
|
-
isRunStarted() {
|
|
6
|
-
return canonicalIsRunStarted(this);
|
|
7
|
-
}
|
|
8
|
-
isRunFinished() {
|
|
9
|
-
return canonicalIsRunFinished(this);
|
|
10
|
-
}
|
|
11
|
-
isRunError() {
|
|
12
|
-
return canonicalIsRunError(this);
|
|
13
|
-
}
|
|
14
|
-
isRunTerminal() {
|
|
15
|
-
return canonicalIsRunTerminal(this);
|
|
16
|
-
}
|
|
17
|
-
isTextMessage() {
|
|
18
|
-
return canonicalIsTextMessage(this);
|
|
19
|
-
}
|
|
20
|
-
isToolCallStart() {
|
|
21
|
-
return canonicalIsToolCallStart(this);
|
|
22
|
-
}
|
|
23
|
-
isToolCallResult() {
|
|
24
|
-
return canonicalIsToolCallResult(this);
|
|
25
|
-
}
|
|
26
|
-
toolCallId() {
|
|
27
|
-
const id = this.data.id;
|
|
28
|
-
return typeof id === "string" ? id : undefined;
|
|
29
|
-
}
|
|
30
|
-
isCustom() {
|
|
31
|
-
return canonicalIsCustom(this);
|
|
32
|
-
}
|
|
33
|
-
isAwaitingApproval() {
|
|
34
|
-
return canonicalIsAwaitingApproval(this);
|
|
35
|
-
}
|
|
36
|
-
isResultDecoded() {
|
|
37
|
-
return canonicalIsResultDecoded(this);
|
|
38
|
-
}
|
|
39
|
-
isResultRefused() {
|
|
40
|
-
return canonicalIsResultRefused(this);
|
|
41
|
-
}
|
|
42
|
-
isLog() {
|
|
43
|
-
return canonicalIsLog(this);
|
|
44
|
-
}
|
|
45
|
-
isEventChannel() {
|
|
46
|
-
return canonicalIsEventChannel(this);
|
|
47
|
-
}
|
|
48
|
-
isFromSource(source) {
|
|
49
|
-
return canonicalIsFromSource(this, source);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
/** Constructor value for `instanceof`; event fields are mixed in. */
|
|
53
|
-
export const AexEventView = EventViewPrototype;
|
|
54
|
-
/** Wrap a durable coordinator event while preserving its precise replayable type. */
|
|
55
|
-
export function asAexEventView(event) {
|
|
56
|
-
return wrap(event);
|
|
57
|
-
}
|
|
58
|
-
/** Wrap a live stream event while preserving durable-vs-live discrimination. */
|
|
59
|
-
export function asAexStreamEventView(event) {
|
|
60
|
-
return wrap(event);
|
|
61
|
-
}
|
|
62
|
-
/** Wrap each durable event in a list. */
|
|
63
|
-
export function asAexEventViews(events) {
|
|
64
|
-
return events.map(asAexEventView);
|
|
65
|
-
}
|
|
66
|
-
function wrap(event) {
|
|
67
|
-
const view = Object.create(EventViewPrototype.prototype);
|
|
68
|
-
return Object.assign(view, event);
|
|
69
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SSoT for the CUSTOMER-FACING failure taxonomy carried by `RUN_ERROR`.
|
|
3
|
-
*
|
|
4
|
-
* `AexRunErrorData.failureClass` used to be an open `string`, so a customer
|
|
5
|
-
* could not branch on WHY a session ended — every exhaustion looked like an
|
|
6
|
-
* opaque `failed`. This tuple closes it. The hosted platform keeps a larger
|
|
7
|
-
* PRIVATE taxonomy (orchestration detail) and projects it onto exactly this
|
|
8
|
-
* union before the value reaches a customer; the platform's
|
|
9
|
-
* `PUBLIC_FAILURE_CLASSES` is this array, imported, never a hand-copied mirror.
|
|
10
|
-
*
|
|
11
|
-
* Resource exhaustion is a first-class customer-facing outcome here:
|
|
12
|
-
* `out_of_memory`, `disk_full`, and `quota_exhausted` say what ran out. There is
|
|
13
|
-
* deliberately NO `resource_exhausted` — a code that teaches the customer
|
|
14
|
-
* nothing is worse than the `failed` it replaces.
|
|
15
|
-
*/
|
|
16
|
-
export declare const AEX_FAILURE_CLASSES: readonly ["wall_clock_exceeded", "max_turns", "budget_exhausted", "step_budget_exceeded", "step_failed", "loop_detected", "invalid_submission", "invalid_model", "workspace_restore_incomplete", "llm_response_stream_failed", "capacity_exhausted", "out_of_memory", "disk_full", "quota_exhausted", "transient-provider", "provider-permanent", "cancelled", "internal_error"];
|
|
17
|
-
/** The closed customer-facing failure taxonomy carried by `RUN_ERROR`. */
|
|
18
|
-
export type AexFailureClass = (typeof AEX_FAILURE_CLASSES)[number];
|
|
19
|
-
/** Narrow an arbitrary value to a known {@link AexFailureClass}. */
|
|
20
|
-
export declare function isAexFailureClass(value: unknown): value is AexFailureClass;
|
|
21
|
-
/**
|
|
22
|
-
* The subset that means "a resource ran out". Customers branch on this to
|
|
23
|
-
* decide between retrying smaller, upgrading, and paging a human — the whole
|
|
24
|
-
* reason the three codes exist as distinct values rather than one vague one.
|
|
25
|
-
*/
|
|
26
|
-
export declare const AEX_RESOURCE_EXHAUSTION_FAILURE_CLASSES: readonly ["out_of_memory", "disk_full", "quota_exhausted"];
|
|
27
|
-
export type AexResourceExhaustionFailureClass = (typeof AEX_RESOURCE_EXHAUSTION_FAILURE_CLASSES)[number];
|
|
28
|
-
/** True when the failure was a resource running out rather than a logic fault. */
|
|
29
|
-
export declare function isResourceExhaustionFailureClass(value: unknown): value is AexResourceExhaustionFailureClass;
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SSoT for the CUSTOMER-FACING failure taxonomy carried by `RUN_ERROR`.
|
|
3
|
-
*
|
|
4
|
-
* `AexRunErrorData.failureClass` used to be an open `string`, so a customer
|
|
5
|
-
* could not branch on WHY a session ended — every exhaustion looked like an
|
|
6
|
-
* opaque `failed`. This tuple closes it. The hosted platform keeps a larger
|
|
7
|
-
* PRIVATE taxonomy (orchestration detail) and projects it onto exactly this
|
|
8
|
-
* union before the value reaches a customer; the platform's
|
|
9
|
-
* `PUBLIC_FAILURE_CLASSES` is this array, imported, never a hand-copied mirror.
|
|
10
|
-
*
|
|
11
|
-
* Resource exhaustion is a first-class customer-facing outcome here:
|
|
12
|
-
* `out_of_memory`, `disk_full`, and `quota_exhausted` say what ran out. There is
|
|
13
|
-
* deliberately NO `resource_exhausted` — a code that teaches the customer
|
|
14
|
-
* nothing is worse than the `failed` it replaces.
|
|
15
|
-
*/
|
|
16
|
-
export const AEX_FAILURE_CLASSES = [
|
|
17
|
-
/** The session exceeded its wall-clock deadline. */
|
|
18
|
-
"wall_clock_exceeded",
|
|
19
|
-
/** The session exhausted its agent-turn budget. */
|
|
20
|
-
"max_turns",
|
|
21
|
-
/** The session exhausted its spend budget. */
|
|
22
|
-
"budget_exhausted",
|
|
23
|
-
/** A single turn exhausted its per-turn step budget. */
|
|
24
|
-
"step_budget_exceeded",
|
|
25
|
-
/** An agent step failed and could not be recovered. */
|
|
26
|
-
"step_failed",
|
|
27
|
-
/** Legacy public projection for already-persisted sessions; new runs never produce it. */
|
|
28
|
-
"loop_detected",
|
|
29
|
-
/** The submission was rejected as invalid before any work started. */
|
|
30
|
-
"invalid_submission",
|
|
31
|
-
/** The requested model is not servable. */
|
|
32
|
-
"invalid_model",
|
|
33
|
-
/** The workspace could not be restored to the state the session required. */
|
|
34
|
-
"workspace_restore_incomplete",
|
|
35
|
-
/** The provider's response stream broke mid-completion. */
|
|
36
|
-
"llm_response_stream_failed",
|
|
37
|
-
/** The platform had no capacity to place this session. */
|
|
38
|
-
"capacity_exhausted",
|
|
39
|
-
/** The runtime was killed for exceeding its memory allocation. */
|
|
40
|
-
"out_of_memory",
|
|
41
|
-
/** A write failed because the runtime's filesystem was full. */
|
|
42
|
-
"disk_full",
|
|
43
|
-
/** A metered usage grant was exhausted and there was no billable path. */
|
|
44
|
-
"quota_exhausted",
|
|
45
|
-
/** A transient provider fault; the same request may succeed on retry. */
|
|
46
|
-
"transient-provider",
|
|
47
|
-
/** A permanent provider fault; retrying the same request will not help. */
|
|
48
|
-
"provider-permanent",
|
|
49
|
-
/** The session was cancelled. */
|
|
50
|
-
"cancelled",
|
|
51
|
-
/** An unclassified platform fault. */
|
|
52
|
-
"internal_error"
|
|
53
|
-
];
|
|
54
|
-
const FAILURE_CLASS_SET = new Set(AEX_FAILURE_CLASSES);
|
|
55
|
-
/** Narrow an arbitrary value to a known {@link AexFailureClass}. */
|
|
56
|
-
export function isAexFailureClass(value) {
|
|
57
|
-
return typeof value === "string" && FAILURE_CLASS_SET.has(value);
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* The subset that means "a resource ran out". Customers branch on this to
|
|
61
|
-
* decide between retrying smaller, upgrading, and paging a human — the whole
|
|
62
|
-
* reason the three codes exist as distinct values rather than one vague one.
|
|
63
|
-
*/
|
|
64
|
-
export const AEX_RESOURCE_EXHAUSTION_FAILURE_CLASSES = [
|
|
65
|
-
"out_of_memory",
|
|
66
|
-
"disk_full",
|
|
67
|
-
"quota_exhausted"
|
|
68
|
-
];
|
|
69
|
-
const RESOURCE_EXHAUSTION_SET = new Set(AEX_RESOURCE_EXHAUSTION_FAILURE_CLASSES);
|
|
70
|
-
/** True when the failure was a resource running out rather than a logic fault. */
|
|
71
|
-
export function isResourceExhaustionFailureClass(value) {
|
|
72
|
-
return typeof value === "string" && RESOURCE_EXHAUSTION_SET.has(value);
|
|
73
|
-
}
|