@aexhq/sdk 0.40.15 → 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.
- package/README.md +25 -25
- package/dist/_contracts/api-key.d.ts +6 -4
- package/dist/_contracts/api-key.js +20 -7
- package/dist/_contracts/asset-upload-helper.d.ts +2 -2
- package/dist/_contracts/asset-upload-helper.js +2 -2
- package/dist/_contracts/connection-ticket.d.ts +5 -5
- package/dist/_contracts/connection-ticket.js +7 -7
- package/dist/_contracts/error-codes.d.ts +1 -1
- package/dist/_contracts/error-codes.js +4 -4
- package/dist/_contracts/error-factory.js +1 -1
- package/dist/_contracts/event-envelope.d.ts +41 -41
- package/dist/_contracts/event-envelope.js +49 -49
- package/dist/_contracts/event-stream-client.d.ts +9 -9
- package/dist/_contracts/event-stream-client.js +5 -5
- package/dist/_contracts/event-view.d.ts +6 -6
- package/dist/_contracts/event-view.js +12 -12
- package/dist/_contracts/http.js +1 -1
- package/dist/_contracts/index.d.ts +10 -10
- package/dist/_contracts/index.js +9 -9
- package/dist/_contracts/models.d.ts +17 -17
- package/dist/_contracts/models.js +14 -14
- package/dist/_contracts/operations.d.ts +79 -82
- package/dist/_contracts/operations.js +233 -243
- package/dist/_contracts/provider-support.d.ts +2 -2
- package/dist/_contracts/runner-event.d.ts +8 -8
- package/dist/_contracts/runner-event.js +9 -9
- package/dist/_contracts/runtime-manifest.d.ts +12 -12
- package/dist/_contracts/runtime-manifest.js +1 -1
- package/dist/_contracts/runtime-sizes.d.ts +12 -12
- package/dist/_contracts/runtime-sizes.js +18 -18
- package/dist/_contracts/runtime-types.d.ts +117 -117
- package/dist/_contracts/runtime-types.js +2 -2
- package/dist/_contracts/sdk-errors.d.ts +3 -3
- package/dist/_contracts/sdk-errors.js +4 -4
- package/dist/_contracts/sdk-secrets.js +10 -10
- package/dist/_contracts/session-artifacts.d.ts +151 -0
- package/dist/_contracts/session-artifacts.js +234 -0
- package/dist/_contracts/{run-config.d.ts → session-config.d.ts} +29 -29
- package/dist/_contracts/{run-config.js → session-config.js} +37 -37
- package/dist/_contracts/session-cost.d.ts +140 -0
- package/dist/_contracts/{run-cost.js → session-cost.js} +94 -94
- package/dist/_contracts/{run-custody.d.ts → session-custody.d.ts} +16 -16
- package/dist/_contracts/{run-custody.js → session-custody.js} +42 -42
- package/dist/_contracts/session-record.d.ts +112 -0
- package/dist/_contracts/{run-record.js → session-record.js} +23 -23
- package/dist/_contracts/session-retention.d.ts +209 -0
- package/dist/_contracts/{run-retention.js → session-retention.js} +116 -116
- package/dist/_contracts/{run-unit.d.ts → session-unit.d.ts} +38 -38
- package/dist/_contracts/{run-unit.js → session-unit.js} +33 -33
- package/dist/_contracts/side-effect-audit.d.ts +14 -14
- package/dist/_contracts/side-effect-audit.js +38 -38
- package/dist/_contracts/sse.d.ts +1 -1
- package/dist/_contracts/sse.js +0 -0
- package/dist/_contracts/stable.d.ts +1 -1
- package/dist/_contracts/stable.js +1 -1
- package/dist/_contracts/status.d.ts +18 -18
- package/dist/_contracts/status.js +19 -19
- package/dist/_contracts/submission.d.ts +101 -99
- package/dist/_contracts/submission.js +96 -96
- package/dist/_contracts/{run-trace.d.ts → turn-trace.d.ts} +1 -1
- package/dist/_contracts/webhook-verify.d.ts +1 -1
- package/dist/_contracts/webhook-verify.js +1 -1
- package/dist/agents-md.d.ts +4 -4
- package/dist/agents-md.js +5 -5
- package/dist/agents-md.js.map +1 -1
- package/dist/bundle.d.ts +1 -1
- package/dist/bundle.js +1 -1
- package/dist/bundle.js.map +1 -1
- package/dist/cli.mjs +580 -623
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +141 -155
- package/dist/client.js +236 -245
- package/dist/client.js.map +1 -1
- package/dist/fetch-archive.js +3 -3
- package/dist/file.d.ts +7 -7
- package/dist/file.js +8 -8
- package/dist/file.js.map +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.d.ts +1 -1
- package/dist/retry.d.ts +1 -1
- package/dist/secret.d.ts +6 -6
- package/dist/secret.js +6 -6
- package/dist/secret.js.map +1 -1
- package/dist/skill.d.ts +2 -2
- package/dist/skill.js +3 -3
- package/dist/skill.js.map +1 -1
- package/dist/tool.js +2 -2
- package/dist/tool.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/docs/authentication.md +11 -11
- package/docs/billing.md +3 -3
- package/docs/cleanup.md +5 -5
- package/docs/concepts/agent-tools.md +5 -5
- package/docs/concepts/composition.md +3 -3
- package/docs/concepts/providers-and-runtimes.md +3 -3
- package/docs/concepts/{runs.md → sessions.md} +8 -8
- package/docs/concepts/subagents.md +16 -16
- package/docs/credentials.md +7 -7
- package/docs/defaults.md +14 -14
- package/docs/errors.md +10 -10
- package/docs/events.md +26 -26
- package/docs/files.md +267 -0
- package/docs/limits-and-quotas.md +35 -35
- package/docs/limits.md +6 -6
- package/docs/mcp.md +3 -3
- package/docs/networking.md +24 -24
- package/docs/provider-runtime-capabilities.md +1 -1
- package/docs/public-surface.json +6 -6
- package/docs/quickstart.md +13 -13
- package/docs/release.md +5 -5
- package/docs/retries.md +3 -3
- package/docs/secrets.md +16 -16
- package/docs/session-config.md +58 -0
- package/docs/{run-record.md → session-record.md} +16 -16
- package/docs/skills.md +9 -9
- package/docs/vision-skills.md +7 -7
- package/docs/webhooks.md +11 -11
- package/examples/feature-tour.ts +17 -17
- package/examples/spike-settle-latency.ts +11 -11
- package/package.json +1 -1
- package/dist/_contracts/run-artifacts.d.ts +0 -49
- package/dist/_contracts/run-artifacts.js +0 -102
- package/dist/_contracts/run-cost.d.ts +0 -140
- package/dist/_contracts/run-record.d.ts +0 -116
- package/dist/_contracts/run-retention.d.ts +0 -209
- package/docs/outputs.md +0 -267
- package/docs/run-config.md +0 -58
- /package/dist/_contracts/{run-trace.js → turn-trace.js} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { SessionStatus, SessionTerminalOutcome } from "./status.js";
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type { SessionCostProviderUsage } from "./session-cost.js";
|
|
3
|
+
import type { PlatformSessionSubmissionInput, PlatformSubmission } from "./submission.js";
|
|
4
4
|
/**
|
|
5
|
-
* Loose record describing a
|
|
5
|
+
* Loose record describing a session as the dashboard BFF returns it. Concrete
|
|
6
6
|
* dashboard-managed fields appear in the index signature; the SDK and CLI
|
|
7
7
|
* may surface them without strong typing per-field.
|
|
8
8
|
*
|
|
@@ -12,7 +12,7 @@ import type { PlatformRunSubmissionInput, PlatformSubmission } from "./submissio
|
|
|
12
12
|
* rollout; SDK consumers MUST treat it as best-effort and not panic on
|
|
13
13
|
* its absence.
|
|
14
14
|
*/
|
|
15
|
-
export interface
|
|
15
|
+
export interface SessionRecord {
|
|
16
16
|
readonly id: string;
|
|
17
17
|
readonly status: string;
|
|
18
18
|
readonly workspaceId?: string;
|
|
@@ -20,10 +20,10 @@ export interface Run {
|
|
|
20
20
|
readonly updatedAt?: string;
|
|
21
21
|
readonly terminalAt?: string | null;
|
|
22
22
|
/**
|
|
23
|
-
* The
|
|
23
|
+
* The session's EXECUTION start (ISO-8601) — when the agent actually began
|
|
24
24
|
* running, distinct from {@link createdAt} (submission/accept time). Present
|
|
25
|
-
* from the moment the
|
|
26
|
-
* absent before it starts and after the
|
|
25
|
+
* from the moment the session starts executing and throughout its live duration;
|
|
26
|
+
* absent before it starts and after the session's live object is torn down (a
|
|
27
27
|
* terminal run also carries {@link terminalAt} and {@link costTelemetry}
|
|
28
28
|
* durations).
|
|
29
29
|
*/
|
|
@@ -36,18 +36,18 @@ export interface Run {
|
|
|
36
36
|
*/
|
|
37
37
|
readonly failureClass?: string | null;
|
|
38
38
|
/**
|
|
39
|
-
* Aggregate token usage when a deployment chooses to expose it on the
|
|
39
|
+
* Aggregate token usage when a deployment chooses to expose it on the session
|
|
40
40
|
* record. Mid-run this is not populated. Settled provider/runtime usage is
|
|
41
41
|
* exposed through {@link costTelemetry}; per-turn usage breadcrumbs, when a
|
|
42
42
|
* deployment records them internally, are not part of the normal public event
|
|
43
43
|
* stream.
|
|
44
44
|
*/
|
|
45
45
|
readonly usage?: UsageSummary;
|
|
46
|
-
readonly costTelemetry?: import("./
|
|
46
|
+
readonly costTelemetry?: import("./session-cost.js").SessionCostTelemetry;
|
|
47
47
|
/**
|
|
48
|
-
* The authoritative terminal OUTCOME of the
|
|
48
|
+
* The authoritative terminal OUTCOME of the session's last turn — the settle-
|
|
49
49
|
* written outcome (`succeeded`/`failed`/`timed_out`/`cancelled`), distinct
|
|
50
|
-
* from the resumable lifecycle {@link status}. Absent until the
|
|
50
|
+
* from the resumable lifecycle {@link status}. Absent until the session settles.
|
|
51
51
|
*/
|
|
52
52
|
readonly lastTurnOutcome?: SessionTerminalOutcome;
|
|
53
53
|
readonly runtimeManifest?: import("./runtime-manifest.js").RuntimeManifest;
|
|
@@ -131,7 +131,7 @@ export interface SessionRetentionPolicy {
|
|
|
131
131
|
export type SessionSubmission = Omit<PlatformSubmission, "prompt"> & {
|
|
132
132
|
readonly prompt?: readonly string[];
|
|
133
133
|
};
|
|
134
|
-
export type SessionCreateRequest = Omit<
|
|
134
|
+
export type SessionCreateRequest = Omit<PlatformSessionSubmissionInput, "idempotencyKey" | "submission"> & {
|
|
135
135
|
readonly submission: SessionSubmission;
|
|
136
136
|
readonly input?: string | readonly string[];
|
|
137
137
|
readonly retention?: SessionRetentionPolicy;
|
|
@@ -181,20 +181,20 @@ export interface UsageSummary {
|
|
|
181
181
|
}
|
|
182
182
|
/**
|
|
183
183
|
* Project a {@link UsageSummary} from the settle-written
|
|
184
|
-
* {@link
|
|
185
|
-
* usage ({@link
|
|
184
|
+
* {@link SessionCostProviderUsage} entries — the SINGLE server source of token
|
|
185
|
+
* usage ({@link SessionRecord.costTelemetry}`.providerUsage`). Sums each field across all
|
|
186
186
|
* provider entries; a field is present only when at least one entry carried it.
|
|
187
187
|
* This retires the dead `session.usage` / `aex.usage`-event usage path: the SDK
|
|
188
188
|
* derives usage from cost telemetry, never re-reads a dual-written top-level
|
|
189
189
|
* `usage`. Pure.
|
|
190
190
|
*/
|
|
191
|
-
export declare function usageFromProviderUsage(providerUsage: readonly
|
|
191
|
+
export declare function usageFromProviderUsage(providerUsage: readonly SessionCostProviderUsage[] | undefined): UsageSummary;
|
|
192
192
|
/**
|
|
193
|
-
* The unified SETTLED-RESULT contract shared by `
|
|
193
|
+
* The unified SETTLED-RESULT contract shared by `start()` and `done()`. Because
|
|
194
194
|
* both await the settle commit by default, these fields are ALWAYS present at a
|
|
195
195
|
* terminal read — they are NON-optional, so a code path that forgets to
|
|
196
196
|
* populate `costUsd`/`usage`/the terminal `status` fails to typecheck. The SDK
|
|
197
|
-
* `
|
|
197
|
+
* `SessionResult`/`SessionTurnResult` extend this one shape so `done()` == `start()`.
|
|
198
198
|
*
|
|
199
199
|
* `costUsd` is the AEX showback estimate in USD (>= 0) and EXCLUDES the
|
|
200
200
|
* customer's BYOK provider spend — price BYOK from `usage` tokens.
|
|
@@ -208,7 +208,7 @@ export interface SettledResult {
|
|
|
208
208
|
readonly costUsd: number;
|
|
209
209
|
/** Aggregate token usage, derived from `costTelemetry.providerUsage`. */
|
|
210
210
|
readonly usage: UsageSummary;
|
|
211
|
-
/** Terminal failure message (from the terminal `
|
|
211
|
+
/** Terminal failure message (from the terminal `TURN_ERROR` event) when `!ok`. */
|
|
212
212
|
readonly error?: string;
|
|
213
213
|
}
|
|
214
214
|
/**
|
|
@@ -217,29 +217,29 @@ export interface SettledResult {
|
|
|
217
217
|
* - `uncertain` — the model signalled low confidence / declined to commit.
|
|
218
218
|
* - `refused` — the model refused the request.
|
|
219
219
|
*/
|
|
220
|
-
export type
|
|
220
|
+
export type TurnRefusalReason = "schema_violation" | "uncertain" | "refused";
|
|
221
221
|
/**
|
|
222
|
-
* The typed outcome of a `
|
|
222
|
+
* The typed outcome of a `start<T>({ responseFormat })`: EITHER a schema-valid
|
|
223
223
|
* decoded value OR a typed refusal — there is no untyped path that silently
|
|
224
224
|
* yields a hallucinated object. `T` is the decoded value type.
|
|
225
225
|
*/
|
|
226
|
-
export type
|
|
226
|
+
export type TurnOutcome<T = unknown> = {
|
|
227
227
|
readonly kind: "decoded";
|
|
228
228
|
readonly value: T;
|
|
229
229
|
} | {
|
|
230
230
|
readonly kind: "refused";
|
|
231
|
-
readonly reason:
|
|
231
|
+
readonly reason: TurnRefusalReason;
|
|
232
232
|
readonly detail?: string;
|
|
233
233
|
};
|
|
234
234
|
/** One item's settled result inside a {@link BatchResult}. */
|
|
235
235
|
export interface BatchItemResult<T = unknown> extends SettledResult {
|
|
236
|
-
readonly
|
|
236
|
+
readonly sessionId: string;
|
|
237
237
|
/** Present only for a `responseFormat`-decoded item. */
|
|
238
|
-
readonly outcome?:
|
|
238
|
+
readonly outcome?: TurnOutcome<T>;
|
|
239
239
|
}
|
|
240
240
|
/**
|
|
241
241
|
* The result of `aex.batch(items, …)`: every item's settled result PLUS a real
|
|
242
|
-
* rollup. The rollup is honest because `
|
|
242
|
+
* rollup. The rollup is honest because `start()` awaits settle, so every item's
|
|
243
243
|
* `costUsd`/`usage` is populated — a missing cost is a typed absent, not a
|
|
244
244
|
* silent `$0`.
|
|
245
245
|
*/
|
|
@@ -251,13 +251,13 @@ export interface BatchResult<T = unknown> {
|
|
|
251
251
|
readonly failed: readonly BatchItemResult<T>[];
|
|
252
252
|
}
|
|
253
253
|
/**
|
|
254
|
-
* Filters for {@link import("./operations.js").
|
|
255
|
-
* Every field is optional; omitting all of them lists the most recent
|
|
254
|
+
* Filters for {@link import("./operations.js").listSessionRecords} / the CLI's `aex sessions`.
|
|
255
|
+
* Every field is optional; omitting all of them lists the most recent sessions in the
|
|
256
256
|
* token's workspace. Workspace identity is derived server-side from the API key,
|
|
257
|
-
* so there is no `workspaceId` here — a token can only ever enumerate its own
|
|
257
|
+
* so there is no `workspaceId` here — a token can only ever enumerate its own sessions.
|
|
258
258
|
*/
|
|
259
|
-
export interface
|
|
260
|
-
/** Restrict to a single
|
|
259
|
+
export interface SessionRecordListQuery {
|
|
260
|
+
/** Restrict to a single session status, e.g. `"succeeded"`. */
|
|
261
261
|
readonly status?: string;
|
|
262
262
|
/** ISO-8601 lower bound on `createdAt` (inclusive). */
|
|
263
263
|
readonly since?: string;
|
|
@@ -267,46 +267,46 @@ export interface RunListQuery {
|
|
|
267
267
|
readonly cursor?: string;
|
|
268
268
|
}
|
|
269
269
|
/**
|
|
270
|
-
* A public-safe run summary as returned by `GET /api/
|
|
270
|
+
* A public-safe run summary as returned by `GET /api/sessions` (the workspace run
|
|
271
271
|
* list). DELIBERATELY omits the submission snapshot (model/prompt/env) — the full,
|
|
272
|
-
* redaction-scanned submission is only reachable through `
|
|
272
|
+
* redaction-scanned submission is only reachable through `getSessionUnit(sessionId)`.
|
|
273
273
|
*/
|
|
274
|
-
export interface
|
|
274
|
+
export interface SessionRecordSummary {
|
|
275
275
|
readonly id: string;
|
|
276
276
|
readonly status: string;
|
|
277
277
|
readonly createdAt: string;
|
|
278
278
|
readonly updatedAt: string;
|
|
279
|
-
/** Settled showback estimate (USD), present once the
|
|
279
|
+
/** Settled showback estimate (USD), present once the session has cost telemetry. */
|
|
280
280
|
readonly costUsd?: number;
|
|
281
281
|
}
|
|
282
|
-
/** One page of the workspace
|
|
283
|
-
export interface
|
|
284
|
-
readonly
|
|
282
|
+
/** One page of the workspace session list. `nextCursor` absent ⇒ last page. */
|
|
283
|
+
export interface SessionRecordListPage {
|
|
284
|
+
readonly sessions: readonly SessionRecordSummary[];
|
|
285
285
|
readonly nextCursor?: string;
|
|
286
286
|
}
|
|
287
287
|
/**
|
|
288
|
-
* The minimal capability a value must carry to be RESOLVABLE through the
|
|
289
|
-
* facade — `
|
|
288
|
+
* The minimal capability a value must carry to be RESOLVABLE through the session
|
|
289
|
+
* facade — `getSessionRecord` / `listSessionRecordEvents` / `listSessionFiles` all key on this `id`.
|
|
290
290
|
* Encodes the "handed ⇒ resolvable" invariant at the type level: anything the
|
|
291
|
-
* platform hands you as a
|
|
291
|
+
* platform hands you as a session reference exposes a resolvable `id`, so a session can
|
|
292
292
|
* never be surfaced as a bare unresolvable string.
|
|
293
293
|
*/
|
|
294
|
-
export interface
|
|
294
|
+
export interface ResolvableSessionRef {
|
|
295
295
|
readonly id: string;
|
|
296
296
|
}
|
|
297
297
|
/**
|
|
298
|
-
* A subagent
|
|
299
|
-
* A first-class, lineage-discoverable run reference: it {@link
|
|
300
|
-
* (its `id` resolves through the
|
|
301
|
-
* lineage (`
|
|
302
|
-
* observable exactly like a top-level
|
|
298
|
+
* A subagent child session, enumerated under its parent via `GET /sessions/:id/children`.
|
|
299
|
+
* A first-class, lineage-discoverable run reference: it {@link ResolvableSessionRef}
|
|
300
|
+
* (its `id` resolves through the session record facade — events/files/getSessionRecord), carries the
|
|
301
|
+
* lineage (`parentSessionId`/`depth`) and the terminal outcome/cost, so a child is
|
|
302
|
+
* observable exactly like a top-level session.
|
|
303
303
|
*/
|
|
304
|
-
export interface
|
|
305
|
-
/** The parent
|
|
306
|
-
readonly
|
|
307
|
-
/** The child's
|
|
304
|
+
export interface ChildSessionRef extends ResolvableSessionRef {
|
|
305
|
+
/** The parent session this child was spawned by. */
|
|
306
|
+
readonly parentSessionId: string;
|
|
307
|
+
/** The child's session status. */
|
|
308
308
|
readonly status: string;
|
|
309
|
-
/** Subagent nesting depth (1 = direct child of the top-level
|
|
309
|
+
/** Subagent nesting depth (1 = direct child of the top-level session). */
|
|
310
310
|
readonly depth?: number;
|
|
311
311
|
/** Settled AEX showback estimate (USD) for the child, when present. */
|
|
312
312
|
readonly costUsd?: number;
|
|
@@ -316,18 +316,18 @@ export interface ChildRunRef extends ResolvableRunRef {
|
|
|
316
316
|
readonly lastTurnOutcome?: SessionTerminalOutcome;
|
|
317
317
|
}
|
|
318
318
|
/**
|
|
319
|
-
* Cross-
|
|
320
|
-
* corpus with `
|
|
321
|
-
* The MVP composes this client-side (per-
|
|
322
|
-
* server-side `GET /api/
|
|
323
|
-
* cross-
|
|
319
|
+
* Cross-session session-file search query (`Aex.files.search`). Restrict to a
|
|
320
|
+
* corpus with `sessionIds`; filter by filename substring / extension / content type.
|
|
321
|
+
* The MVP composes this client-side (per-session `listSessionFiles` + filter) — a future
|
|
322
|
+
* server-side `GET /api/files/search` can back the same contract with a real
|
|
323
|
+
* cross-session index, body-only swap.
|
|
324
324
|
*/
|
|
325
|
-
export interface
|
|
326
|
-
/** Restrict the search to these
|
|
327
|
-
readonly
|
|
325
|
+
export interface SessionFileSearchQuery {
|
|
326
|
+
/** Restrict the search to these sessions (the chat corpus allow-list). */
|
|
327
|
+
readonly sessionIds?: readonly string[];
|
|
328
328
|
/**
|
|
329
329
|
* Filename match. A string is a case-insensitive SUBSTRING match; a RegExp is
|
|
330
|
-
* tested as given. Unified with {@link
|
|
330
|
+
* tested as given. Unified with {@link SessionFileQuery.filename} (`string | RegExp`)
|
|
331
331
|
* so the same value works on `find()` and `search()` — feed it through
|
|
332
332
|
* {@link import("./operations.js").toFilenameMatcher} rather than assuming a string.
|
|
333
333
|
*/
|
|
@@ -339,30 +339,30 @@ export interface OutputSearchQuery {
|
|
|
339
339
|
/** Cap the number of hits returned (default 100). */
|
|
340
340
|
readonly limit?: number;
|
|
341
341
|
}
|
|
342
|
-
/** One
|
|
343
|
-
export interface
|
|
344
|
-
readonly
|
|
345
|
-
readonly
|
|
342
|
+
/** One session-file search hit — a reference only (no bytes); read with `readSessionFileText`. */
|
|
343
|
+
export interface SessionFileSearchHit {
|
|
344
|
+
readonly sessionId: string;
|
|
345
|
+
readonly fileId: string;
|
|
346
346
|
readonly filename?: string;
|
|
347
347
|
readonly sizeBytes?: number;
|
|
348
348
|
readonly contentType?: string;
|
|
349
349
|
}
|
|
350
|
-
/** A page of
|
|
351
|
-
export interface
|
|
352
|
-
readonly hits: readonly
|
|
350
|
+
/** A page of session-file search hits. */
|
|
351
|
+
export interface SessionFileSearchPage {
|
|
352
|
+
readonly hits: readonly SessionFileSearchHit[];
|
|
353
353
|
}
|
|
354
|
-
/** Status of a per-
|
|
355
|
-
export type
|
|
354
|
+
/** Status of a per-session webhook delivery. Terminal: delivered/exhausted/invalid. */
|
|
355
|
+
export type SessionWebhookDeliveryStatus = "pending" | "delivering" | "retrying" | "delivered" | "exhausted" | "invalid";
|
|
356
356
|
/**
|
|
357
|
-
* One row of a
|
|
358
|
-
* `GET /api/
|
|
357
|
+
* One row of a session's webhook delivery ledger, as returned by
|
|
358
|
+
* `GET /api/sessions/:id/webhook-deliveries`. `id` is the stable `webhook-id`
|
|
359
359
|
* header the consumer dedupes on across retries; the optional fields are
|
|
360
360
|
* populated only once a delivery attempt has been made.
|
|
361
361
|
*/
|
|
362
|
-
export interface
|
|
362
|
+
export interface SessionWebhookDelivery {
|
|
363
363
|
readonly id: string;
|
|
364
364
|
readonly eventType: string;
|
|
365
|
-
readonly status:
|
|
365
|
+
readonly status: SessionWebhookDeliveryStatus;
|
|
366
366
|
readonly attemptCount: number;
|
|
367
367
|
readonly lastStatusCode?: number;
|
|
368
368
|
readonly lastError?: string;
|
|
@@ -381,10 +381,10 @@ export interface ProviderEvent {
|
|
|
381
381
|
readonly [key: string]: unknown;
|
|
382
382
|
}
|
|
383
383
|
/**
|
|
384
|
-
* One captured
|
|
385
|
-
* `
|
|
384
|
+
* One captured session file as the dashboard reports it. Use
|
|
385
|
+
* `sessionFileLink` / `createSessionFileLink` to get a temporary direct URL for download.
|
|
386
386
|
*/
|
|
387
|
-
export interface
|
|
387
|
+
export interface SessionFile {
|
|
388
388
|
readonly id: string;
|
|
389
389
|
readonly filename?: string;
|
|
390
390
|
readonly sizeBytes?: number;
|
|
@@ -392,15 +392,15 @@ export interface Output {
|
|
|
392
392
|
readonly createdAt?: string;
|
|
393
393
|
readonly [key: string]: unknown;
|
|
394
394
|
}
|
|
395
|
-
export type
|
|
396
|
-
export type
|
|
397
|
-
export interface
|
|
398
|
-
/** Exact normalized
|
|
395
|
+
export type SessionFilePathMatch = "exact" | "suffix";
|
|
396
|
+
export type SessionFileType = "text" | "json" | "image" | "audio" | "video" | "pdf" | "archive" | "binary" | "unknown";
|
|
397
|
+
export interface SessionFileQuery {
|
|
398
|
+
/** Exact normalized file path. Leading `/` and `files/` are ignored. */
|
|
399
399
|
readonly path?: string;
|
|
400
400
|
/** Basename match. A RegExp is tested against the basename only. */
|
|
401
401
|
readonly filename?: string | RegExp;
|
|
402
402
|
/**
|
|
403
|
-
* Directory prefix. Leading `/` and `
|
|
403
|
+
* Directory prefix. Leading `/` and `files/` are ignored.
|
|
404
404
|
* `recursive` defaults to true.
|
|
405
405
|
*/
|
|
406
406
|
readonly dir?: string;
|
|
@@ -410,22 +410,22 @@ export interface OutputQuery {
|
|
|
410
410
|
/** Exact content type or a prefix wildcard such as `image/*`. */
|
|
411
411
|
readonly contentType?: string;
|
|
412
412
|
/** High-level type inferred from content type first, then extension. */
|
|
413
|
-
readonly type?:
|
|
413
|
+
readonly type?: SessionFileType;
|
|
414
414
|
}
|
|
415
|
-
export interface
|
|
415
|
+
export interface SessionFilePathSelector {
|
|
416
416
|
readonly path: string;
|
|
417
|
-
readonly match?:
|
|
417
|
+
readonly match?: SessionFilePathMatch;
|
|
418
418
|
}
|
|
419
|
-
export interface
|
|
419
|
+
export interface SessionFileIdSelector {
|
|
420
420
|
readonly id: string;
|
|
421
421
|
}
|
|
422
|
-
export type
|
|
423
|
-
export interface
|
|
424
|
-
readonly
|
|
422
|
+
export type SessionFileSelector = SessionFile | SessionFileIdSelector | SessionFilePathSelector;
|
|
423
|
+
export interface SessionFileDownload {
|
|
424
|
+
readonly file: SessionFile;
|
|
425
425
|
readonly bytes: Uint8Array;
|
|
426
426
|
}
|
|
427
|
-
/** Options for `Aex.sessions.
|
|
428
|
-
export interface
|
|
427
|
+
/** Options for `Aex.sessions.files(id).read` / {@link import("./operations.js").readSessionFileText}. */
|
|
428
|
+
export interface ReadSessionFileTextOptions {
|
|
429
429
|
/**
|
|
430
430
|
* Stop reading after this many bytes. Defaults to 50_000; clamped server-side
|
|
431
431
|
* of the SDK to [1, 10_000_000]. The read streams and cancels once the cap is
|
|
@@ -433,8 +433,8 @@ export interface ReadOutputTextOptions {
|
|
|
433
433
|
*/
|
|
434
434
|
readonly maxBytes?: number;
|
|
435
435
|
/**
|
|
436
|
-
* Per-attempt timeout for fetching and reading the selected
|
|
437
|
-
* Defaults to 30_000ms; idempotent
|
|
436
|
+
* Per-attempt timeout for fetching and reading the selected file body.
|
|
437
|
+
* Defaults to 30_000ms; idempotent file reads retry once on timeout before
|
|
438
438
|
* surfacing a structured NETWORK_ERROR.
|
|
439
439
|
*/
|
|
440
440
|
readonly timeoutMs?: number;
|
|
@@ -445,14 +445,14 @@ export interface ReadOutputTextOptions {
|
|
|
445
445
|
readonly grep?: string | RegExp;
|
|
446
446
|
}
|
|
447
447
|
/**
|
|
448
|
-
* A byte-capped, decoded text read of one
|
|
449
|
-
* `Aex.sessions.
|
|
448
|
+
* A byte-capped, decoded text read of one session file, as returned by
|
|
449
|
+
* `Aex.sessions.files(id).read`. Built for feeding session deliverables to an LLM
|
|
450
450
|
* without loading the whole (possibly very large) file into memory or context:
|
|
451
451
|
* the read streams and stops at `maxBytes`, so `text` is at most that many bytes
|
|
452
452
|
* decoded as UTF-8. Check {@link truncated} before treating `text` as complete.
|
|
453
453
|
*/
|
|
454
|
-
export interface
|
|
455
|
-
readonly
|
|
454
|
+
export interface SessionFileText {
|
|
455
|
+
readonly file: SessionFile;
|
|
456
456
|
/** Decoded UTF-8, capped to the requested `maxBytes`. */
|
|
457
457
|
readonly text: string;
|
|
458
458
|
/** True when the file is larger than `maxBytes` (so `text` is a prefix). */
|
|
@@ -463,16 +463,16 @@ export interface OutputText {
|
|
|
463
463
|
*/
|
|
464
464
|
readonly totalBytes: number;
|
|
465
465
|
}
|
|
466
|
-
export type
|
|
467
|
-
export interface
|
|
466
|
+
export type SessionFileLinkExpiresIn = number | "15m" | "1h" | "1d";
|
|
467
|
+
export interface SessionFileLinkOptions {
|
|
468
468
|
/** Seconds or one of the documented presets. Defaults to `"1h"`. */
|
|
469
|
-
readonly expiresIn?:
|
|
469
|
+
readonly expiresIn?: SessionFileLinkExpiresIn;
|
|
470
470
|
}
|
|
471
|
-
export interface
|
|
471
|
+
export interface SessionFileLink {
|
|
472
472
|
readonly url: string;
|
|
473
473
|
readonly expiresAt?: string;
|
|
474
474
|
readonly expiresInSeconds?: number;
|
|
475
|
-
readonly
|
|
475
|
+
readonly file?: SessionFile;
|
|
476
476
|
readonly [key: string]: unknown;
|
|
477
477
|
}
|
|
478
478
|
export interface WhoAmI {
|
|
@@ -496,21 +496,21 @@ export interface WhoAmI {
|
|
|
496
496
|
* `null` means no app-visible cap is applied for that field.
|
|
497
497
|
*/
|
|
498
498
|
readonly caps?: {
|
|
499
|
-
/** Token-bucket cap on POST /api/
|
|
500
|
-
readonly
|
|
501
|
-
/** Hard cap on concurrent non-terminal
|
|
502
|
-
readonly
|
|
503
|
-
/** Storage cap (bytes) on captured
|
|
499
|
+
/** Token-bucket cap on POST /api/sessions per minute, per workspace. */
|
|
500
|
+
readonly sessionSubmitPerMinute?: number;
|
|
501
|
+
/** Hard cap on concurrent non-terminal sessions the workspace may hold. */
|
|
502
|
+
readonly maxConcurrentSessions?: number;
|
|
503
|
+
/** Storage cap (bytes) on captured file objects, workspace-wide. `null` means unlimited. */
|
|
504
504
|
readonly storageCapBytes?: number | null;
|
|
505
|
-
/** Current captured-
|
|
505
|
+
/** Current captured-file usage in bytes. */
|
|
506
506
|
readonly storageUsedBytes?: number;
|
|
507
507
|
/**
|
|
508
508
|
* Wall-clock ceiling on a single run before forced termination.
|
|
509
509
|
* `null` means no aex-imposed cap, but this is **not unlimited
|
|
510
510
|
* overall**: the managed runner, infrastructure, or upstream provider may
|
|
511
|
-
* still impose a ceiling, and a
|
|
511
|
+
* still impose a ceiling, and a session that exceeds it terminates regardless.
|
|
512
512
|
*/
|
|
513
|
-
readonly
|
|
513
|
+
readonly maxSessionDurationMs?: number | null;
|
|
514
514
|
};
|
|
515
515
|
/**
|
|
516
516
|
* ADDITIVE effective per-workspace limits returned by `GET /whoami` on
|
|
@@ -521,7 +521,7 @@ export interface WhoAmI {
|
|
|
521
521
|
*/
|
|
522
522
|
readonly limits?: {
|
|
523
523
|
/** Effective live-run concurrency cap. One more live run past it fails with `429 workspace_concurrency_exceeded`. */
|
|
524
|
-
readonly
|
|
524
|
+
readonly maxConcurrentSessions: number;
|
|
525
525
|
/** Effective submit-velocity cap per minute; `0` = unlimited (disabled). Past it: `429 workspace_submit_rate_exceeded`. */
|
|
526
526
|
readonly submitRatePerMinute: number;
|
|
527
527
|
/** Effective monthly spend cap in USD; `0` = unlimited. Once `monthSpendUsd` reaches it: `402 workspace_spend_cap_exceeded`. */
|
|
@@ -541,7 +541,7 @@ export interface WhoAmI {
|
|
|
541
541
|
* Workspace skill bundle as the dashboard BFF returns it. Mirrors a row
|
|
542
542
|
* of `skill_bundles` joined with its computed manifest. `state` is the
|
|
543
543
|
* upload lifecycle (`pending` -> `ready`); only `ready` rows are
|
|
544
|
-
* referenceable from a
|
|
544
|
+
* referenceable from a session. Delete is hard; historical sessions keep their
|
|
545
545
|
* submit-time snapshots rather than depending on this row.
|
|
546
546
|
*
|
|
547
547
|
* See the public architecture notes and server-side persistence schema for
|
|
@@ -614,7 +614,7 @@ export interface FileRecord {
|
|
|
614
614
|
* Wire-level metadata record for a workspace skill as returned by the BFF.
|
|
615
615
|
*
|
|
616
616
|
* Workspace skills are named, mutable, by-name-bound bundles: `skill.upload()`
|
|
617
|
-
* upserts one under a stable `name`; a
|
|
617
|
+
* upserts one under a stable `name`; a session references it by that name and the
|
|
618
618
|
* platform resolves it to the CURRENT bytes at submit time. This record is
|
|
619
619
|
* METADATA ONLY — the bytes live in the content-addressed asset store keyed by
|
|
620
620
|
* `contentHash`. `version` bumps each time the bytes change under the name.
|
|
@@ -636,7 +636,7 @@ export interface SkillRecord {
|
|
|
636
636
|
* Wire-level record for a workspace secret as returned by the BFF.
|
|
637
637
|
*
|
|
638
638
|
* Workspace secrets share the lifecycle SEMANTIC of skills/files: a
|
|
639
|
-
* `Secret.value(...)` is per-
|
|
639
|
+
* `Secret.value(...)` is per-session and gone at terminal; PROMOTING it (or
|
|
640
640
|
* `aex.secrets.set`) persists a named, searchable workspace secret. The
|
|
641
641
|
* identity is the `name` (the handle a `Secret.ref` points at); the value
|
|
642
642
|
* rotates under that stable name, bumping `version`.
|
|
@@ -675,7 +675,7 @@ export interface BillingSummary {
|
|
|
675
675
|
readonly balanceUsd: number;
|
|
676
676
|
/** Accrued spend for the current calendar month. */
|
|
677
677
|
readonly monthSpendUsd: number;
|
|
678
|
-
/** Monthly spend cap enforced on new
|
|
678
|
+
/** Monthly spend cap enforced on new sessions. */
|
|
679
679
|
readonly spendCapUsd: number;
|
|
680
680
|
readonly planKey: string;
|
|
681
681
|
readonly subscriptionStatus: string;
|
|
@@ -710,12 +710,12 @@ export interface BillingHostedSession {
|
|
|
710
710
|
*/
|
|
711
711
|
export interface BillingLedgerEntry {
|
|
712
712
|
readonly id: string;
|
|
713
|
-
/** e.g. `top_up`, `
|
|
713
|
+
/** e.g. `top_up`, `session_charge`. Open server vocabulary. */
|
|
714
714
|
readonly entryType: string;
|
|
715
715
|
readonly amountUsd: number;
|
|
716
716
|
readonly currency: string;
|
|
717
|
-
/** The
|
|
718
|
-
readonly
|
|
717
|
+
/** The session this entry charges, `null` for non-run entries. */
|
|
718
|
+
readonly sessionId?: string | null;
|
|
719
719
|
readonly description?: string | null;
|
|
720
720
|
readonly createdBy?: string;
|
|
721
721
|
readonly createdAt: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Project a {@link UsageSummary} from the settle-written
|
|
3
|
-
* {@link
|
|
4
|
-
* usage ({@link
|
|
3
|
+
* {@link SessionCostProviderUsage} entries — the SINGLE server source of token
|
|
4
|
+
* usage ({@link SessionRecord.costTelemetry}`.providerUsage`). Sums each field across all
|
|
5
5
|
* provider entries; a field is present only when at least one entry carried it.
|
|
6
6
|
* This retires the dead `session.usage` / `aex.usage`-event usage path: the SDK
|
|
7
7
|
* derives usage from cost telemetry, never re-reads a dual-written top-level
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AexApiErrorCode } from "./error-codes.js";
|
|
2
|
-
export type AexErrorCode = "
|
|
2
|
+
export type AexErrorCode = "SESSION_CONFIG_INVALID" | "CREDENTIAL_INVALID" | "PROVIDER_ERROR" | "SESSION_STATE_ERROR" | "CLEANUP_ERROR" | "RUNTIME_UNSUPPORTED" | "API_ERROR" | "NETWORK_ERROR";
|
|
3
3
|
export declare class AexError extends Error {
|
|
4
4
|
readonly code: AexErrorCode;
|
|
5
5
|
readonly details?: unknown;
|
|
@@ -7,7 +7,7 @@ export declare class AexError extends Error {
|
|
|
7
7
|
readonly cause?: unknown;
|
|
8
8
|
});
|
|
9
9
|
}
|
|
10
|
-
export declare class
|
|
10
|
+
export declare class SessionConfigValidationError extends AexError {
|
|
11
11
|
constructor(message: string, details?: unknown);
|
|
12
12
|
}
|
|
13
13
|
export declare class CredentialValidationError extends AexError {
|
|
@@ -20,7 +20,7 @@ export declare class ProviderError extends AexError {
|
|
|
20
20
|
details?: unknown;
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
|
-
export declare class
|
|
23
|
+
export declare class SessionStateError extends AexError {
|
|
24
24
|
/**
|
|
25
25
|
* HTTP status from a wrapped API rejection, when this state error is a
|
|
26
26
|
* bounded client-side interpretation of that rejection.
|
|
@@ -10,9 +10,9 @@ export class AexError extends Error {
|
|
|
10
10
|
this.details = details === undefined ? undefined : redactSecrets(details);
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
-
export class
|
|
13
|
+
export class SessionConfigValidationError extends AexError {
|
|
14
14
|
constructor(message, details) {
|
|
15
|
-
super("
|
|
15
|
+
super("SESSION_CONFIG_INVALID", message, details);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
export class CredentialValidationError extends AexError {
|
|
@@ -27,7 +27,7 @@ export class ProviderError extends AexError {
|
|
|
27
27
|
this.status = options.status;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
export class
|
|
30
|
+
export class SessionStateError extends AexError {
|
|
31
31
|
/**
|
|
32
32
|
* HTTP status from a wrapped API rejection, when this state error is a
|
|
33
33
|
* bounded client-side interpretation of that rejection.
|
|
@@ -42,7 +42,7 @@ export class RunStateError extends AexError {
|
|
|
42
42
|
? details
|
|
43
43
|
: undefined;
|
|
44
44
|
const cause = options?.cause ?? detailRecord?.cause;
|
|
45
|
-
super("
|
|
45
|
+
super("SESSION_STATE_ERROR", message, details, cause === undefined ? undefined : { cause });
|
|
46
46
|
const status = detailRecord?.httpStatus ?? detailRecord?.status;
|
|
47
47
|
const apiCode = detailRecord?.apiCode;
|
|
48
48
|
this.status = typeof status === "number" ? status : undefined;
|
|
@@ -55,25 +55,25 @@ const MIN_CHAR_CLASSES = 2;
|
|
|
55
55
|
* A mixed-case run with no digit and < this length is treated as a benign
|
|
56
56
|
* identifier, not a secret. Real opaque secrets are alnum-mixed (carry a
|
|
57
57
|
* digit) or very long; digit-free camelCase identifiers like
|
|
58
|
-
* `
|
|
58
|
+
* `asyncEntryPointWithESMLoader` / `getReadableStreamController` (which
|
|
59
59
|
* appear in stack traces the diagnostic bundle captures) are 24–39 chars and
|
|
60
60
|
* digit-free — eating them would gut debuggability. The length escape hatch
|
|
61
61
|
* still catches the rare long digit-free secret.
|
|
62
62
|
*/
|
|
63
63
|
const HIGH_ENTROPY_NO_DIGIT_MIN_LEN = 40;
|
|
64
64
|
/**
|
|
65
|
-
* Canonical aex
|
|
66
|
-
* by `
|
|
67
|
-
*
|
|
65
|
+
* Canonical aex session-id hex: exactly 32 lowercase hex chars directly preceded
|
|
66
|
+
* by `ses_`. The HIGH_ENTROPY_CANDIDATE class excludes `_`, so the candidate
|
|
67
|
+
* candidate for a session id is the bare hex — dense enough to trip the entropy gate.
|
|
68
68
|
* Masking it destroys the ONE identifier every error message needs for
|
|
69
|
-
* traceability (`cancel via openSession("
|
|
70
|
-
* guidance). A
|
|
69
|
+
* traceability (`cancel via openSession("ses_[REDACTED]")` is useless
|
|
70
|
+
* guidance). A session id is not a credential: it grants nothing without the
|
|
71
71
|
* bearer token. Mirrors the platform-side redactor's canonical-id exemption.
|
|
72
72
|
*/
|
|
73
|
-
function
|
|
73
|
+
function isCanonicalSessionIdHex(input, matchStart, match) {
|
|
74
74
|
if (!/^[0-9a-f]{32}$/.test(match))
|
|
75
75
|
return false;
|
|
76
|
-
return input.slice(Math.max(0, matchStart - 4), matchStart) === "
|
|
76
|
+
return input.slice(Math.max(0, matchStart - 4), matchStart) === "ses_";
|
|
77
77
|
}
|
|
78
78
|
export class SecretString {
|
|
79
79
|
#value;
|
|
@@ -133,7 +133,7 @@ export function redactString(input, known = []) {
|
|
|
133
133
|
// Patterns with a captured prefix (Authorization header) keep the
|
|
134
134
|
// prefix; the rest replace the whole match.
|
|
135
135
|
typeof captured === "string" ? `${captured} ${REDACTED}` : REDACTED), out);
|
|
136
|
-
return out.replace(HIGH_ENTROPY_CANDIDATE, (match, offset, whole) => !
|
|
136
|
+
return out.replace(HIGH_ENTROPY_CANDIDATE, (match, offset, whole) => !isCanonicalSessionIdHex(whole, offset, match) && looksHighEntropySecret(match) ? REDACTED : match);
|
|
137
137
|
}
|
|
138
138
|
export function containsSecretLikeValue(input) {
|
|
139
139
|
if (SECRET_PATTERNS.some((pattern) => {
|
|
@@ -145,7 +145,7 @@ export function containsSecretLikeValue(input) {
|
|
|
145
145
|
HIGH_ENTROPY_CANDIDATE.lastIndex = 0;
|
|
146
146
|
let candidate;
|
|
147
147
|
while ((candidate = HIGH_ENTROPY_CANDIDATE.exec(input)) !== null) {
|
|
148
|
-
if (
|
|
148
|
+
if (isCanonicalSessionIdHex(input, candidate.index, candidate[0])) {
|
|
149
149
|
continue;
|
|
150
150
|
}
|
|
151
151
|
if (looksHighEntropySecret(candidate[0])) {
|