@aexhq/sdk 0.38.1 → 0.40.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.
Files changed (100) hide show
  1. package/README.md +23 -17
  2. package/dist/_contracts/api-key.d.ts +49 -0
  3. package/dist/_contracts/api-key.js +87 -0
  4. package/dist/_contracts/bundle-manifest.d.ts +86 -0
  5. package/dist/_contracts/bundle-manifest.js +157 -0
  6. package/dist/_contracts/error-codes.d.ts +26 -0
  7. package/dist/_contracts/error-codes.js +79 -0
  8. package/dist/_contracts/error-factory.d.ts +32 -0
  9. package/dist/_contracts/error-factory.js +142 -0
  10. package/dist/_contracts/event-envelope.d.ts +33 -10
  11. package/dist/_contracts/event-envelope.js +46 -10
  12. package/dist/_contracts/event-view.d.ts +123 -0
  13. package/dist/_contracts/event-view.js +120 -0
  14. package/dist/_contracts/http.js +12 -3
  15. package/dist/_contracts/index.d.ts +8 -4
  16. package/dist/_contracts/index.js +11 -7
  17. package/dist/_contracts/models.d.ts +15 -0
  18. package/dist/_contracts/models.js +33 -0
  19. package/dist/_contracts/operations.d.ts +70 -2
  20. package/dist/_contracts/operations.js +143 -7
  21. package/dist/_contracts/run-config.d.ts +35 -10
  22. package/dist/_contracts/run-config.js +17 -5
  23. package/dist/_contracts/run-record.d.ts +3 -2
  24. package/dist/_contracts/runtime-types.d.ts +148 -36
  25. package/dist/_contracts/runtime-types.js +33 -1
  26. package/dist/_contracts/sdk-errors.d.ts +61 -2
  27. package/dist/_contracts/sdk-errors.js +83 -3
  28. package/dist/_contracts/sdk-secrets.js +31 -6
  29. package/dist/_contracts/stable.d.ts +14 -0
  30. package/dist/_contracts/stable.js +14 -0
  31. package/dist/_contracts/status.d.ts +28 -1
  32. package/dist/_contracts/status.js +48 -3
  33. package/dist/_contracts/submission.d.ts +157 -14
  34. package/dist/_contracts/submission.js +319 -55
  35. package/dist/_contracts/suggest.d.ts +15 -0
  36. package/dist/_contracts/suggest.js +54 -0
  37. package/dist/asset-upload.d.ts +27 -1
  38. package/dist/asset-upload.js +219 -4
  39. package/dist/asset-upload.js.map +1 -1
  40. package/dist/bundle.d.ts +23 -14
  41. package/dist/bundle.js +39 -20
  42. package/dist/bundle.js.map +1 -1
  43. package/dist/canonical-zip.d.ts +68 -0
  44. package/dist/canonical-zip.js +307 -0
  45. package/dist/canonical-zip.js.map +1 -0
  46. package/dist/cli.mjs +1927 -326
  47. package/dist/cli.mjs.sha256 +1 -1
  48. package/dist/client.d.ts +273 -70
  49. package/dist/client.js +885 -335
  50. package/dist/client.js.map +1 -1
  51. package/dist/fetch-archive.js +14 -14
  52. package/dist/fetch-archive.js.map +1 -1
  53. package/dist/file.d.ts +33 -6
  54. package/dist/file.js +120 -54
  55. package/dist/file.js.map +1 -1
  56. package/dist/index.d.ts +23 -14
  57. package/dist/index.js +31 -14
  58. package/dist/index.js.map +1 -1
  59. package/dist/node-fs.d.ts +26 -9
  60. package/dist/node-fs.js +13 -38
  61. package/dist/node-fs.js.map +1 -1
  62. package/dist/node-walk.d.ts +69 -0
  63. package/dist/node-walk.js +146 -0
  64. package/dist/node-walk.js.map +1 -0
  65. package/dist/retry.d.ts +9 -13
  66. package/dist/retry.js +18 -17
  67. package/dist/retry.js.map +1 -1
  68. package/dist/skill.d.ts +151 -0
  69. package/dist/skill.js +298 -0
  70. package/dist/skill.js.map +1 -0
  71. package/dist/tool.d.ts +14 -2
  72. package/dist/tool.js +33 -7
  73. package/dist/tool.js.map +1 -1
  74. package/dist/version.d.ts +1 -1
  75. package/dist/version.js +1 -1
  76. package/docs/authentication.md +29 -5
  77. package/docs/billing.md +6 -0
  78. package/docs/concepts/agent-tools.md +11 -0
  79. package/docs/concepts/composition.md +3 -3
  80. package/docs/defaults.md +1 -0
  81. package/docs/errors.md +64 -4
  82. package/docs/events.md +84 -49
  83. package/docs/limits-and-quotas.md +24 -0
  84. package/docs/mcp.md +3 -2
  85. package/docs/networking.md +7 -1
  86. package/docs/outputs.md +36 -7
  87. package/docs/provider-runtime-capabilities.md +1 -1
  88. package/docs/quickstart.md +17 -7
  89. package/docs/run-config.md +3 -3
  90. package/docs/secrets.md +14 -0
  91. package/docs/skills.md +74 -44
  92. package/docs/vision-skills.md +3 -3
  93. package/examples/feature-tour.ts +4 -6
  94. package/examples/spike-settle-latency.ts +125 -0
  95. package/package.json +4 -3
  96. package/dist/_contracts/event-guards.d.ts +0 -67
  97. package/dist/_contracts/event-guards.js +0 -36
  98. package/dist/skill-tool.d.ts +0 -102
  99. package/dist/skill-tool.js +0 -190
  100. package/dist/skill-tool.js.map +0 -1
@@ -0,0 +1,142 @@
1
+ /**
2
+ * The SINGLE wire→exception mapping. `apiErrorFromResponse` reads a non-2xx
3
+ * body's stable `error` code, attaches it (typed) as `apiCode` plus the
4
+ * `requestId`, and dispatches to the right {@link AexApiError} subclass. Both
5
+ * `HttpClient.request` and `HttpClient.download` construct errors ONLY through
6
+ * here, so the wire→exception mapping lives in one place — no inline
7
+ * `new AexApiError(...)` with a hardcoded coarse code.
8
+ */
9
+ import { AexApiError, AexAuthError, AexIdempotencyConflictError, AexNotFoundError, AexRateLimitError } from "./sdk-errors.js";
10
+ import { AEX_API_ERROR_MESSAGES, isAexApiErrorCode } from "./error-codes.js";
11
+ /**
12
+ * EXHAUSTIVE stable-code → subclass-kind map. There is NO `default`: adding a
13
+ * code to {@link AEX_API_ERROR_CODES} without a case here fails to compile
14
+ * (the function would fall through and return `undefined`, which the
15
+ * `ApiErrorKind` return type forbids). This is the whole-class guard that a new
16
+ * server code can never silently collapse to the base error.
17
+ */
18
+ export function apiErrorKindForCode(code) {
19
+ switch (code) {
20
+ case "unauthorized":
21
+ case "forbidden":
22
+ case "insufficient_scope":
23
+ case "token_invalid":
24
+ case "token_revoked":
25
+ case "token_expired":
26
+ case "malformed_token":
27
+ return "auth";
28
+ case "idempotency_conflict":
29
+ return "idempotency";
30
+ case "not_found":
31
+ return "not_found";
32
+ case "rate_limited":
33
+ case "workspace_concurrency_exceeded":
34
+ case "workspace_submit_rate_exceeded":
35
+ return "rate_limit";
36
+ case "session_busy":
37
+ case "run_not_terminal":
38
+ case "unknown_workspace":
39
+ case "workspace_spend_cap_exceeded":
40
+ case "insufficient_balance":
41
+ case "upstream_error":
42
+ case "internal_error":
43
+ return "generic";
44
+ }
45
+ }
46
+ function kindForStatus(status) {
47
+ if (status === 401 || status === 403)
48
+ return "auth";
49
+ if (status === 404)
50
+ return "not_found";
51
+ if (status === 409)
52
+ return "idempotency";
53
+ if (status === 429)
54
+ return "rate_limit";
55
+ return "generic";
56
+ }
57
+ export function apiErrorFromResponse(input) {
58
+ const apiCode = apiCodeFromBody(input.body);
59
+ const requestId = input.requestId ?? requestIdFromBody(input.body);
60
+ const message = input.message ?? fallbackMessage(apiCode, input.body);
61
+ const kind = apiCode !== undefined ? apiErrorKindForCode(apiCode) : kindForStatus(input.status);
62
+ const init = {
63
+ status: input.status,
64
+ message,
65
+ body: input.body,
66
+ apiCode,
67
+ requestId,
68
+ cause: input.cause
69
+ };
70
+ switch (kind) {
71
+ case "auth":
72
+ return new AexAuthError({ ...init, requiredScope: requiredScopeFromBody(input.body) });
73
+ case "idempotency":
74
+ return new AexIdempotencyConflictError(init);
75
+ case "not_found":
76
+ return new AexNotFoundError(init);
77
+ case "rate_limit":
78
+ return new AexRateLimitError({ ...init, retryAfterMs: retryAfterMsFromBody(input.body) });
79
+ case "generic":
80
+ return new AexApiError(input.status, message, input.body, {
81
+ apiCode,
82
+ requestId,
83
+ ...(input.cause !== undefined ? { cause: input.cause } : {})
84
+ });
85
+ }
86
+ }
87
+ function asRecord(body) {
88
+ return body !== null && typeof body === "object" && !Array.isArray(body)
89
+ ? body
90
+ : undefined;
91
+ }
92
+ function apiCodeFromBody(body) {
93
+ const record = asRecord(body);
94
+ if (!record)
95
+ return undefined;
96
+ if (isAexApiErrorCode(record.error))
97
+ return record.error;
98
+ if (isAexApiErrorCode(record.code))
99
+ return record.code;
100
+ return undefined;
101
+ }
102
+ function requestIdFromBody(body) {
103
+ const record = asRecord(body);
104
+ const value = record?.requestId;
105
+ return typeof value === "string" && value.trim().length > 0 ? value : undefined;
106
+ }
107
+ function requiredScopeFromBody(body) {
108
+ const record = asRecord(body);
109
+ if (!record)
110
+ return undefined;
111
+ for (const key of ["requiredScope", "required_scope", "scope"]) {
112
+ const value = record[key];
113
+ if (typeof value === "string" && value.length > 0)
114
+ return value;
115
+ }
116
+ return undefined;
117
+ }
118
+ function retryAfterMsFromBody(body) {
119
+ const record = asRecord(body);
120
+ if (!record)
121
+ return undefined;
122
+ if (typeof record.retryAfterMs === "number" && Number.isFinite(record.retryAfterMs)) {
123
+ return record.retryAfterMs;
124
+ }
125
+ if (typeof record.retryAfter === "number" && Number.isFinite(record.retryAfter)) {
126
+ return record.retryAfter * 1000;
127
+ }
128
+ return undefined;
129
+ }
130
+ function fallbackMessage(apiCode, body) {
131
+ if (apiCode !== undefined)
132
+ return AEX_API_ERROR_MESSAGES[apiCode];
133
+ const record = asRecord(body);
134
+ const message = record?.message;
135
+ if (typeof message === "string" && message.length > 0)
136
+ return message;
137
+ const error = record?.error;
138
+ if (typeof error === "string" && error.length > 0)
139
+ return error;
140
+ return "aex API request failed";
141
+ }
142
+ //# sourceMappingURL=error-factory.js.map
@@ -196,18 +196,25 @@ export declare function isRunError(e: AexEvent): boolean;
196
196
  /** A terminal event of either flavour (finished or error). */
197
197
  export declare function isRunTerminal(e: AexEvent): boolean;
198
198
  /**
199
- * The CUSTOM `data.name`s the MANAGED runtime emits as a run/turn's terminal.
200
- * A managed one-shot run PARKS (session_parked.v1 → `aex.session.idle` / `.error`
201
- * / `.suspended`) rather than writing a `session_finished` → RUN_FINISHED, so
202
- * these — not just the AG-UI RUN_FINISHED/RUN_ERROR — are what actually ends a
203
- * managed run's event stream. Kept in sync with the platform journal projection
204
- * (`journal-project.ts` session_parked.v1 mapping).
199
+ * The CUSTOM `data.name`s the MANAGED runtime emits as a run/turn's SETTLED
200
+ * terminal. A managed one-shot run PARKS (`session_parked.v1`one of these)
201
+ * rather than writing a `session_finished` → RUN_FINISHED, so these — not just
202
+ * the AG-UI RUN_FINISHED/RUN_ERROR — are what actually end a managed run's event
203
+ * stream. Clean-cut (WS1): the bare `aex.session.error` park is retired in favour
204
+ * of the terminal OUTCOME vocabulary — a failed turn is `failed`, a wall-clock
205
+ * kill `timed_out`, a cancel `cancelled`, a clean finish `succeeded`; `idle`/
206
+ * `suspended` remain the resumable parks. Held `awaiting_approval` is NOT here:
207
+ * it ends the TURN stream (see `isSessionTurnTerminalEvent` in the SDK) but the
208
+ * RUN is not settled. Kept byte-in-sync with `@aexhq/shared` `AEX_SESSION_PARKED_NAMES`
209
+ * and the platform journal projection (`journal-project.ts` session_parked.v1).
205
210
  */
206
- export declare const AEX_SESSION_PARKED_NAMES: readonly ["aex.session.idle", "aex.session.error", "aex.session.suspended"];
211
+ export declare const AEX_SESSION_PARKED_NAMES: readonly ["aex.session.idle", "aex.session.suspended", "aex.session.succeeded", "aex.session.failed", "aex.session.timed_out", "aex.session.cancelled"];
207
212
  /**
208
- * True for a managed-runtime session-park terminal (idle/error/suspended). The
209
- * turn's work is done and the record has reached its terminal status; a stream
210
- * consumer should stop here exactly as it would on RUN_FINISHED/RUN_ERROR.
213
+ * True for a managed-runtime session-park terminal (a resumable idle/suspended
214
+ * park OR a terminal succeeded/failed/timed_out/cancelled outcome). The turn's
215
+ * work is done and the record has reached its terminal status; a stream consumer
216
+ * should stop here exactly as it would on RUN_FINISHED/RUN_ERROR. (Held
217
+ * `awaiting_approval` is deliberately excluded — the run is paused, not settled.)
211
218
  */
212
219
  export declare function isSessionParked(e: AexEvent): boolean;
213
220
  export declare function isTextMessage(e: AexEvent): boolean;
@@ -236,6 +243,22 @@ export declare const AEX_RUN_SETTLED_NAME = "aex.run.settled";
236
243
  * the park instead of hanging forever waiting for a barrier that never arrives.
237
244
  */
238
245
  export declare function isRunSettled(e: AexEvent): boolean;
246
+ /**
247
+ * The CUSTOM `data.name` of the HITL write-gate park: the run has reached the
248
+ * `awaiting_approval` state before a gated action and is holding for an
249
+ * `approve()`/`deny()`. Structural (independent of model prose).
250
+ */
251
+ export declare const AEX_SESSION_AWAITING_APPROVAL_NAME = "aex.session.awaiting_approval";
252
+ /** The CUSTOM `data.name` carrying a schema-decoded value (`{ value }`). */
253
+ export declare const AEX_RESULT_DECODED_NAME = "aex.result.decoded";
254
+ /** The CUSTOM `data.name` carrying a typed decode refusal (`{ reason, detail? }`). */
255
+ export declare const AEX_RESULT_REFUSED_NAME = "aex.result.refused";
256
+ /** True for the HITL `awaiting_approval` gate event. */
257
+ export declare function isAwaitingApproval(e: AexEvent): boolean;
258
+ /** True for a schema-decoded terminal result event. */
259
+ export declare function isResultDecoded(e: AexEvent): boolean;
260
+ /** True for a typed decode-refusal terminal result event. */
261
+ export declare function isResultRefused(e: AexEvent): boolean;
239
262
  export declare function isFromSource(e: AexEvent, source: AexEventSource): boolean;
240
263
  /** The channel a record rides, defaulting an absent value to `"event"`. */
241
264
  export declare function channelOf(e: AexEvent): AexEventChannel;
@@ -213,18 +213,32 @@ export function isRunTerminal(e) {
213
213
  return e.type === "RUN_FINISHED" || e.type === "RUN_ERROR";
214
214
  }
215
215
  /**
216
- * The CUSTOM `data.name`s the MANAGED runtime emits as a run/turn's terminal.
217
- * A managed one-shot run PARKS (session_parked.v1 → `aex.session.idle` / `.error`
218
- * / `.suspended`) rather than writing a `session_finished` → RUN_FINISHED, so
219
- * these — not just the AG-UI RUN_FINISHED/RUN_ERROR — are what actually ends a
220
- * managed run's event stream. Kept in sync with the platform journal projection
221
- * (`journal-project.ts` session_parked.v1 mapping).
216
+ * The CUSTOM `data.name`s the MANAGED runtime emits as a run/turn's SETTLED
217
+ * terminal. A managed one-shot run PARKS (`session_parked.v1`one of these)
218
+ * rather than writing a `session_finished` → RUN_FINISHED, so these — not just
219
+ * the AG-UI RUN_FINISHED/RUN_ERROR — are what actually end a managed run's event
220
+ * stream. Clean-cut (WS1): the bare `aex.session.error` park is retired in favour
221
+ * of the terminal OUTCOME vocabulary — a failed turn is `failed`, a wall-clock
222
+ * kill `timed_out`, a cancel `cancelled`, a clean finish `succeeded`; `idle`/
223
+ * `suspended` remain the resumable parks. Held `awaiting_approval` is NOT here:
224
+ * it ends the TURN stream (see `isSessionTurnTerminalEvent` in the SDK) but the
225
+ * RUN is not settled. Kept byte-in-sync with `@aexhq/shared` `AEX_SESSION_PARKED_NAMES`
226
+ * and the platform journal projection (`journal-project.ts` session_parked.v1).
222
227
  */
223
- export const AEX_SESSION_PARKED_NAMES = ["aex.session.idle", "aex.session.error", "aex.session.suspended"];
228
+ export const AEX_SESSION_PARKED_NAMES = [
229
+ "aex.session.idle",
230
+ "aex.session.suspended",
231
+ "aex.session.succeeded",
232
+ "aex.session.failed",
233
+ "aex.session.timed_out",
234
+ "aex.session.cancelled"
235
+ ];
224
236
  /**
225
- * True for a managed-runtime session-park terminal (idle/error/suspended). The
226
- * turn's work is done and the record has reached its terminal status; a stream
227
- * consumer should stop here exactly as it would on RUN_FINISHED/RUN_ERROR.
237
+ * True for a managed-runtime session-park terminal (a resumable idle/suspended
238
+ * park OR a terminal succeeded/failed/timed_out/cancelled outcome). The turn's
239
+ * work is done and the record has reached its terminal status; a stream consumer
240
+ * should stop here exactly as it would on RUN_FINISHED/RUN_ERROR. (Held
241
+ * `awaiting_approval` is deliberately excluded — the run is paused, not settled.)
228
242
  */
229
243
  export function isSessionParked(e) {
230
244
  const name = customName(e);
@@ -268,6 +282,28 @@ export const AEX_RUN_SETTLED_NAME = "aex.run.settled";
268
282
  export function isRunSettled(e) {
269
283
  return customName(e) === AEX_RUN_SETTLED_NAME || isSessionParked(e);
270
284
  }
285
+ /**
286
+ * The CUSTOM `data.name` of the HITL write-gate park: the run has reached the
287
+ * `awaiting_approval` state before a gated action and is holding for an
288
+ * `approve()`/`deny()`. Structural (independent of model prose).
289
+ */
290
+ export const AEX_SESSION_AWAITING_APPROVAL_NAME = "aex.session.awaiting_approval";
291
+ /** The CUSTOM `data.name` carrying a schema-decoded value (`{ value }`). */
292
+ export const AEX_RESULT_DECODED_NAME = "aex.result.decoded";
293
+ /** The CUSTOM `data.name` carrying a typed decode refusal (`{ reason, detail? }`). */
294
+ export const AEX_RESULT_REFUSED_NAME = "aex.result.refused";
295
+ /** True for the HITL `awaiting_approval` gate event. */
296
+ export function isAwaitingApproval(e) {
297
+ return customName(e) === AEX_SESSION_AWAITING_APPROVAL_NAME;
298
+ }
299
+ /** True for a schema-decoded terminal result event. */
300
+ export function isResultDecoded(e) {
301
+ return customName(e) === AEX_RESULT_DECODED_NAME;
302
+ }
303
+ /** True for a typed decode-refusal terminal result event. */
304
+ export function isResultRefused(e) {
305
+ return customName(e) === AEX_RESULT_REFUSED_NAME;
306
+ }
271
307
  export function isFromSource(e, source) {
272
308
  return e.source === source;
273
309
  }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Event methods over the coordinator {@link AexEvent} the SDK yields.
3
+ *
4
+ * The SDK hands users an {@link AexEventView} — the coordinator envelope enriched
5
+ * with one type-predicate METHOD per standardized event type, so a consumer
6
+ * branches on the event with `event.isTextMessage()` / `event.isToolCallStart()`
7
+ * / … instead of a free-function guard or a raw `event.type === "…"` compare.
8
+ *
9
+ * `isTextMessage()` / `isToolCallStart()` / `isToolCallResult()` are TS type
10
+ * predicates: inside the guarded branch `event.data` NARROWS to that event type's
11
+ * payload fields (e.g. `event.data.text` is `string`), exactly what the former
12
+ * free `is*` guards gave. Like those guards the narrowing is DISCRIMINANT-only at
13
+ * runtime (it tests `type`); the narrowed `data` shape is a typing convenience,
14
+ * not deep runtime validation. Parse/verify the payload fields before trusting
15
+ * them when the producer is untrusted.
16
+ *
17
+ * The view is a thin wrapper: {@link asAexEventView} sets the prototype and
18
+ * copies the envelope's own fields, so every {@link AexEvent} field (`type`,
19
+ * `data`, `source`, `sequence`, …) reads exactly as before, the methods live on
20
+ * the prototype (they never serialize), and an `AexEventView` is still a
21
+ * structural {@link AexEvent}.
22
+ */
23
+ import type { AexEvent, AexEventSource } from "./event-envelope.js";
24
+ import type { JsonValue } from "./submission.js";
25
+ /**
26
+ * A `TEXT_MESSAGE_CONTENT` event with its assistant-text payload narrowed.
27
+ * `delta` discriminates a per-token STREAMING delta (`delta: true`, emitted on
28
+ * `outputMode:'stream'`) from the final coalesced block (`delta` absent/false).
29
+ * Both narrow via `isTextMessage()`.
30
+ */
31
+ export interface TextMessageEventView extends AexEventView {
32
+ readonly type: "TEXT_MESSAGE_CONTENT";
33
+ readonly data: Readonly<Record<string, JsonValue>> & {
34
+ readonly text: string;
35
+ readonly messageId?: string;
36
+ /** `true` on a per-token streaming delta; absent/false on the coalesced block. */
37
+ readonly delta?: boolean;
38
+ };
39
+ }
40
+ /** A `TOOL_CALL_START` event with the tool-call id/name/args narrowed. */
41
+ export interface ToolCallStartEventView extends AexEventView {
42
+ readonly type: "TOOL_CALL_START";
43
+ readonly data: Readonly<Record<string, JsonValue>> & {
44
+ readonly id: string;
45
+ readonly name: string;
46
+ readonly arguments?: {
47
+ readonly [key: string]: JsonValue;
48
+ };
49
+ };
50
+ /** The tool-call correlation id (`data.id`), the cross-projection join key. */
51
+ toolCallId(): string;
52
+ }
53
+ /** A `TOOL_CALL_RESULT` event with the correlating id + result narrowed. */
54
+ export interface ToolCallResultEventView extends AexEventView {
55
+ readonly type: "TOOL_CALL_RESULT";
56
+ readonly data: Readonly<Record<string, JsonValue>> & {
57
+ readonly id: string;
58
+ readonly content?: JsonValue;
59
+ readonly isError?: boolean;
60
+ };
61
+ /** The tool-call correlation id (`data.id`), the cross-projection join key. */
62
+ toolCallId(): string;
63
+ }
64
+ /**
65
+ * A coordinator {@link AexEvent} with the standardized-event-type guards carried
66
+ * as METHODS (`event.isTextMessage()`, `event.isToolCallStart()`, …). Extends
67
+ * {@link AexEvent} by declaration merging, so it exposes every envelope field
68
+ * unchanged. Construct one with {@link asAexEventView}.
69
+ */
70
+ export declare class AexEventView {
71
+ /** True for the run-start lifecycle event. */
72
+ isRunStarted(): boolean;
73
+ /** True for the terminal success event. */
74
+ isRunFinished(): boolean;
75
+ /** True for the terminal error event. */
76
+ isRunError(): boolean;
77
+ /** True for a terminal event of either flavour (finished or error). */
78
+ isRunTerminal(): boolean;
79
+ /** True for an assistant text event; narrows `data.text` to `string`. */
80
+ isTextMessage(): this is TextMessageEventView;
81
+ /** True for a tool-call start event; narrows `data` to `{ id, name }`. */
82
+ isToolCallStart(): this is ToolCallStartEventView;
83
+ /** True for a tool-call result event; narrows `data` to `{ id, content }`. */
84
+ isToolCallResult(): this is ToolCallResultEventView;
85
+ /**
86
+ * The tool-call correlation id — `data.id`, the documented, stable join key
87
+ * that a `TOOL_CALL_START` and its `TOOL_CALL_RESULT` share (and that is
88
+ * IDENTICAL across the list and stream projections). Returns `undefined` on a
89
+ * non-tool-call event; on a tool-call view the return narrows to `string`.
90
+ */
91
+ toolCallId(): string | undefined;
92
+ /** True for an aex-native CUSTOM event (an `aex.*` name under `data.name`). */
93
+ isCustom(): boolean;
94
+ /** True for the HITL `awaiting_approval` write-gate event. */
95
+ isAwaitingApproval(): boolean;
96
+ /** True for a schema-decoded terminal result event (`aex.result.decoded`). */
97
+ isResultDecoded(): boolean;
98
+ /** True for a typed decode-refusal terminal result event (`aex.result.refused`). */
99
+ isResultRefused(): boolean;
100
+ /** True when the record is a log line (the `log` channel / `LOG` type). */
101
+ isLog(): boolean;
102
+ /** True when the record is a typed AG-UI event (the `event` channel). */
103
+ isEventChannel(): boolean;
104
+ /**
105
+ * True for the settle-consistency barrier event AND for a managed-runtime
106
+ * session-park terminal (idle/error/suspended) — the one check that reliably
107
+ * means "this stream is done and the record is authoritative".
108
+ */
109
+ isRunSettled(): boolean;
110
+ /** True when the record originates from the given coarse source. */
111
+ isFromSource(source: AexEventSource): boolean;
112
+ }
113
+ export interface AexEventView extends AexEvent {
114
+ }
115
+ /**
116
+ * Wrap a coordinator {@link AexEvent} as an {@link AexEventView}: the methods
117
+ * live on the prototype and the envelope's own fields are copied across, so the
118
+ * returned value reads identically to the raw envelope and serializes to the
119
+ * same bytes (prototype methods are not own-enumerable).
120
+ */
121
+ export declare function asAexEventView(event: AexEvent): AexEventView;
122
+ /** Wrap each event of a list as an {@link AexEventView}. */
123
+ export declare function asAexEventViews(events: readonly AexEvent[]): AexEventView[];
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Event methods over the coordinator {@link AexEvent} the SDK yields.
3
+ *
4
+ * The SDK hands users an {@link AexEventView} — the coordinator envelope enriched
5
+ * with one type-predicate METHOD per standardized event type, so a consumer
6
+ * branches on the event with `event.isTextMessage()` / `event.isToolCallStart()`
7
+ * / … instead of a free-function guard or a raw `event.type === "…"` compare.
8
+ *
9
+ * `isTextMessage()` / `isToolCallStart()` / `isToolCallResult()` are TS type
10
+ * predicates: inside the guarded branch `event.data` NARROWS to that event type's
11
+ * payload fields (e.g. `event.data.text` is `string`), exactly what the former
12
+ * free `is*` guards gave. Like those guards the narrowing is DISCRIMINANT-only at
13
+ * runtime (it tests `type`); the narrowed `data` shape is a typing convenience,
14
+ * not deep runtime validation. Parse/verify the payload fields before trusting
15
+ * them when the producer is untrusted.
16
+ *
17
+ * The view is a thin wrapper: {@link asAexEventView} sets the prototype and
18
+ * copies the envelope's own fields, so every {@link AexEvent} field (`type`,
19
+ * `data`, `source`, `sequence`, …) reads exactly as before, the methods live on
20
+ * the prototype (they never serialize), and an `AexEventView` is still a
21
+ * structural {@link AexEvent}.
22
+ */
23
+ import { channelOf, isRunSettled, isAwaitingApproval, isResultDecoded, isResultRefused } from "./event-envelope.js";
24
+ /**
25
+ * A coordinator {@link AexEvent} with the standardized-event-type guards carried
26
+ * as METHODS (`event.isTextMessage()`, `event.isToolCallStart()`, …). Extends
27
+ * {@link AexEvent} by declaration merging, so it exposes every envelope field
28
+ * unchanged. Construct one with {@link asAexEventView}.
29
+ */
30
+ export class AexEventView {
31
+ /** True for the run-start lifecycle event. */
32
+ isRunStarted() {
33
+ return this.type === "RUN_STARTED";
34
+ }
35
+ /** True for the terminal success event. */
36
+ isRunFinished() {
37
+ return this.type === "RUN_FINISHED";
38
+ }
39
+ /** True for the terminal error event. */
40
+ isRunError() {
41
+ return this.type === "RUN_ERROR";
42
+ }
43
+ /** True for a terminal event of either flavour (finished or error). */
44
+ isRunTerminal() {
45
+ return this.type === "RUN_FINISHED" || this.type === "RUN_ERROR";
46
+ }
47
+ /** True for an assistant text event; narrows `data.text` to `string`. */
48
+ isTextMessage() {
49
+ return this.type === "TEXT_MESSAGE_CONTENT";
50
+ }
51
+ /** True for a tool-call start event; narrows `data` to `{ id, name }`. */
52
+ isToolCallStart() {
53
+ return this.type === "TOOL_CALL_START";
54
+ }
55
+ /** True for a tool-call result event; narrows `data` to `{ id, content }`. */
56
+ isToolCallResult() {
57
+ return this.type === "TOOL_CALL_RESULT";
58
+ }
59
+ /**
60
+ * The tool-call correlation id — `data.id`, the documented, stable join key
61
+ * that a `TOOL_CALL_START` and its `TOOL_CALL_RESULT` share (and that is
62
+ * IDENTICAL across the list and stream projections). Returns `undefined` on a
63
+ * non-tool-call event; on a tool-call view the return narrows to `string`.
64
+ */
65
+ toolCallId() {
66
+ const id = this.data.id;
67
+ return typeof id === "string" ? id : undefined;
68
+ }
69
+ /** True for an aex-native CUSTOM event (an `aex.*` name under `data.name`). */
70
+ isCustom() {
71
+ return this.type === "CUSTOM";
72
+ }
73
+ /** True for the HITL `awaiting_approval` write-gate event. */
74
+ isAwaitingApproval() {
75
+ return isAwaitingApproval(this);
76
+ }
77
+ /** True for a schema-decoded terminal result event (`aex.result.decoded`). */
78
+ isResultDecoded() {
79
+ return isResultDecoded(this);
80
+ }
81
+ /** True for a typed decode-refusal terminal result event (`aex.result.refused`). */
82
+ isResultRefused() {
83
+ return isResultRefused(this);
84
+ }
85
+ /** True when the record is a log line (the `log` channel / `LOG` type). */
86
+ isLog() {
87
+ return channelOf(this) === "log";
88
+ }
89
+ /** True when the record is a typed AG-UI event (the `event` channel). */
90
+ isEventChannel() {
91
+ return channelOf(this) === "event";
92
+ }
93
+ /**
94
+ * True for the settle-consistency barrier event AND for a managed-runtime
95
+ * session-park terminal (idle/error/suspended) — the one check that reliably
96
+ * means "this stream is done and the record is authoritative".
97
+ */
98
+ isRunSettled() {
99
+ return isRunSettled(this);
100
+ }
101
+ /** True when the record originates from the given coarse source. */
102
+ isFromSource(source) {
103
+ return this.source === source;
104
+ }
105
+ }
106
+ /**
107
+ * Wrap a coordinator {@link AexEvent} as an {@link AexEventView}: the methods
108
+ * live on the prototype and the envelope's own fields are copied across, so the
109
+ * returned value reads identically to the raw envelope and serializes to the
110
+ * same bytes (prototype methods are not own-enumerable).
111
+ */
112
+ export function asAexEventView(event) {
113
+ const view = Object.create(AexEventView.prototype);
114
+ return Object.assign(view, event);
115
+ }
116
+ /** Wrap each event of a list as an {@link AexEventView}. */
117
+ export function asAexEventViews(events) {
118
+ return events.map(asAexEventView);
119
+ }
120
+ //# sourceMappingURL=event-view.js.map
@@ -1,4 +1,5 @@
1
- import { AexApiError, AexError, AexNetworkError, redactUrl } from "./sdk-errors.js";
1
+ import { AexError, AexNetworkError, redactUrl } from "./sdk-errors.js";
2
+ import { apiErrorFromResponse } from "./error-factory.js";
2
3
  import { AEX_DEFAULT_BASE_URL } from "./stable.js";
3
4
  /**
4
5
  * Thin transport used by every BFF-bound operation. The SDK class and
@@ -63,7 +64,11 @@ export class HttpClient {
63
64
  const body = await readJson(response);
64
65
  if (!response.ok) {
65
66
  const errorBody = withResponseRequestId(body, response.headers);
66
- throw new AexApiError(response.status, extractErrorMessage(errorBody), errorBody);
67
+ throw apiErrorFromResponse({
68
+ status: response.status,
69
+ body: errorBody,
70
+ message: extractErrorMessage(errorBody)
71
+ });
67
72
  }
68
73
  return body;
69
74
  }
@@ -88,7 +93,11 @@ export class HttpClient {
88
93
  if (!response.ok) {
89
94
  const body = await readJson(response);
90
95
  const errorBody = withResponseRequestId(body, response.headers);
91
- throw new AexApiError(response.status, extractErrorMessage(errorBody), errorBody);
96
+ throw apiErrorFromResponse({
97
+ status: response.status,
98
+ body: errorBody,
99
+ message: extractErrorMessage(errorBody)
100
+ });
92
101
  }
93
102
  return { response };
94
103
  }
@@ -1,11 +1,12 @@
1
1
  export * from "./provider-support.js";
2
2
  export * from "./models.js";
3
3
  export * from "./status.js";
4
- export { AEX_RESERVED_ENV_PREFIX, BUILTIN_TOOL_NAMES, BuiltinTools, DEFAULT_BUILTIN_TOOLS, DEFAULT_OUTPUT_MODE, DEFAULT_RUN_PROVIDER, ENV_VARS_MAX_ENTRIES, ENV_VARS_MAX_TOTAL_BYTES, ENV_VARS_MAX_VALUE_BYTES, OUTPUT_MODES, PLATFORM_PACKAGE_ECOSYSTEMS, Providers, RUN_PROVIDERS, SECRETS_KEY, SECRET_ENV_NAME_PATTERN, SECRET_HANDLE_PATTERN, crossValidateSecretEnvAndValues, packageInstallString, parseInlineSecrets, parseRunLimits, parseRunProvider, parseRunSubmissionRequest, parseRunWebhook, parseSubmission, resolveBuiltinToolNames } from "./submission.js";
5
- export type { BuiltinToolName, JsonPrimitive, JsonValue, OutputMode, ParseRunSubmissionOptions, PlatformEnvironment, PlatformEnvironmentInput, PlatformInlineSecrets, PlatformInjectionConfig, PlatformMcpServerSecret, PlatformNetworking, PlatformOutputCaptureConfig, PlatformPackage, PlatformPackageEcosystem, PlatformPackageInput, PlatformRunSubmissionInput, PlatformRunSubmissionRequest, PlatformSecretEnvEntry, PlatformSubmission, RunLimits, RunMachine, RunProvider, RunWebhookSpec } from "./submission.js";
4
+ export { AEX_RESERVED_ENV_PREFIX, BUILTIN_TOOL_NAMES, BuiltinTools, DEFAULT_BUILTIN_TOOLS, DEFAULT_OUTPUT_MODE, DEFAULT_RUN_PROVIDER, ENV_VARS_MAX_ENTRIES, ENV_VARS_MAX_TOTAL_BYTES, ENV_VARS_MAX_VALUE_BYTES, OUTPUT_MODES, PLATFORM_PACKAGE_ECOSYSTEMS, Providers, RESPONSE_FORMAT_KINDS, RUN_PROVIDERS, SECRETS_KEY, SECRET_ENV_NAME_PATTERN, SECRET_HANDLE_PATTERN, SKILLS_MAX, SKILLS_TOOL_DEFINITION, SKILLS_TOOL_NAME, STREAMABLE_SHAPES, assertStreamableOutputMode, crossValidateSecretEnvAndValues, isStreamableProvider, packageInstallString, parseApprovalGate, parseInlineSecrets, parseResponseFormat, parseRunLimits, parseRunProvider, parseRunSubmissionRequest, parseRunWebhook, parseSkills, parseSubmission, resolveBuiltinToolNames } from "./submission.js";
5
+ export type { ApprovalGate, BuiltinToolName, JsonPrimitive, JsonValue, OutputMode, ParseRunSubmissionOptions, PlatformEnvironment, PlatformEnvironmentInput, PlatformInlineSecrets, PlatformInjectionConfig, PlatformMcpServerSecret, PlatformNetworking, PlatformOutputCaptureConfig, PlatformPackage, PlatformPackageEcosystem, PlatformPackageInput, PlatformRunSubmissionInput, PlatformRunSubmissionRequest, PlatformSecretEnvEntry, PlatformSubmission, ResponseFormat, ResponseFormatKind, RunLimits, RunMachine, RunProvider, RunWebhookSpec, StreamableShape } from "./submission.js";
6
6
  export * from "./runtime-sizes.js";
7
7
  export * from "./runner-event.js";
8
8
  export * from "./event-envelope.js";
9
+ export * from "./event-view.js";
9
10
  export * from "./connection-ticket.js";
10
11
  export * from "./event-stream-client.js";
11
12
  export * from "./run-unit.js";
@@ -21,11 +22,14 @@ export * from "./stable.js";
21
22
  export * from "./sdk-secrets.js";
22
23
  export * from "./sdk-errors.js";
23
24
  export * from "./run-config.js";
25
+ export * from "./bundle-manifest.js";
24
26
  export * from "./runtime-types.js";
25
27
  export * from "./webhook-verify.js";
26
28
  export * from "./http.js";
27
29
  export * from "./run-artifacts.js";
28
30
  export * as operations from "./operations.js";
29
31
  export * from "./sse.js";
30
- export { isRunFinished, isTextMessage, isToolCallResult, isToolCallStart } from "./event-guards.js";
31
- export type { RunFinishedRunEvent, TextMessageRunEvent, ToolCallResultRunEvent, ToolCallStartRunEvent } from "./event-guards.js";
32
+ export * from "./error-codes.js";
33
+ export * from "./error-factory.js";
34
+ export * from "./suggest.js";
35
+ export * from "./api-key.js";
@@ -1,10 +1,11 @@
1
1
  export * from "./provider-support.js";
2
2
  export * from "./models.js";
3
3
  export * from "./status.js";
4
- export { AEX_RESERVED_ENV_PREFIX, BUILTIN_TOOL_NAMES, BuiltinTools, DEFAULT_BUILTIN_TOOLS, DEFAULT_OUTPUT_MODE, DEFAULT_RUN_PROVIDER, ENV_VARS_MAX_ENTRIES, ENV_VARS_MAX_TOTAL_BYTES, ENV_VARS_MAX_VALUE_BYTES, OUTPUT_MODES, PLATFORM_PACKAGE_ECOSYSTEMS, Providers, RUN_PROVIDERS, SECRETS_KEY, SECRET_ENV_NAME_PATTERN, SECRET_HANDLE_PATTERN, crossValidateSecretEnvAndValues, packageInstallString, parseInlineSecrets, parseRunLimits, parseRunProvider, parseRunSubmissionRequest, parseRunWebhook, parseSubmission, resolveBuiltinToolNames } from "./submission.js";
4
+ export { AEX_RESERVED_ENV_PREFIX, BUILTIN_TOOL_NAMES, BuiltinTools, DEFAULT_BUILTIN_TOOLS, DEFAULT_OUTPUT_MODE, DEFAULT_RUN_PROVIDER, ENV_VARS_MAX_ENTRIES, ENV_VARS_MAX_TOTAL_BYTES, ENV_VARS_MAX_VALUE_BYTES, OUTPUT_MODES, PLATFORM_PACKAGE_ECOSYSTEMS, Providers, RESPONSE_FORMAT_KINDS, RUN_PROVIDERS, SECRETS_KEY, SECRET_ENV_NAME_PATTERN, SECRET_HANDLE_PATTERN, SKILLS_MAX, SKILLS_TOOL_DEFINITION, SKILLS_TOOL_NAME, STREAMABLE_SHAPES, assertStreamableOutputMode, crossValidateSecretEnvAndValues, isStreamableProvider, packageInstallString, parseApprovalGate, parseInlineSecrets, parseResponseFormat, parseRunLimits, parseRunProvider, parseRunSubmissionRequest, parseRunWebhook, parseSkills, parseSubmission, resolveBuiltinToolNames } from "./submission.js";
5
5
  export * from "./runtime-sizes.js";
6
6
  export * from "./runner-event.js";
7
7
  export * from "./event-envelope.js";
8
+ export * from "./event-view.js";
8
9
  export * from "./connection-ticket.js";
9
10
  export * from "./event-stream-client.js";
10
11
  export * from "./run-unit.js";
@@ -19,16 +20,19 @@ export * from "./stable.js";
19
20
  export * from "./sdk-secrets.js";
20
21
  export * from "./sdk-errors.js";
21
22
  export * from "./run-config.js";
23
+ export * from "./bundle-manifest.js";
22
24
  export * from "./runtime-types.js";
23
25
  export * from "./webhook-verify.js";
24
26
  export * from "./http.js";
25
27
  export * from "./run-artifacts.js";
26
28
  export * as operations from "./operations.js";
27
29
  export * from "./sse.js";
28
- // Explicit re-export (shadows the same-named `AexEvent` guards from
29
- // `event-envelope.js`): the public `is*` guards narrow the loose `RunEvent`
30
- // snapshot shape `listEvents` returns. An `AexEvent` is assignable to `RunEvent`,
31
- // so envelope consumers keep working; the envelope-typed guards stay reachable
32
- // via the direct `event-envelope.js` module.
33
- export { isRunFinished, isTextMessage, isToolCallResult, isToolCallStart } from "./event-guards.js";
30
+ // The single canonical event surface: the `is*` guards live on `AexEvent`
31
+ // (`event-envelope.js`) and as METHODS on `AexEventView` (`event-view.js`).
32
+ // The loose `RunEvent` type and its free-function guard mirror (`event-guards.js`)
33
+ // are RETIRED there is exactly one event shape.
34
+ export * from "./error-codes.js";
35
+ export * from "./error-factory.js";
36
+ export * from "./suggest.js";
37
+ export * from "./api-key.js";
34
38
  //# sourceMappingURL=index.js.map
@@ -147,6 +147,21 @@ export declare function providerForModel(model: string): RunProvider | undefined
147
147
  * `"openai/gpt-4o-mini"`). Throws when the provider does not serve the model.
148
148
  */
149
149
  export declare function resolveProviderModelId(model: string, provider: RunProvider): string;
150
+ /**
151
+ * The single model→provider resolver shared by the SDK and the CLI, wrapping
152
+ * {@link providersForModel} with the forward-compat unknown-model allowance:
153
+ *
154
+ * - `provider` given: it is honored. If `model` is a KNOWN id, the provider
155
+ * must serve it (else throw). If `model` is UNKNOWN, it is allowed through
156
+ * so a slightly-old client can still run a newly-launched model (the server
157
+ * arbitrates).
158
+ * - `provider` omitted: a known model resolves to its DEFAULT provider (first
159
+ * declared). An UNKNOWN model with no provider throws a `did you mean?`
160
+ * hint — you must name a provider to run a model this client doesn't know.
161
+ *
162
+ * Returns the resolved {@link RunProvider}.
163
+ */
164
+ export declare function resolveModelProvider(model: string, provider?: RunProvider): RunProvider;
150
165
  export declare function isRunModel(input: unknown): input is RunModel;
151
166
  export declare function parseRunModel(input: unknown, field?: string): RunModel;
152
167
  export declare function assertRunModelMatchesProvider(provider: RunProvider, model: RunModel, field?: string): void;