@aexhq/sdk 0.40.8 → 0.40.10

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.
@@ -224,12 +224,12 @@ export declare function download(http: HttpClient, runId: string): Promise<Uint8
224
224
  export declare function downloadOutputs(http: HttpClient, runId: string, options?: OutputTransferOptions): Promise<Uint8Array>;
225
225
  /**
226
226
  * Download only the event archive (the `events` namespace). Always includes
227
- * typed `events.jsonl`.
227
+ * typed `events.jsonl` plus `manifest.json`.
228
228
  */
229
229
  export declare function downloadEvents(http: HttpClient, runId: string): Promise<Uint8Array>;
230
230
  /**
231
231
  * Download only the run record (the `metadata` namespace) as a zip
232
- * containing `run.json`.
232
+ * containing `run.json` plus `manifest.json`.
233
233
  */
234
234
  export declare function downloadMetadata(http: HttpClient, runId: string): Promise<Uint8Array>;
235
235
  export declare function submitRun(http: HttpClient, request: PlatformRunSubmissionInput): Promise<Run>;
@@ -419,7 +419,7 @@ async function readOutputTextWithRetry(http, path, maxBytes, timeoutMs) {
419
419
  }
420
420
  async function downloadOutputResponse(http, path, timeoutMs) {
421
421
  const controller = new AbortController();
422
- const { response } = await withOutputTransferTimeout(http.download(path, { signal: controller.signal }), timeoutMs, () => controller.abort(), "output response");
422
+ const { response } = await withOutputTransferTimeout(http.download(path, { signal: controller.signal }), timeoutMs, () => controller.abort(), "download-open");
423
423
  return response;
424
424
  }
425
425
  async function outputTransferWithRetry(path, timeoutMs, action) {
@@ -439,7 +439,7 @@ async function outputTransferWithRetry(path, timeoutMs, action) {
439
439
  method: "GET",
440
440
  host: "",
441
441
  path,
442
- cause: lastTimeout ?? new OutputTransferTimeoutError("output transfer", timeoutMs),
442
+ cause: lastTimeout ?? new OutputTransferTimeoutError("unknown", timeoutMs),
443
443
  attempts: OUTPUT_FILE_TRANSFER_ATTEMPTS,
444
444
  elapsedMs: Date.now() - startedMs
445
445
  });
@@ -456,18 +456,20 @@ function normalizeOutputTransferTimeoutMs(value) {
456
456
  }
457
457
  class OutputTransferTimeoutError extends Error {
458
458
  code = "ETIMEDOUT";
459
- constructor(label, timeoutMs) {
460
- super(`${label} timed out after ${timeoutMs}ms`);
459
+ phase;
460
+ constructor(phase, timeoutMs) {
461
+ super(`output transfer phase=${phase} timed out after ${timeoutMs}ms`);
461
462
  this.name = "OutputTransferTimeoutError";
463
+ this.phase = phase;
462
464
  }
463
465
  }
464
- async function withOutputTransferTimeout(promise, timeoutMs, abort, label) {
466
+ async function withOutputTransferTimeout(promise, timeoutMs, abort, phase) {
465
467
  let timedOut = false;
466
468
  let timeout;
467
469
  const timeoutPromise = new Promise((_, reject) => {
468
470
  timeout = setTimeout(() => {
469
471
  timedOut = true;
470
- reject(new OutputTransferTimeoutError(label, timeoutMs));
472
+ reject(new OutputTransferTimeoutError(phase, timeoutMs));
471
473
  queueMicrotask(() => {
472
474
  try {
473
475
  abort();
@@ -483,7 +485,7 @@ async function withOutputTransferTimeout(promise, timeoutMs, abort, label) {
483
485
  }
484
486
  catch (err) {
485
487
  if (timedOut && isAbortLikeError(err))
486
- throw new OutputTransferTimeoutError(label, timeoutMs);
488
+ throw new OutputTransferTimeoutError(phase, timeoutMs);
487
489
  throw err;
488
490
  }
489
491
  finally {
@@ -498,7 +500,7 @@ function isAbortLikeError(err) {
498
500
  async function readResponseBytes(response, timeoutMs) {
499
501
  const body = response.body;
500
502
  if (!body) {
501
- const buffer = await withOutputTransferTimeout(response.arrayBuffer(), timeoutMs, () => { }, "output body");
503
+ const buffer = await withOutputTransferTimeout(response.arrayBuffer(), timeoutMs, () => { }, "body-read");
502
504
  return new Uint8Array(buffer);
503
505
  }
504
506
  const reader = body.getReader();
@@ -507,7 +509,7 @@ async function readResponseBytes(response, timeoutMs) {
507
509
  while (true) {
508
510
  const { done, value } = await withOutputTransferTimeout(reader.read(), timeoutMs, () => {
509
511
  void reader.cancel().catch(() => { });
510
- }, "output body");
512
+ }, "body-read");
511
513
  if (done)
512
514
  break;
513
515
  if (value && value.byteLength > 0)
@@ -532,7 +534,7 @@ async function readCappedText(response, maxBytes, timeoutMs) {
532
534
  const body = response.body;
533
535
  if (!body) {
534
536
  // No streaming body (some fetch polyfills) — buffer, then slice to the cap.
535
- const buf = new Uint8Array(await withOutputTransferTimeout(response.arrayBuffer(), timeoutMs, () => { }, "output body"));
537
+ const buf = new Uint8Array(await withOutputTransferTimeout(response.arrayBuffer(), timeoutMs, () => { }, "body-read"));
536
538
  const total = declared ?? buf.byteLength;
537
539
  return {
538
540
  text: decoder.decode(buf.subarray(0, maxBytes)),
@@ -548,7 +550,7 @@ async function readCappedText(response, maxBytes, timeoutMs) {
548
550
  while (read < maxBytes) {
549
551
  const { done, value } = await withOutputTransferTimeout(reader.read(), timeoutMs, () => {
550
552
  void reader.cancel().catch(() => { });
551
- }, "output body");
553
+ }, "body-read");
552
554
  if (done)
553
555
  break;
554
556
  if (value && value.byteLength > 0) {
@@ -560,7 +562,7 @@ async function readCappedText(response, maxBytes, timeoutMs) {
560
562
  // We hit the cap; peek once more to learn whether bytes remain, then stop.
561
563
  const next = await withOutputTransferTimeout(reader.read(), timeoutMs, () => {
562
564
  void reader.cancel().catch(() => { });
563
- }, "output body");
565
+ }, "body-read");
564
566
  if (!next.done && next.value && next.value.byteLength > 0)
565
567
  sawMore = true;
566
568
  }
@@ -978,19 +980,35 @@ export async function downloadOutputs(http, runId, options) {
978
980
  }
979
981
  /**
980
982
  * Download only the event archive (the `events` namespace). Always includes
981
- * typed `events.jsonl`.
983
+ * typed `events.jsonl` plus `manifest.json`.
982
984
  */
983
985
  export async function downloadEvents(http, runId) {
984
986
  const events = await listRunEvents(http, runId);
985
- return zipEntries([jsonlEntry("events.jsonl", events)]);
987
+ return zipEntries([
988
+ jsonlEntry("events.jsonl", events),
989
+ jsonEntry("manifest.json", {
990
+ runId,
991
+ namespace: "events",
992
+ files: [{ path: "events.jsonl", role: "typed_events", status: "present", recordCount: events.length }],
993
+ errors: []
994
+ })
995
+ ]);
986
996
  }
987
997
  /**
988
998
  * Download only the run record (the `metadata` namespace) as a zip
989
- * containing `run.json`.
999
+ * containing `run.json` plus `manifest.json`.
990
1000
  */
991
1001
  export async function downloadMetadata(http, runId) {
992
1002
  const run = await getRun(http, runId);
993
- return zipEntries([jsonEntry("run.json", run)]);
1003
+ return zipEntries([
1004
+ jsonEntry("run.json", run),
1005
+ jsonEntry("manifest.json", {
1006
+ runId,
1007
+ namespace: "metadata",
1008
+ files: [{ path: "run.json", role: "run_metadata", status: "present" }],
1009
+ errors: []
1010
+ })
1011
+ ]);
994
1012
  }
995
1013
  function zipEntries(entries) {
996
1014
  assertRunRecordArchivePublicSafeV1(entries);
package/dist/cli.mjs CHANGED
@@ -3357,7 +3357,7 @@ async function readOutputTextWithRetry(http, path, maxBytes, timeoutMs) {
3357
3357
  }
3358
3358
  async function downloadOutputResponse(http, path, timeoutMs) {
3359
3359
  const controller = new AbortController();
3360
- const { response } = await withOutputTransferTimeout(http.download(path, { signal: controller.signal }), timeoutMs, () => controller.abort(), "output response");
3360
+ const { response } = await withOutputTransferTimeout(http.download(path, { signal: controller.signal }), timeoutMs, () => controller.abort(), "download-open");
3361
3361
  return response;
3362
3362
  }
3363
3363
  async function outputTransferWithRetry(path, timeoutMs, action) {
@@ -3376,7 +3376,7 @@ async function outputTransferWithRetry(path, timeoutMs, action) {
3376
3376
  method: "GET",
3377
3377
  host: "",
3378
3378
  path,
3379
- cause: lastTimeout ?? new OutputTransferTimeoutError("output transfer", timeoutMs),
3379
+ cause: lastTimeout ?? new OutputTransferTimeoutError("unknown", timeoutMs),
3380
3380
  attempts: OUTPUT_FILE_TRANSFER_ATTEMPTS,
3381
3381
  elapsedMs: Date.now() - startedMs
3382
3382
  });
@@ -3393,18 +3393,20 @@ function normalizeOutputTransferTimeoutMs(value) {
3393
3393
  }
3394
3394
  var OutputTransferTimeoutError = class extends Error {
3395
3395
  code = "ETIMEDOUT";
3396
- constructor(label, timeoutMs) {
3397
- super(`${label} timed out after ${timeoutMs}ms`);
3396
+ phase;
3397
+ constructor(phase, timeoutMs) {
3398
+ super(`output transfer phase=${phase} timed out after ${timeoutMs}ms`);
3398
3399
  this.name = "OutputTransferTimeoutError";
3400
+ this.phase = phase;
3399
3401
  }
3400
3402
  };
3401
- async function withOutputTransferTimeout(promise, timeoutMs, abort, label) {
3403
+ async function withOutputTransferTimeout(promise, timeoutMs, abort, phase) {
3402
3404
  let timedOut = false;
3403
3405
  let timeout;
3404
3406
  const timeoutPromise = new Promise((_, reject) => {
3405
3407
  timeout = setTimeout(() => {
3406
3408
  timedOut = true;
3407
- reject(new OutputTransferTimeoutError(label, timeoutMs));
3409
+ reject(new OutputTransferTimeoutError(phase, timeoutMs));
3408
3410
  queueMicrotask(() => {
3409
3411
  try {
3410
3412
  abort();
@@ -3417,7 +3419,7 @@ async function withOutputTransferTimeout(promise, timeoutMs, abort, label) {
3417
3419
  return await Promise.race([promise, timeoutPromise]);
3418
3420
  } catch (err2) {
3419
3421
  if (timedOut && isAbortLikeError(err2))
3420
- throw new OutputTransferTimeoutError(label, timeoutMs);
3422
+ throw new OutputTransferTimeoutError(phase, timeoutMs);
3421
3423
  throw err2;
3422
3424
  } finally {
3423
3425
  if (timeout !== void 0)
@@ -3432,7 +3434,7 @@ async function readResponseBytes(response, timeoutMs) {
3432
3434
  const body = response.body;
3433
3435
  if (!body) {
3434
3436
  const buffer = await withOutputTransferTimeout(response.arrayBuffer(), timeoutMs, () => {
3435
- }, "output body");
3437
+ }, "body-read");
3436
3438
  return new Uint8Array(buffer);
3437
3439
  }
3438
3440
  const reader = body.getReader();
@@ -3442,7 +3444,7 @@ async function readResponseBytes(response, timeoutMs) {
3442
3444
  const { done, value } = await withOutputTransferTimeout(reader.read(), timeoutMs, () => {
3443
3445
  void reader.cancel().catch(() => {
3444
3446
  });
3445
- }, "output body");
3447
+ }, "body-read");
3446
3448
  if (done)
3447
3449
  break;
3448
3450
  if (value && value.byteLength > 0)
@@ -3461,7 +3463,7 @@ async function readCappedText(response, maxBytes, timeoutMs) {
3461
3463
  const body = response.body;
3462
3464
  if (!body) {
3463
3465
  const buf = new Uint8Array(await withOutputTransferTimeout(response.arrayBuffer(), timeoutMs, () => {
3464
- }, "output body"));
3466
+ }, "body-read"));
3465
3467
  const total = declared ?? buf.byteLength;
3466
3468
  return {
3467
3469
  text: decoder.decode(buf.subarray(0, maxBytes)),
@@ -3478,7 +3480,7 @@ async function readCappedText(response, maxBytes, timeoutMs) {
3478
3480
  const { done, value } = await withOutputTransferTimeout(reader.read(), timeoutMs, () => {
3479
3481
  void reader.cancel().catch(() => {
3480
3482
  });
3481
- }, "output body");
3483
+ }, "body-read");
3482
3484
  if (done)
3483
3485
  break;
3484
3486
  if (value && value.byteLength > 0) {
@@ -3490,7 +3492,7 @@ async function readCappedText(response, maxBytes, timeoutMs) {
3490
3492
  const next = await withOutputTransferTimeout(reader.read(), timeoutMs, () => {
3491
3493
  void reader.cancel().catch(() => {
3492
3494
  });
3493
- }, "output body");
3495
+ }, "body-read");
3494
3496
  if (!next.done && next.value && next.value.byteLength > 0)
3495
3497
  sawMore = true;
3496
3498
  }
@@ -3814,11 +3816,27 @@ async function downloadOutputs(http, runId, options) {
3814
3816
  }
3815
3817
  async function downloadEvents(http, runId) {
3816
3818
  const events = await listRunEvents(http, runId);
3817
- return zipEntries([jsonlEntry("events.jsonl", events)]);
3819
+ return zipEntries([
3820
+ jsonlEntry("events.jsonl", events),
3821
+ jsonEntry("manifest.json", {
3822
+ runId,
3823
+ namespace: "events",
3824
+ files: [{ path: "events.jsonl", role: "typed_events", status: "present", recordCount: events.length }],
3825
+ errors: []
3826
+ })
3827
+ ]);
3818
3828
  }
3819
3829
  async function downloadMetadata(http, runId) {
3820
3830
  const run = await getRun(http, runId);
3821
- return zipEntries([jsonEntry("run.json", run)]);
3831
+ return zipEntries([
3832
+ jsonEntry("run.json", run),
3833
+ jsonEntry("manifest.json", {
3834
+ runId,
3835
+ namespace: "metadata",
3836
+ files: [{ path: "run.json", role: "run_metadata", status: "present" }],
3837
+ errors: []
3838
+ })
3839
+ ]);
3822
3840
  }
3823
3841
  function zipEntries(entries) {
3824
3842
  assertRunRecordArchivePublicSafeV1(entries);
@@ -1 +1 @@
1
- cdab07311ba092bc586f1d536208b0ca762c2014ddfb8f4219beb21a6302b59b cli.mjs
1
+ feca3311d49affc9dd305e9c1a8da4faee1c604662ebb34abc142c8f1276635c cli.mjs
package/dist/version.d.ts CHANGED
@@ -6,4 +6,4 @@
6
6
  *
7
7
  * Used by the (future) User-Agent header on outbound SDK requests.
8
8
  */
9
- export declare const SDK_VERSION = "0.40.8";
9
+ export declare const SDK_VERSION = "0.40.10";
package/dist/version.js CHANGED
@@ -6,5 +6,5 @@
6
6
  *
7
7
  * Used by the (future) User-Agent header on outbound SDK requests.
8
8
  */
9
- export const SDK_VERSION = "0.40.8";
9
+ export const SDK_VERSION = "0.40.10";
10
10
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC"}
package/docs/outputs.md CHANGED
@@ -38,8 +38,8 @@ A session's downloadable content is organised into three logical namespaces, eac
38
38
  | Namespace | What it holds | Verb | CLI |
39
39
  | --- | --- | --- | --- |
40
40
  | `outputs` | The session's real deliverables. | `session.outputs().download()` | `download <id> --only outputs` |
41
- | `events` | Typed event-channel records (`events.jsonl`). | `session.events().download()` | `download <id> --only events` |
42
- | `metadata` | The session record (`run.json`). | `session.downloadMetadata()` | `download <id> --only metadata` |
41
+ | `events` | Typed event-channel records (`events.jsonl`) plus a namespace manifest. | `session.events().download()` | `download <id> --only events` |
42
+ | `metadata` | The session record (`run.json`) plus a namespace manifest. | `session.downloadMetadata()` | `download <id> --only metadata` |
43
43
 
44
44
  Platform diagnostics are stored outside the public archive under `runs/<runId>/internal/logs/` for internal/admin access only. They are not exposed by the SDK download helpers or the public CLI.
45
45
 
@@ -66,7 +66,7 @@ manifest.json # RunRecordManifestV1
66
66
  | `outputs[]` | `{ id, filename, sizeBytes?, contentType? }` — one row per file successfully written under `outputs/`. |
67
67
  | `errors[]` | `{ namespace, id, filename, message }` — per-artifact byte fetches that failed during assembly. Best-effort: a failure records an entry here and is skipped from the tree rather than aborting the whole zip. |
68
68
 
69
- The single-namespace verbs return the same per-file bytes at the zip root (e.g. `session.outputs().download()` -> `report.txt` + a `manifest.json`; `session.events().download()` -> `events.jsonl`).
69
+ The single-namespace verbs return the same per-file bytes at the zip root (e.g. `session.outputs().download()` -> `report.txt` + `manifest.json`; `session.events().download()` -> `events.jsonl` + `manifest.json`; `session.downloadMetadata()` -> `run.json` + `manifest.json`).
70
70
 
71
71
  ## Downloading one output
72
72
 
@@ -253,7 +253,7 @@ Capture notes:
253
253
 
254
254
  ## Runs without explicit `outputs.allowedDirs`
255
255
 
256
- Metadata still gets the full treatment. aex captures every regular file the run created or modified outside mandatory platform excludes. A run that produces no files still returns a zip with `run.json`, `events.jsonl`, and an empty `outputs/` directory (manifest `outputs: []`).
256
+ Metadata still gets the full treatment. aex captures every regular file the run created or modified outside mandatory platform excludes. A run that produces no files still returns a whole-session zip with `metadata/run.json`, `events/events.jsonl`, and `manifest.json` (manifest `outputs: []`).
257
257
 
258
258
  ## Mid-session download semantics
259
259
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aexhq/sdk",
3
- "version": "0.40.8",
3
+ "version": "0.40.10",
4
4
  "description": "TypeScript SDK for running autonomous agent sessions across providers (Anthropic, OpenAI, DeepSeek, Gemini, Mistral) behind one interface.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {