@aexhq/sdk 0.40.16 → 0.41.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 (130) hide show
  1. package/README.md +25 -25
  2. package/dist/_contracts/api-key.d.ts +6 -4
  3. package/dist/_contracts/api-key.js +20 -7
  4. package/dist/_contracts/connection-ticket.d.ts +5 -5
  5. package/dist/_contracts/connection-ticket.js +7 -7
  6. package/dist/_contracts/error-codes.d.ts +1 -1
  7. package/dist/_contracts/error-codes.js +4 -4
  8. package/dist/_contracts/error-factory.js +1 -1
  9. package/dist/_contracts/event-envelope.d.ts +41 -41
  10. package/dist/_contracts/event-envelope.js +49 -49
  11. package/dist/_contracts/event-stream-client.d.ts +9 -9
  12. package/dist/_contracts/event-stream-client.js +5 -5
  13. package/dist/_contracts/event-view.d.ts +6 -6
  14. package/dist/_contracts/event-view.js +12 -12
  15. package/dist/_contracts/http.js +1 -1
  16. package/dist/_contracts/index.d.ts +10 -10
  17. package/dist/_contracts/index.js +9 -9
  18. package/dist/_contracts/models.d.ts +17 -17
  19. package/dist/_contracts/models.js +14 -14
  20. package/dist/_contracts/operations.d.ts +79 -82
  21. package/dist/_contracts/operations.js +233 -243
  22. package/dist/_contracts/provider-support.d.ts +2 -2
  23. package/dist/_contracts/runner-event.d.ts +8 -8
  24. package/dist/_contracts/runner-event.js +9 -9
  25. package/dist/_contracts/runtime-manifest.d.ts +12 -12
  26. package/dist/_contracts/runtime-manifest.js +1 -1
  27. package/dist/_contracts/runtime-sizes.d.ts +12 -12
  28. package/dist/_contracts/runtime-sizes.js +18 -18
  29. package/dist/_contracts/runtime-types.d.ts +117 -117
  30. package/dist/_contracts/runtime-types.js +2 -2
  31. package/dist/_contracts/sdk-errors.d.ts +3 -3
  32. package/dist/_contracts/sdk-errors.js +4 -4
  33. package/dist/_contracts/sdk-secrets.js +10 -10
  34. package/dist/_contracts/session-artifacts.d.ts +151 -0
  35. package/dist/_contracts/session-artifacts.js +234 -0
  36. package/dist/_contracts/{run-config.d.ts → session-config.d.ts} +29 -29
  37. package/dist/_contracts/{run-config.js → session-config.js} +37 -37
  38. package/dist/_contracts/session-cost.d.ts +140 -0
  39. package/dist/_contracts/{run-cost.js → session-cost.js} +94 -94
  40. package/dist/_contracts/{run-custody.d.ts → session-custody.d.ts} +16 -16
  41. package/dist/_contracts/{run-custody.js → session-custody.js} +42 -42
  42. package/dist/_contracts/session-record.d.ts +112 -0
  43. package/dist/_contracts/{run-record.js → session-record.js} +23 -23
  44. package/dist/_contracts/session-retention.d.ts +209 -0
  45. package/dist/_contracts/{run-retention.js → session-retention.js} +116 -116
  46. package/dist/_contracts/{run-unit.d.ts → session-unit.d.ts} +38 -38
  47. package/dist/_contracts/{run-unit.js → session-unit.js} +33 -33
  48. package/dist/_contracts/side-effect-audit.d.ts +14 -14
  49. package/dist/_contracts/side-effect-audit.js +38 -38
  50. package/dist/_contracts/sse.d.ts +1 -1
  51. package/dist/_contracts/sse.js +0 -0
  52. package/dist/_contracts/stable.d.ts +1 -1
  53. package/dist/_contracts/stable.js +1 -1
  54. package/dist/_contracts/status.d.ts +18 -18
  55. package/dist/_contracts/status.js +19 -19
  56. package/dist/_contracts/submission.d.ts +101 -99
  57. package/dist/_contracts/submission.js +96 -96
  58. package/dist/_contracts/{run-trace.d.ts → turn-trace.d.ts} +1 -1
  59. package/dist/_contracts/webhook-verify.d.ts +1 -1
  60. package/dist/_contracts/webhook-verify.js +1 -1
  61. package/dist/agents-md.d.ts +4 -4
  62. package/dist/agents-md.js +5 -5
  63. package/dist/agents-md.js.map +1 -1
  64. package/dist/bundle.d.ts +1 -1
  65. package/dist/bundle.js +1 -1
  66. package/dist/bundle.js.map +1 -1
  67. package/dist/cli.mjs +578 -621
  68. package/dist/cli.mjs.sha256 +1 -1
  69. package/dist/client.d.ts +141 -155
  70. package/dist/client.js +236 -245
  71. package/dist/client.js.map +1 -1
  72. package/dist/fetch-archive.js +3 -3
  73. package/dist/file.d.ts +7 -7
  74. package/dist/file.js +8 -8
  75. package/dist/file.js.map +1 -1
  76. package/dist/index.d.ts +10 -10
  77. package/dist/index.js +8 -8
  78. package/dist/index.js.map +1 -1
  79. package/dist/mcp-server.d.ts +1 -1
  80. package/dist/retry.d.ts +1 -1
  81. package/dist/secret.d.ts +6 -6
  82. package/dist/secret.js +6 -6
  83. package/dist/secret.js.map +1 -1
  84. package/dist/skill.d.ts +2 -2
  85. package/dist/skill.js +3 -3
  86. package/dist/skill.js.map +1 -1
  87. package/dist/tool.js +2 -2
  88. package/dist/tool.js.map +1 -1
  89. package/dist/version.d.ts +1 -1
  90. package/dist/version.js +1 -1
  91. package/dist/version.js.map +1 -1
  92. package/docs/authentication.md +11 -11
  93. package/docs/billing.md +3 -3
  94. package/docs/cleanup.md +5 -5
  95. package/docs/concepts/agent-tools.md +5 -5
  96. package/docs/concepts/composition.md +3 -3
  97. package/docs/concepts/providers-and-runtimes.md +3 -3
  98. package/docs/concepts/{runs.md → sessions.md} +8 -8
  99. package/docs/concepts/subagents.md +16 -16
  100. package/docs/credentials.md +7 -7
  101. package/docs/defaults.md +14 -14
  102. package/docs/errors.md +10 -10
  103. package/docs/events.md +26 -26
  104. package/docs/files.md +267 -0
  105. package/docs/limits-and-quotas.md +35 -35
  106. package/docs/limits.md +6 -6
  107. package/docs/mcp.md +3 -3
  108. package/docs/networking.md +24 -24
  109. package/docs/provider-runtime-capabilities.md +1 -1
  110. package/docs/public-surface.json +6 -6
  111. package/docs/quickstart.md +13 -13
  112. package/docs/release.md +5 -5
  113. package/docs/retries.md +3 -3
  114. package/docs/secrets.md +16 -16
  115. package/docs/session-config.md +58 -0
  116. package/docs/{run-record.md → session-record.md} +16 -16
  117. package/docs/skills.md +9 -9
  118. package/docs/vision-skills.md +7 -7
  119. package/docs/webhooks.md +11 -11
  120. package/examples/feature-tour.ts +17 -17
  121. package/examples/spike-settle-latency.ts +11 -11
  122. package/package.json +1 -1
  123. package/dist/_contracts/run-artifacts.d.ts +0 -49
  124. package/dist/_contracts/run-artifacts.js +0 -102
  125. package/dist/_contracts/run-cost.d.ts +0 -140
  126. package/dist/_contracts/run-record.d.ts +0 -116
  127. package/dist/_contracts/run-retention.d.ts +0 -209
  128. package/docs/outputs.md +0 -267
  129. package/docs/run-config.md +0 -58
  130. /package/dist/_contracts/{run-trace.js → turn-trace.js} +0 -0
package/README.md CHANGED
@@ -8,10 +8,10 @@ aex is an agent execution platform for launching autonomous agents from a simple
8
8
 
9
9
  The package ships:
10
10
 
11
- - `Aex` for sessions, one-shot runs, inspect, download, cancel, and delete.
11
+ - `Aex` for sessions, one-shot sessions, inspect, download, cancel, and delete.
12
12
  - `sessions` / `openSession()` for durable, resumable agent sessions.
13
13
  - Typed run primitives: `Models`, `Providers`, `Sizes`, `Skill`, `Tool` / `Tools`, `AgentsMd`, `File`, `McpServer`, and `Secret`.
14
- - A bundled `aex` CLI with the same run, status, events, outputs, download, cancel, delete, and whoami operations.
14
+ - A bundled `aex` CLI with the same run, status, events, files, download, cancel, delete, and whoami operations.
15
15
 
16
16
  ## Install
17
17
 
@@ -55,24 +55,24 @@ const resumed = await aex.openSession(session.id);
55
55
  await resumed.send("Continue with the follow-up validation.").done();
56
56
  ```
57
57
 
58
- Need a one-shot convenience? `run()` opens a session, sends `message` as one
59
- turn, and returns the collected result. The returned `runId` is the session id,
60
- so it can be resumed later with `openSession(runId)`.
58
+ Need a one-shot convenience? `start()` opens a session, sends `message` as one
59
+ turn, and returns the collected result. The returned `sessionId` is the session id,
60
+ so it can be resumed later with `openSession(sessionId)`.
61
61
 
62
62
  ```ts
63
- const result = await aex.run({
63
+ const result = await aex.start({
64
64
  model: Models.CLAUDE_HAIKU_4_5,
65
65
  apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! },
66
- message: "Write the report and save outputs."
66
+ message: "Write the report and save files."
67
67
  });
68
68
 
69
- console.log(result.runId, result.status, result.text);
69
+ console.log(result.sessionId, result.status, result.text);
70
70
  ```
71
71
 
72
72
  For multiple providers, include each BYOK key in `apiKeys`:
73
73
 
74
74
  ```ts
75
- await aex.run({
75
+ await aex.start({
76
76
  model: Models.CLAUDE_HAIKU_4_5,
77
77
  apiKeys: {
78
78
  anthropic: process.env.ANTHROPIC_API_KEY!,
@@ -85,11 +85,11 @@ await aex.run({
85
85
  The same request can run from the bundled CLI (`npx aex` on a local install):
86
86
 
87
87
  ```bash
88
- npx aex run \
88
+ npx aex start \
89
89
  --api-key "$AEX_API_KEY" \
90
90
  --anthropic-api-key "$ANTHROPIC_API_KEY" \
91
91
  --model claude-haiku-4-5 \
92
- --prompt "Write the report and save outputs." \
92
+ --prompt "Write the report and save files." \
93
93
  --follow
94
94
  ```
95
95
 
@@ -115,44 +115,44 @@ by default, machine JSON under `--json`). Per-verb `--help` is also key-free:
115
115
  npx aex models list # canonical models + their default provider
116
116
  npx aex providers list # providers + the models each serves
117
117
  npx aex tools list # complete builtin tool set
118
- npx aex runtime-sizes list # managed runtime presets (cpus / memory / default)
119
- npx aex run --help # flags for one verb (no API key required)
118
+ npx aex starttime-sizes list # managed runtime presets (cpus / memory / default)
119
+ npx aex start --help # flags for one verb (no API key required)
120
120
  ```
121
121
 
122
- Errors are typed and actionable. Every `openSession()` / `run()` config-validation
123
- failure throws a `RunConfigValidationError` (`err.code === "RUN_CONFIG_INVALID"`)
122
+ Errors are typed and actionable. Every `openSession()` / `start()` config-validation
123
+ failure throws a `SessionConfigValidationError` (`err.code === "SESSION_CONFIG_INVALID"`)
124
124
  you can `catch` by code; CLI failures print a JSON envelope carrying the HTTP
125
- `status`, a one-line `remedy`, and the `runId` where known, and a wrong `--model`,
125
+ `status`, a one-line `remedy`, and the `sessionId` where known, and a wrong `--model`,
126
126
  `--provider`, or `--runtime-size` gets a "did you mean?" suggestion.
127
127
 
128
128
  ## Continue with sessions
129
129
 
130
- Use sessions for conversational flows. `run()` is the one-shot convenience; a
130
+ Use sessions for conversational flows. `start()` is the one-shot convenience; a
131
131
  `SessionHandle` is the lower-level surface when you want multiple turns,
132
- streaming, messages, events, outputs, or downloads.
132
+ streaming, messages, events, files, or downloads.
133
133
 
134
134
  ```ts
135
- const session = await aex.openSession(result.runId);
135
+ const session = await aex.openSession(result.sessionId);
136
136
  const next = await session.send("Turn this into a checklist.").done();
137
137
  console.log(next.text);
138
138
 
139
139
  const messages = await session.messages().list();
140
- const outputs = await aex.sessions.outputs(session.id).list();
140
+ const files = await aex.sessions.files(session.id).list();
141
141
  ```
142
142
 
143
143
  ## Feature Areas
144
144
 
145
- - **Agent runtime:** managed autonomous runs with filesystem read/edit, grep/glob/head/tail, open web fetch/search, background commands, code execution, git, and subagents.
146
- - **Durable infrastructure:** run records, status, wait/cancel/delete, idempotency, typed events, output capture, downloads, timeouts, and runtime sizes.
145
+ - **Agent runtime:** managed autonomous sessions with filesystem read/edit, grep/glob/head/tail, open web fetch/search, background commands, code execution, git, and subagents.
146
+ - **Durable infrastructure:** session records, status, wait/cancel/delete, idempotency, typed events, file capture, downloads, timeouts, and runtime sizes.
147
147
  - **Agent composition:** skills, files, AGENTS.md, remote MCP servers, environment variables, packages, and networking controls.
148
- - **Subagents:** typed parent/child lineage for async child runs, output handoff, and bounded agent delegation.
148
+ - **Subagents:** typed parent/child lineage for async child sessions, file handoff, and bounded agent delegation.
149
149
  - **Models and providers:** Anthropic, DeepSeek, OpenAI, Gemini, Mistral, OpenRouter, Doubao, and Doubao China behind one submission shape.
150
- - **Typed control surface:** strongly typed SDK inputs, CLI parity, BYOK provider keys, workspace secrets, redaction, and output modes.
150
+ - **Typed control surface:** strongly typed SDK inputs, CLI parity, BYOK provider keys, workspace secrets, redaction, assistant text modes, and file capture policy.
151
151
 
152
152
  ## Docs
153
153
 
154
154
  - [Quickstart](docs/quickstart.md)
155
- - [Run configuration](docs/run-config.md)
155
+ - [SessionRecord configuration](docs/session-config.md)
156
156
  - [Composition](docs/concepts/composition.md)
157
157
  - [Secrets](docs/secrets.md)
158
158
  - [Limits](docs/limits.md)
@@ -24,9 +24,10 @@ export interface ParsedApiKey {
24
24
  readonly workspaceId: string;
25
25
  }
26
26
  /**
27
- * Canonical form of a workspaceId for EMBEDDING in a key: dashes stripped so the
28
- * whole key is a single double-click-selectable word (`_` is a word char, `-`
29
- * is not). Kept byte-for-byte in sync with the platform codec.
27
+ * Canonical form of a workspaceId for EMBEDDING in a key. Public workspace ids
28
+ * are `wsp_<uuidhex>`, while storage rows still use dashed UUIDs. Keys embed only
29
+ * the hex field so the token remains underscore-delimited and double-click
30
+ * selectable.
30
31
  */
31
32
  export declare function normalizeWorkspaceId(workspaceId: string): string;
32
33
  /**
@@ -39,7 +40,8 @@ export declare function parseApiKey(token: string): ParsedApiKey | null;
39
40
  * Assemble a valid API key from its parts (the inverse of {@link parseApiKey}).
40
41
  * Unlike the server's `mintApiKeyValue` this takes an EXPLICIT `secret` so it is
41
42
  * deterministic — used by codec round-trip / cross-repo parity tests. The
42
- * embedded workspace id is dash-normalized; `workspaceId` must not contain `_`.
43
+ * embedded workspace id is normalized; public `wsp_...` ids are accepted and
44
+ * embedded as their hex field.
43
45
  */
44
46
  export declare function formatApiKey(input: {
45
47
  readonly plane: ApiKeyPlane;
@@ -21,13 +21,24 @@ export const API_KEY_REGION_TO_CODE = {
21
21
  };
22
22
  const CODE_TO_REGION = Object.fromEntries(Object.entries(API_KEY_REGION_TO_CODE).map(([region, code]) => [code, region]));
23
23
  const API_KEY_PLANE_SET = new Set(API_KEY_PLANES);
24
+ const PUBLIC_WORKSPACE_ID_RE = /^wsp_([0-9a-f]{32})$/i;
25
+ const DASHLESS_UUID_RE = /^[0-9a-f]{32}$/i;
26
+ const UUID_RE = /^([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})$/i;
24
27
  /**
25
- * Canonical form of a workspaceId for EMBEDDING in a key: dashes stripped so the
26
- * whole key is a single double-click-selectable word (`_` is a word char, `-`
27
- * is not). Kept byte-for-byte in sync with the platform codec.
28
+ * Canonical form of a workspaceId for EMBEDDING in a key. Public workspace ids
29
+ * are `wsp_<uuidhex>`, while storage rows still use dashed UUIDs. Keys embed only
30
+ * the hex field so the token remains underscore-delimited and double-click
31
+ * selectable.
28
32
  */
29
33
  export function normalizeWorkspaceId(workspaceId) {
30
- return workspaceId.replace(/-/g, "");
34
+ const trimmed = workspaceId.trim();
35
+ const publicMatch = PUBLIC_WORKSPACE_ID_RE.exec(trimmed);
36
+ if (publicMatch)
37
+ return publicMatch[1].toLowerCase();
38
+ if (DASHLESS_UUID_RE.test(trimmed))
39
+ return trimmed.toLowerCase();
40
+ const uuidMatch = UUID_RE.exec(trimmed);
41
+ return uuidMatch ? uuidMatch.slice(1).join("").toLowerCase() : trimmed.replace(/-/g, "");
31
42
  }
32
43
  /**
33
44
  * Parse a self-describing API key, or `null` for any legacy/opaque/tampered
@@ -55,20 +66,22 @@ export function parseApiKey(token) {
55
66
  * Assemble a valid API key from its parts (the inverse of {@link parseApiKey}).
56
67
  * Unlike the server's `mintApiKeyValue` this takes an EXPLICIT `secret` so it is
57
68
  * deterministic — used by codec round-trip / cross-repo parity tests. The
58
- * embedded workspace id is dash-normalized; `workspaceId` must not contain `_`.
69
+ * embedded workspace id is normalized; public `wsp_...` ids are accepted and
70
+ * embedded as their hex field.
59
71
  */
60
72
  export function formatApiKey(input) {
61
73
  const code = API_KEY_REGION_TO_CODE[input.region];
62
74
  if (code === undefined) {
63
75
  throw new Error(`API key region is not supported: ${input.region}`);
64
76
  }
65
- if (!input.workspaceId || input.workspaceId.includes("_")) {
77
+ const workspaceField = normalizeWorkspaceId(input.workspaceId);
78
+ if (!workspaceField || workspaceField.includes("_")) {
66
79
  throw new Error("workspaceId must be non-empty and contain no '_'");
67
80
  }
68
81
  if (!input.secret || input.secret.includes("_")) {
69
82
  throw new Error("secret must be non-empty and contain no '_'");
70
83
  }
71
- const body = ["aex", input.plane, code, normalizeWorkspaceId(input.workspaceId), input.secret].join("_");
84
+ const body = ["aex", input.plane, code, workspaceField, input.secret].join("_");
72
85
  return `${body}_${crc32Base36(body)}`;
73
86
  }
74
87
  function crc32Base36(input) {
@@ -4,8 +4,8 @@
4
4
  * A browser/runtime WebSocket handshake cannot carry an Authorization header,
5
5
  * so a subscriber first obtains a short-lived ticket from an authenticated
6
6
  * HTTP endpoint, then presents it as a `?ticket=` query parameter on the WS
7
- * upgrade. The ticket is an HMAC over `${runId}.${channel}.${exp}` keyed by
8
- * the coordinator secret — it binds the grant to one run, one stream channel,
7
+ * upgrade. The ticket is an HMAC over `${sessionId}.${channel}.${exp}` keyed by
8
+ * the coordinator secret — it binds the grant to one session, one stream channel,
9
9
  * and one expiry and is verified without any per-ticket storage.
10
10
  *
11
11
  * This lives in shared so the coordinator (which verifies) and the API
@@ -14,9 +14,9 @@
14
14
  */
15
15
  export type ConnectionTicketChannel = "event" | "log" | "all";
16
16
  /** Mint a `${channel}.${exp}.${mac}` ticket valid for `ttlMs` from `nowMs`. */
17
- export declare function mintConnectionTicket(runId: string, secret: string, nowMs: number, ttlMs?: number, channel?: ConnectionTicketChannel): Promise<{
17
+ export declare function mintConnectionTicket(sessionId: string, secret: string, nowMs: number, ttlMs?: number, channel?: ConnectionTicketChannel): Promise<{
18
18
  ticket: string;
19
19
  expiresAtMs: number;
20
20
  }>;
21
- /** Verify a ticket against `runId`, channel, and current time. Constant-time MAC compare. */
22
- export declare function verifyConnectionTicket(ticket: string, runId: string, secret: string, nowMs: number, channel?: ConnectionTicketChannel): Promise<boolean>;
21
+ /** Verify a ticket against `sessionId`, channel, and current time. Constant-time MAC compare. */
22
+ export declare function verifyConnectionTicket(ticket: string, sessionId: string, secret: string, nowMs: number, channel?: ConnectionTicketChannel): Promise<boolean>;
@@ -4,8 +4,8 @@
4
4
  * A browser/runtime WebSocket handshake cannot carry an Authorization header,
5
5
  * so a subscriber first obtains a short-lived ticket from an authenticated
6
6
  * HTTP endpoint, then presents it as a `?ticket=` query parameter on the WS
7
- * upgrade. The ticket is an HMAC over `${runId}.${channel}.${exp}` keyed by
8
- * the coordinator secret — it binds the grant to one run, one stream channel,
7
+ * upgrade. The ticket is an HMAC over `${sessionId}.${channel}.${exp}` keyed by
8
+ * the coordinator secret — it binds the grant to one session, one stream channel,
9
9
  * and one expiry and is verified without any per-ticket storage.
10
10
  *
11
11
  * This lives in shared so the coordinator (which verifies) and the API
@@ -23,14 +23,14 @@ async function hmacHex(secret, message) {
23
23
  return [...new Uint8Array(sig)].map((b) => b.toString(16).padStart(2, "0")).join("");
24
24
  }
25
25
  /** Mint a `${channel}.${exp}.${mac}` ticket valid for `ttlMs` from `nowMs`. */
26
- export async function mintConnectionTicket(runId, secret, nowMs, ttlMs = DEFAULT_TICKET_TTL_MS, channel = "event") {
26
+ export async function mintConnectionTicket(sessionId, secret, nowMs, ttlMs = DEFAULT_TICKET_TTL_MS, channel = "event") {
27
27
  const boundChannel = normalizeTicketChannel(channel);
28
28
  const exp = nowMs + ttlMs;
29
- const mac = await hmacHex(secret, `${runId}.${boundChannel}.${exp}`);
29
+ const mac = await hmacHex(secret, `${sessionId}.${boundChannel}.${exp}`);
30
30
  return { ticket: `${boundChannel}.${exp}.${mac}`, expiresAtMs: exp };
31
31
  }
32
- /** Verify a ticket against `runId`, channel, and current time. Constant-time MAC compare. */
33
- export async function verifyConnectionTicket(ticket, runId, secret, nowMs, channel = "event") {
32
+ /** Verify a ticket against `sessionId`, channel, and current time. Constant-time MAC compare. */
33
+ export async function verifyConnectionTicket(ticket, sessionId, secret, nowMs, channel = "event") {
34
34
  const [ticketChannel, expRaw, mac, ...rest] = ticket.split(".");
35
35
  if (rest.length > 0 || !ticketChannel || !expRaw || !mac)
36
36
  return false;
@@ -40,7 +40,7 @@ export async function verifyConnectionTicket(ticket, runId, secret, nowMs, chann
40
40
  const exp = Number(expRaw);
41
41
  if (!Number.isFinite(exp) || exp < nowMs)
42
42
  return false;
43
- const expected = await hmacHex(secret, `${runId}.${boundChannel}.${exp}`);
43
+ const expected = await hmacHex(secret, `${sessionId}.${boundChannel}.${exp}`);
44
44
  return timingSafeEqual(mac, expected);
45
45
  }
46
46
  /** Length-then-constant-time comparison of two hex strings. */
@@ -11,7 +11,7 @@
11
11
  * from the human `message`. `idempotency_conflict` and `insufficient_scope`
12
12
  * (previously message-less bare 409/403 bodies) are first-class here.
13
13
  */
14
- export declare const AEX_API_ERROR_CODES: readonly ["unauthorized", "forbidden", "insufficient_scope", "token_invalid", "token_revoked", "token_expired", "malformed_token", "not_found", "idempotency_conflict", "session_busy", "run_not_terminal", "unknown_workspace", "workspace_concurrency_exceeded", "workspace_submit_rate_exceeded", "workspace_spend_cap_exceeded", "insufficient_balance", "rate_limited", "upstream_error", "internal_error"];
14
+ export declare const AEX_API_ERROR_CODES: readonly ["unauthorized", "forbidden", "insufficient_scope", "token_invalid", "token_revoked", "token_expired", "malformed_token", "not_found", "idempotency_conflict", "session_busy", "session_not_terminal", "unknown_workspace", "workspace_concurrency_exceeded", "workspace_submit_rate_exceeded", "workspace_spend_cap_exceeded", "insufficient_balance", "rate_limited", "upstream_error", "internal_error"];
15
15
  export type AexApiErrorCode = (typeof AEX_API_ERROR_CODES)[number];
16
16
  /**
17
17
  * Human message per stable code. A `Record` (not `Partial`) so a code added to
@@ -22,7 +22,7 @@ export const AEX_API_ERROR_CODES = [
22
22
  "not_found",
23
23
  "idempotency_conflict",
24
24
  "session_busy",
25
- "run_not_terminal",
25
+ "session_not_terminal",
26
26
  "unknown_workspace",
27
27
  "workspace_concurrency_exceeded",
28
28
  "workspace_submit_rate_exceeded",
@@ -49,12 +49,12 @@ export const AEX_API_ERROR_MESSAGES = {
49
49
  not_found: "The requested resource was not found.",
50
50
  idempotency_conflict: "This idempotency key was already used with a different request body.",
51
51
  session_busy: "The session is busy handling another turn.",
52
- run_not_terminal: "The run has not reached a terminal state yet.",
52
+ session_not_terminal: "The session has not reached a terminal state yet.",
53
53
  unknown_workspace: "The workspace could not be resolved from the API key.",
54
54
  workspace_concurrency_exceeded: "The workspace has reached its concurrent-run limit.",
55
55
  workspace_submit_rate_exceeded: "The workspace submit-rate limit was exceeded.",
56
56
  workspace_spend_cap_exceeded: "The workspace monthly spend cap was reached.",
57
- insufficient_balance: "The workspace prepaid balance is insufficient to submit this run.",
57
+ insufficient_balance: "The workspace prepaid balance is insufficient to submit this session.",
58
58
  rate_limited: "Too many requests — retry after a short backoff.",
59
59
  upstream_error: "An upstream provider returned an error.",
60
60
  internal_error: "The aex API encountered an internal error."
@@ -68,7 +68,7 @@ export const AEX_API_ERROR_REMEDIES = {
68
68
  token_revoked: "Mint a new API key.",
69
69
  workspace_spend_cap_exceeded: "Raise the workspace spend cap or wait for the next billing cycle.",
70
70
  insufficient_balance: "Top up the workspace balance or add a payment method.",
71
- workspace_concurrency_exceeded: "Wait for in-flight runs to finish or raise the concurrency limit.",
71
+ workspace_concurrency_exceeded: "Wait for in-flight sessions to finish or raise the concurrency limit.",
72
72
  workspace_submit_rate_exceeded: "Slow the submit rate or raise the workspace submit-rate limit."
73
73
  };
74
74
  const API_ERROR_CODE_SET = new Set(AEX_API_ERROR_CODES);
@@ -34,7 +34,7 @@ export function apiErrorKindForCode(code) {
34
34
  case "workspace_submit_rate_exceeded":
35
35
  return "rate_limit";
36
36
  case "session_busy":
37
- case "run_not_terminal":
37
+ case "session_not_terminal":
38
38
  case "unknown_workspace":
39
39
  case "workspace_spend_cap_exceeded":
40
40
  case "insufficient_balance":
@@ -7,17 +7,17 @@
7
7
  * the shape the coordinator (Phase 2) appends, broadcasts, and archives.
8
8
  *
9
9
  * - **CloudEvents-shaped** self-describing envelope: a stable `id`, the
10
- * coarse `source`, the AG-UI-aligned `type`, the `subject` (run), a
10
+ * coarse `source`, the AG-UI-aligned `type`, the `subject` (session), a
11
11
  * `time`, the `sequence` cursor, and the typed `data`.
12
12
  * - **AG-UI vocabulary** for `type` where it maps; aex-specific events
13
13
  * ride AG-UI's reserved `CUSTOM` carrier under an `aex.*` name, so an
14
- * off-the-shelf AG-UI client reads an aex run with no glue.
14
+ * off-the-shelf AG-UI client reads an aex start with no glue.
15
15
  * - Two aex extensions: a coarse `source` (filter first by origin) and
16
16
  * an optional human `message` (log / CLI / dashboard rendering).
17
17
  *
18
18
  * Unified observability spine:
19
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-run
20
+ * event stream and the high-volume hosted-platform log stream ride one per-session
21
21
  * coordinator:
22
22
  * - `channel` — "event" (the typed AG-UI stream) or "log" (a verbose log
23
23
  * line). The single axis a consumer splits the unified stream
@@ -62,7 +62,7 @@ export declare const AEX_EVENT_MAP_VERSION: 1;
62
62
  export declare const AEX_EVENT_SOURCES: readonly ["agent", "api", "runtime", "mcp", "aex", "workflow", "host"];
63
63
  export type AexEventSource = (typeof AEX_EVENT_SOURCES)[number];
64
64
  /**
65
- * The channel a record rides on the unified per-run stream:
65
+ * The channel a record rides on the unified per-session stream:
66
66
  * - `event` — the typed, low-volume, fully-replayed AG-UI event stream.
67
67
  * - `log` — a high-volume verbose log line (level + message + fields). The
68
68
  * coordinator prunes flushed log rows after evidence archival
@@ -84,7 +84,7 @@ export type AexLogLevel = (typeof AEX_LOG_LEVELS)[number];
84
84
  * full AG-UI protocol — the events aex actually produces today — plus
85
85
  * `CUSTOM`, AG-UI's reserved carrier for aex-native events.
86
86
  */
87
- export declare const AEX_EVENT_TYPES: readonly ["RUN_STARTED", "RUN_FINISHED", "RUN_ERROR", "TEXT_MESSAGE_CONTENT", "TOOL_CALL_START", "TOOL_CALL_RESULT", "CUSTOM", "LOG"];
87
+ export declare const AEX_EVENT_TYPES: readonly ["TURN_STARTED", "TURN_FINISHED", "TURN_ERROR", "TEXT_MESSAGE_CONTENT", "TOOL_CALL_START", "TOOL_CALL_RESULT", "CUSTOM", "LOG"];
88
88
  export type AexEventType = (typeof AEX_EVENT_TYPES)[number];
89
89
  /**
90
90
  * One event on the unified log. CloudEvents core attributes (`specversion`,
@@ -94,18 +94,18 @@ export type AexEventType = (typeof AEX_EVENT_TYPES)[number];
94
94
  export interface AexEvent {
95
95
  /** CloudEvents specversion. Always {@link AEX_EVENT_SPECVERSION}. */
96
96
  readonly specversion: typeof AEX_EVENT_SPECVERSION;
97
- /** Stable, globally-unique event id: `${runId}:${sequence}`. Dedupe key. */
97
+ /** Stable, globally-unique event id: `${sessionId}:${sequence}`. Dedupe key. */
98
98
  readonly id: string;
99
99
  /** Coarse origin classifier. */
100
100
  readonly source: AexEventSource;
101
101
  /** AG-UI-aligned event type. */
102
102
  readonly type: AexEventType;
103
- /** The run this event belongs to (CloudEvents `subject`). */
103
+ /** The session this event belongs to (CloudEvents `subject`). */
104
104
  readonly subject: string;
105
- /** ISO-8601 event time (run base + the RunnerEvent's relative `tMs`). */
105
+ /** ISO-8601 event time (session base + the RunnerEvent's relative `tMs`). */
106
106
  readonly time: string;
107
107
  /**
108
- * Monotonic ordering cursor within the run — the GLOBAL `seq` the coordinator
108
+ * Monotonic ordering cursor within the session — the GLOBAL `seq` the coordinator
109
109
  * assigns on arrival. This is the canonical stream order and the dedupe key.
110
110
  */
111
111
  readonly sequence: number;
@@ -126,12 +126,12 @@ export interface AexEvent {
126
126
  * The DO's authoritative receive time (wall-clock ms), stamped at ingest
127
127
  * alongside the global {@link sequence}. This is the authoritative wall-clock
128
128
  * companion to `sequence` — distinct from `emittedAt` (the SOURCE's clock) and
129
- * `time` (the LOGICAL time = run base + relative tMs).
129
+ * `time` (the LOGICAL time = session base + relative tMs).
130
130
  *
131
131
  * NOTE: some edge clocks are coarsened/frozen-at-I/O, so `receivedAt` is
132
132
  * precisely "the coordinator's last-I/O wall-clock at ingest" — that is fine
133
133
  * as the authoritative receive marker. It does NOT need to exceed `emittedAt`:
134
- * the source runs on a different host with an independent clock, so cross-host
134
+ * the source sessions on a different host with an independent clock, so cross-host
135
135
  * drift can leave `receivedAt < emittedAt` and that is expected, not an error.
136
136
  */
137
137
  readonly receivedAt?: number;
@@ -152,10 +152,10 @@ export interface AexEvent {
152
152
  }
153
153
  /** Context the mapper needs to stamp absolute identity/time onto an event. */
154
154
  export interface AexEventContext {
155
- readonly runId: string;
155
+ readonly sessionId: string;
156
156
  /**
157
- * Run-start epoch ms. The RunnerEvent's `tMs` is relative to this, so
158
- * `time = new Date(baseMs + tMs)`. Pass the run's `createdAtMs`.
157
+ * SessionRecord-start epoch ms. The RunnerEvent's `tMs` is relative to this, so
158
+ * `time = new Date(baseMs + tMs)`. Pass the session's `createdAtMs`.
159
159
  */
160
160
  readonly baseMs: number;
161
161
  }
@@ -190,22 +190,22 @@ export type AexInboundLog = Omit<AexEvent, "specversion" | "id" | "subject" | "s
190
190
  * and the `LOG` payload — is supplied here.
191
191
  */
192
192
  export declare function logToInbound(source: AexEventSource, line: AexLogLine): AexInboundLog;
193
- export declare function isRunStarted(e: AexEvent): boolean;
194
- export declare function isRunFinished(e: AexEvent): boolean;
195
- export declare function isRunError(e: AexEvent): boolean;
193
+ export declare function isTurnStarted(e: AexEvent): boolean;
194
+ export declare function isTurnFinished(e: AexEvent): boolean;
195
+ export declare function isTurnError(e: AexEvent): boolean;
196
196
  /** A terminal event of either flavour (finished or error). */
197
- export declare function isRunTerminal(e: AexEvent): boolean;
197
+ export declare function isTurnTerminal(e: AexEvent): boolean;
198
198
  /**
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
199
+ * The CUSTOM `data.name`s the MANAGED runtime emits as a session/turn's SETTLED
200
+ * terminal. A managed one-shot session PARKS (`session_parked.v1` → one of these)
201
+ * rather than writing a `session_finished` → TURN_FINISHED, so these — not just
202
+ * the AG-UI TURN_FINISHED/TURN_ERROR — are what actually end a managed session's event
203
203
  * stream. Clean-cut (WS1): the bare `aex.session.error` park is retired in favour
204
204
  * of the terminal OUTCOME vocabulary — a failed turn is `failed`, a wall-clock
205
205
  * kill `timed_out`, a cancel `cancelled`, a clean finish `succeeded`; `idle`/
206
206
  * `suspended` remain the resumable parks. Held `awaiting_approval` is NOT here:
207
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`
208
+ * session is not settled. Kept byte-in-sync with `@aexhq/shared` `AEX_SESSION_PARKED_NAMES`
209
209
  * and the platform journal projection (`journal-project.ts` session_parked.v1).
210
210
  */
211
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"];
@@ -213,8 +213,8 @@ export declare const AEX_SESSION_PARKED_NAMES: readonly ["aex.session.idle", "ae
213
213
  * True for a managed-runtime session-park terminal (a resumable idle/suspended
214
214
  * park OR a terminal succeeded/failed/timed_out/cancelled outcome). The turn's
215
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.)
216
+ * should stop here exactly as it would on TURN_FINISHED/TURN_ERROR. (Held
217
+ * `awaiting_approval` is deliberately excluded — the session is paused, not settled.)
218
218
  */
219
219
  export declare function isSessionParked(e: AexEvent): boolean;
220
220
  export declare function isTextMessage(e: AexEvent): boolean;
@@ -225,25 +225,25 @@ export declare function isCustom(e: AexEvent): boolean;
225
225
  export declare function customName(e: AexEvent): string | null;
226
226
  /**
227
227
  * The `data.name` of the settle-consistency barrier event. The coordinator
228
- * broadcasts ONE such CUSTOM event as a run's LAST stream event, after the
229
- * Postgres mirror lands — so observing it ⇒ a subsequent `getRun` is terminal
230
- * and `listOutputs` is complete. It is intentionally a CUSTOM event (not a
231
- * typed RUN_* event): off-the-shelf AG-UI clients ignore it, while
232
- * `streamEnvelopes(runId, { settleConsistent: true })` ends the iterator on it.
233
- * Unlike RUN_FINISHED (the AG-UI render-complete UX signal, emitted by the
228
+ * broadcasts ONE such CUSTOM event as a session's LAST stream event, after the
229
+ * Postgres mirror lands — so observing it ⇒ a subsequent `getSessionRecord` is terminal
230
+ * and `listSessionFiles` is complete. It is intentionally a CUSTOM event (not a
231
+ * typed SESSION_* event): off-the-shelf AG-UI clients ignore it, while
232
+ * `streamEnvelopes(sessionId, { settleConsistent: true })` ends the iterator on it.
233
+ * Unlike TURN_FINISHED (the AG-UI render-complete UX signal, emitted by the
234
234
  * runner BEFORE the platform learns the outcome), this is settle-gated. The
235
235
  * platform mirrors this constant in `@aexhq/shared`.
236
236
  */
237
- export declare const AEX_RUN_SETTLED_NAME = "aex.run.settled";
237
+ export declare const AEX_SESSION_SETTLED_NAME = "aex.session.settled";
238
238
  /**
239
239
  * True for the settle-consistency barrier event (post-mirror, read-consistent).
240
240
  * Also true for a managed-runtime session-park terminal: the current plane emits
241
- * an `aex.run.settled` barrier after settle, but a stream may still observe the
241
+ * an `aex.session.settled` barrier after settle, but a stream may still observe the
242
242
  * park as the terminal event when no later barrier is delivered.
243
243
  */
244
- export declare function isRunSettled(e: AexEvent): boolean;
244
+ export declare function isSessionSettled(e: AexEvent): boolean;
245
245
  /**
246
- * The CUSTOM `data.name` of the HITL write-gate park: the run has reached the
246
+ * The CUSTOM `data.name` of the HITL write-gate park: the session has reached the
247
247
  * `awaiting_approval` state before a gated action and is holding for an
248
248
  * `approve()`/`deny()`. Structural (independent of model prose).
249
249
  */
@@ -285,17 +285,17 @@ export declare function exceedsRowBudget(e: AexEvent, max?: number): boolean;
285
285
  * that want it.
286
286
  */
287
287
  export type AguiEvent = {
288
- type: "RUN_STARTED";
288
+ type: "TURN_STARTED";
289
289
  timestamp: number;
290
290
  threadId: string;
291
- runId: string;
291
+ sessionId: string;
292
292
  } | {
293
- type: "RUN_FINISHED";
293
+ type: "TURN_FINISHED";
294
294
  timestamp: number;
295
295
  threadId: string;
296
- runId: string;
296
+ sessionId: string;
297
297
  } | {
298
- type: "RUN_ERROR";
298
+ type: "TURN_ERROR";
299
299
  timestamp: number;
300
300
  message: string;
301
301
  code?: string;
@@ -323,7 +323,7 @@ export type AguiEvent = {
323
323
  };
324
324
  /**
325
325
  * Project an aex envelope to a strict AG-UI event so an off-the-shelf
326
- * AG-UI client can consume an aex run with no glue. This is the
326
+ * AG-UI client can consume an aex start with no glue. This is the
327
327
  * client-side projection the SDK exposes.
328
328
  */
329
329
  export declare function toAGUI(e: AexEvent): AguiEvent;