@aexhq/sdk 0.13.7 → 0.13.8

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 (51) hide show
  1. package/README.md +14 -14
  2. package/dist/_contracts/connection-ticket.d.ts +8 -7
  3. package/dist/_contracts/connection-ticket.js +20 -14
  4. package/dist/_contracts/event-envelope.d.ts +17 -18
  5. package/dist/_contracts/event-envelope.js +10 -11
  6. package/dist/_contracts/managed-key.d.ts +27 -1
  7. package/dist/_contracts/managed-key.js +75 -4
  8. package/dist/_contracts/operations.d.ts +9 -20
  9. package/dist/_contracts/operations.js +33 -82
  10. package/dist/_contracts/proxy-protocol.d.ts +35 -2
  11. package/dist/_contracts/proxy-protocol.js +34 -1
  12. package/dist/_contracts/run-artifacts.d.ts +12 -10
  13. package/dist/_contracts/run-artifacts.js +13 -11
  14. package/dist/_contracts/run-config.d.ts +7 -0
  15. package/dist/_contracts/run-config.js +93 -24
  16. package/dist/_contracts/run-custody.d.ts +3 -3
  17. package/dist/_contracts/run-custody.js +5 -5
  18. package/dist/_contracts/run-record.d.ts +5 -17
  19. package/dist/_contracts/run-record.js +4 -15
  20. package/dist/_contracts/run-retention.d.ts +2 -2
  21. package/dist/_contracts/run-retention.js +3 -3
  22. package/dist/_contracts/run-unit.d.ts +4 -5
  23. package/dist/_contracts/runner-event.d.ts +7 -8
  24. package/dist/_contracts/runner-event.js +7 -8
  25. package/dist/_contracts/side-effect-audit.d.ts +2 -2
  26. package/dist/_contracts/side-effect-audit.js +3 -3
  27. package/dist/_contracts/stable.d.ts +1 -1
  28. package/dist/_contracts/stable.js +1 -1
  29. package/dist/_contracts/submission.d.ts +5 -6
  30. package/dist/_contracts/submission.js +1 -1
  31. package/dist/cli.mjs +127 -127
  32. package/dist/cli.mjs.sha256 +1 -1
  33. package/dist/client.d.ts +7 -57
  34. package/dist/client.js +302 -167
  35. package/dist/client.js.map +1 -1
  36. package/dist/index.d.ts +3 -3
  37. package/dist/index.js +2 -2
  38. package/dist/index.js.map +1 -1
  39. package/dist/version.d.ts +1 -1
  40. package/dist/version.js +1 -1
  41. package/docs/cleanup.md +4 -4
  42. package/docs/credentials.md +5 -5
  43. package/docs/events.md +5 -5
  44. package/docs/outputs.md +23 -25
  45. package/docs/product-boundaries.md +5 -5
  46. package/docs/provider-runtime-capabilities.md +1 -1
  47. package/docs/quickstart.md +12 -12
  48. package/docs/run-config.md +1 -1
  49. package/docs/run-record.md +6 -9
  50. package/docs/skills.md +23 -25
  51. package/package.json +2 -2
package/dist/cli.mjs CHANGED
@@ -10,8 +10,14 @@ import { readFile as readFile2, writeFile, readdir as readdir2, stat as stat2 }
10
10
  import { resolve as resolvePath4 } from "node:path";
11
11
 
12
12
  // ../contracts/dist/proxy-protocol.js
13
- var PROXY_PROTOCOL_VERSION = "1";
13
+ var PROXY_PROTOCOL_VERSION_V2 = "2";
14
14
  var PROXY_PROTOCOL_HEADER = "x-aex-proxy-protocol";
15
+ var PROXY_RESP_STATUS_HEADER = "x-aex-proxy-status";
16
+ var PROXY_RESP_MODE_HEADER = "x-aex-proxy-effective-mode";
17
+ var PROXY_RESP_TRUNCATED_HEADER = "x-aex-proxy-truncated";
18
+ var PROXY_RESP_REMAINING_CALLS_HEADER = "x-aex-proxy-remaining-calls";
19
+ var PROXY_RESP_REMAINING_BYTES_HEADER = "x-aex-proxy-remaining-bytes";
20
+ var PROXY_RESP_UPSTREAM_HEADERS_HEADER = "x-aex-proxy-upstream-headers";
15
21
  var PROXY_METHOD_HEADER = "x-aex-method";
16
22
  var PROXY_PATH_HEADER = "x-aex-path";
17
23
  var PROXY_QUERY_HEADER = "x-aex-query";
@@ -114,6 +120,13 @@ var terminalRunStatuses = new Set(TERMINAL_RUN_STATUSES);
114
120
  var SKILL_BUNDLE_LIMITS = {
115
121
  /** Compressed (.zip) ceiling. */
116
122
  maxCompressedBytes: 10 * 1024 * 1024,
123
+ /**
124
+ * Hard ceiling for the direct-to-storage (presigned PUT) upload path, where
125
+ * bytes never transit the hosted API so its memory/request-payload limits no
126
+ * longer cap the bundle. Kept well under the object store's 5 GiB single-PUT
127
+ * limit; objects above this would need S3 multipart, which is out of scope.
128
+ */
129
+ maxBytes: 2 * 1024 * 1024 * 1024,
117
130
  /** Sum of uncompressed file sizes. */
118
131
  maxDecompressedBytes: 50 * 1024 * 1024,
119
132
  /** Number of regular file entries (directories don't count). */
@@ -302,32 +315,63 @@ function rejectStdioMcpShape(record) {
302
315
  }
303
316
  }
304
317
  }
305
- function denyReasonForMcpHost(parsed) {
306
- const host = parsed.hostname.toLowerCase().replace(/^\[|\]$/g, "");
307
- if (host === "localhost" || host.endsWith(".localhost")) {
308
- return "must not target a loopback hostname";
318
+ function denyReasonForHostIp(host) {
319
+ const mappedDotted = /^::(?:ffff:)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/.exec(host);
320
+ if (mappedDotted) {
321
+ return denyReasonForV4(mappedDotted[1]);
309
322
  }
310
- if (/^127(?:\.[0-9]+){3}$/.test(host)) {
311
- return "must not target loopback IPv4 (127.0.0.0/8)";
323
+ const mappedHex = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(host);
324
+ if (mappedHex) {
325
+ const hi = Number.parseInt(mappedHex[1], 16);
326
+ const lo = Number.parseInt(mappedHex[2], 16);
327
+ const dotted = `${hi >> 8}.${hi & 255}.${lo >> 8}.${lo & 255}`;
328
+ return denyReasonForV4(dotted);
312
329
  }
330
+ const v4 = denyReasonForV4(host);
331
+ if (v4)
332
+ return v4;
313
333
  if (host === "::1" || host === "0:0:0:0:0:0:0:1") {
314
334
  return "must not target loopback IPv6 (::1)";
315
335
  }
316
336
  if (/^fe[89ab][0-9a-f]?:/.test(host)) {
317
337
  return "must not target link-local IPv6 (fe80::/10)";
318
338
  }
319
- if (/^169\.254\.[0-9]+\.[0-9]+$/.test(host)) {
339
+ if (/^f[cd][0-9a-f]{0,2}:/.test(host)) {
340
+ return "must not target unique-local IPv6 (fc00::/7)";
341
+ }
342
+ return null;
343
+ }
344
+ function denyReasonForV4(host) {
345
+ if (!/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host))
346
+ return null;
347
+ const octets = host.split(".").map((o) => Number.parseInt(o, 10));
348
+ if (octets.some((o) => o > 255))
349
+ return null;
350
+ const [a, b] = octets;
351
+ if (a === 127)
352
+ return "must not target loopback IPv4 (127.0.0.0/8)";
353
+ if (a === 169 && b === 254) {
320
354
  return "must not target link-local IPv4 (169.254.0.0/16) \u2014 cloud metadata range";
321
355
  }
322
- if (/^10\.[0-9]+\.[0-9]+\.[0-9]+$/.test(host)) {
323
- return "must not target RFC1918 IPv4 (10.0.0.0/8)";
356
+ if (a === 100 && b >= 64 && b <= 127) {
357
+ return "must not target CGNAT IPv4 (100.64.0.0/10)";
324
358
  }
325
- if (/^172\.(1[6-9]|2[0-9]|3[01])\.[0-9]+\.[0-9]+$/.test(host)) {
359
+ if (a === 10)
360
+ return "must not target RFC1918 IPv4 (10.0.0.0/8)";
361
+ if (a === 172 && b >= 16 && b <= 31)
326
362
  return "must not target RFC1918 IPv4 (172.16.0.0/12)";
327
- }
328
- if (/^192\.168\.[0-9]+\.[0-9]+$/.test(host)) {
363
+ if (a === 192 && b === 168)
329
364
  return "must not target RFC1918 IPv4 (192.168.0.0/16)";
365
+ return null;
366
+ }
367
+ function denyReasonForMcpHost(parsed) {
368
+ const host = parsed.hostname.toLowerCase().replace(/^\[|\]$/g, "");
369
+ if (host === "localhost" || host.endsWith(".localhost")) {
370
+ return "must not target a loopback hostname";
330
371
  }
372
+ const ipDenial = denyReasonForHostIp(host);
373
+ if (ipDenial)
374
+ return ipDenial;
331
375
  if (parsed.protocol === "https:" && parsed.port !== "" && parsed.port !== "443") {
332
376
  return `must use port 443 for https (got ${parsed.port})`;
333
377
  }
@@ -544,7 +588,7 @@ var BLOCKED_MANAGED_KEY_POLICY_V1 = Object.freeze({
544
588
  schemaVersion: MANAGED_KEY_POLICY_SCHEMA_VERSION,
545
589
  credentialMode: "managed",
546
590
  launchStage: "blocked",
547
- serviceAvailable: false,
591
+ privateImplementationAvailable: false,
548
592
  billingRequired: true,
549
593
  providers: Object.freeze([]),
550
594
  runtimes: Object.freeze([]),
@@ -624,7 +668,7 @@ var forbiddenStringPatterns = Object.freeze([
624
668
  regex: /\b(?:sk-(?:ant|proj|live|test|deepseek|openai)|xox[baprs]-|AIza)[A-Za-z0-9_-]{8,}/i
625
669
  },
626
670
  { reason: "signed_url", regex: /[?&](?:X-Amz-Signature|X-Amz-Credential|X-Amz-Algorithm|AWSAccessKeyId)=/i },
627
- { reason: "r2_object_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
671
+ { reason: "object_store_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
628
672
  { reason: "vault_id", regex: /\b(?:vault|vlt|secret)[_:-][A-Za-z0-9][A-Za-z0-9_-]{7,}\b/i },
629
673
  {
630
674
  reason: "private_resource_handle",
@@ -633,7 +677,7 @@ var forbiddenStringPatterns = Object.freeze([
633
677
  { reason: "high_entropy_token", regex: /\b(?=[A-Za-z0-9_-]{40,}\b)(?=.*[A-Za-z])(?=.*\d)[A-Za-z0-9_-]{40,}\b/ }
634
678
  ]);
635
679
  function isForbiddenCustodyFieldName(key) {
636
- return /^(apiKey|secretValue|bearerHash|signedUrl|r2Key|objectKey|vaultId|providerResponseBody|responseBody|privateResourceHandle|resourceHandle|rawBody)$/i.test(key);
680
+ return /^(apiKey|secretValue|bearerHash|signedUrl|objectStoreKey|objectKey|vaultId|providerResponseBody|responseBody|privateResourceHandle|resourceHandle|rawBody)$/i.test(key);
637
681
  }
638
682
 
639
683
  // ../contracts/dist/run-record.js
@@ -650,7 +694,6 @@ var RunRecordArchiveRedactionError = class extends Error {
650
694
  };
651
695
  function buildRunRecordDownloadManifestV1(input) {
652
696
  const outputs = input.outputs.map((file2) => normalizeArtifactSummary(file2));
653
- const logs = input.logs.map((file2) => normalizeArtifactSummary(file2));
654
697
  const errors = (input.errors ?? []).map((error) => Object.freeze({ ...error }));
655
698
  return Object.freeze({
656
699
  schemaVersion: RUN_RECORD_MANIFEST_SCHEMA_VERSION,
@@ -658,9 +701,8 @@ function buildRunRecordDownloadManifestV1(input) {
658
701
  runId: input.runId,
659
702
  namespaces: Object.freeze([
660
703
  namespace("metadata", "Run metadata, submission snapshot, custody, and cost files."),
661
- namespace("events", "Typed event-channel exports and optional full-stream/log-channel exports."),
662
- namespace("outputs", "Captured deliverables produced by the run."),
663
- namespace("logs", "Platform diagnostics and runtime log artifacts.")
704
+ namespace("events", "Typed event-channel exports."),
705
+ namespace("outputs", "Captured deliverables produced by the run.")
664
706
  ]),
665
707
  files: Object.freeze([
666
708
  file("metadata", "metadata/run.json", "run_metadata", "present"),
@@ -670,14 +712,10 @@ function buildRunRecordDownloadManifestV1(input) {
670
712
  file("events", "events/events.jsonl", "typed_events", "present", {
671
713
  recordCount: input.typedEventCount ?? 0
672
714
  }),
673
- file("events", "events/logs.jsonl", "log_events", input.logEvents?.status ?? "unavailable", recordCountExtra(input.logEvents)),
674
- file("events", "events/all.jsonl", "all_events", input.allEvents?.status ?? "unavailable", recordCountExtra(input.allEvents)),
675
715
  file("events", "events/manifest.json", "coordinator_events_manifest", input.coordinatorEventsManifest?.status ?? "unavailable"),
676
- ...outputs.map((output) => artifactFile("outputs", "output", "outputs/", output)),
677
- ...logs.map((log) => artifactFile("logs", "log", "logs/", log))
716
+ ...outputs.map((output) => artifactFile("outputs", "output", "outputs/", output))
678
717
  ]),
679
718
  outputs: Object.freeze(outputs),
680
- logs: Object.freeze(logs),
681
719
  errors: Object.freeze(errors)
682
720
  });
683
721
  }
@@ -698,9 +736,6 @@ function file(namespaceName, path, role, status, extra) {
698
736
  ...extra?.recordCount !== void 0 ? { recordCount: extra.recordCount } : {}
699
737
  });
700
738
  }
701
- function recordCountExtra(input) {
702
- return input?.status === "present" && input.recordCount !== void 0 ? { recordCount: input.recordCount } : void 0;
703
- }
704
739
  function artifactFile(namespaceName, role, prefix, artifact) {
705
740
  return Object.freeze({
706
741
  namespace: namespaceName,
@@ -767,7 +802,7 @@ function isAllowedArchiveHighEntropyField(entryPath, finding) {
767
802
  if (finding.reason !== "high_entropy_token" || !entryPath.endsWith("manifest.json")) {
768
803
  return false;
769
804
  }
770
- return /^\$(?:\.files\[\d+\]|\.outputs\[\d+\]|\.logs\[\d+\])\.id$/.test(finding.path);
805
+ return /^\$(?:\.files\[\d+\]|\.outputs\[\d+\])\.id$/.test(finding.path);
771
806
  }
772
807
  function parseArchiveTextValues(path, text) {
773
808
  if (/\.json$/i.test(path)) {
@@ -806,7 +841,7 @@ function formatArchiveFindingPaths(findings) {
806
841
  // ../contracts/dist/run-retention.js
807
842
  var forbiddenStringPatterns2 = Object.freeze([
808
843
  { reason: "signed_url", regex: /[?&](?:X-Amz-Signature|X-Amz-Credential|X-Amz-Algorithm|AWSAccessKeyId)=/i },
809
- { reason: "r2_object_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
844
+ { reason: "object_store_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
810
845
  { reason: "vault_id", regex: /\b(?:vault|vlt|secret)[_:-][A-Za-z0-9][A-Za-z0-9_-]{7,}\b/i },
811
846
  {
812
847
  reason: "private_resource_handle",
@@ -823,7 +858,7 @@ var forbiddenStringPatterns3 = Object.freeze([
823
858
  regex: /\b(?:sk-(?:ant|proj|live|test|deepseek|openai)|xox[baprs]-|AIza)[A-Za-z0-9_-]{8,}/i
824
859
  },
825
860
  { reason: "signed_url", regex: /[?&](?:X-Amz-Signature|X-Amz-Credential|X-Amz-Algorithm|AWSAccessKeyId)=/i },
826
- { reason: "r2_object_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
861
+ { reason: "object_store_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
827
862
  { reason: "vault_id", regex: /\b(?:vault|vlt|secret)[_:-][A-Za-z0-9][A-Za-z0-9_-]{7,}\b/i },
828
863
  {
829
864
  reason: "private_resource_handle",
@@ -1062,39 +1097,6 @@ function extractErrorMessage(body) {
1062
1097
  return "aex API request failed";
1063
1098
  }
1064
1099
 
1065
- // ../contracts/dist/run-artifacts.js
1066
- function runArtifactRel(rel) {
1067
- if (rel.startsWith(".runtime-logs/"))
1068
- return `runtime/${rel.slice(".runtime-logs/".length)}`;
1069
- if (rel.startsWith("runtime/"))
1070
- return rel;
1071
- if (rel.startsWith(".host-logs/"))
1072
- return `host/${rel.slice(".host-logs/".length)}`;
1073
- if (rel.startsWith("host/"))
1074
- return rel;
1075
- if (rel.startsWith(".provider-proxy/"))
1076
- return `provider-proxy/${rel.slice(".provider-proxy/".length)}`;
1077
- if (rel.startsWith("provider-proxy/"))
1078
- return rel;
1079
- if (rel.startsWith(".control-plane/"))
1080
- return `control-plane/${rel.slice(".control-plane/".length)}`;
1081
- if (rel.startsWith("control-plane/"))
1082
- return rel;
1083
- if (rel.startsWith(".goose-logs/"))
1084
- return `runtime/${rel.slice(".goose-logs/".length)}`;
1085
- if (rel.startsWith("goose-logs/"))
1086
- return `runtime/${rel.slice("goose-logs/".length)}`;
1087
- if (rel.startsWith(".fly-logs/"))
1088
- return `host/${rel.slice(".fly-logs/".length)}`;
1089
- if (rel.startsWith("fly-logs/"))
1090
- return `host/${rel.slice("fly-logs/".length)}`;
1091
- if (rel.startsWith(".anthropic-debug/"))
1092
- return `provider-proxy/${rel.slice(".anthropic-debug/".length)}`;
1093
- if (rel.startsWith("anthropic-debug/"))
1094
- return `provider-proxy/${rel.slice("anthropic-debug/".length)}`;
1095
- return rel;
1096
- }
1097
-
1098
1100
  // ../contracts/dist/operations.js
1099
1101
  var operations_exports = {};
1100
1102
  __export(operations_exports, {
@@ -1111,7 +1113,6 @@ __export(operations_exports, {
1111
1113
  deleteWorkspaceAsset: () => deleteWorkspaceAsset,
1112
1114
  download: () => download,
1113
1115
  downloadEvents: () => downloadEvents,
1114
- downloadLogs: () => downloadLogs,
1115
1116
  downloadMetadata: () => downloadMetadata,
1116
1117
  downloadOutput: () => downloadOutput,
1117
1118
  downloadOutputs: () => downloadOutputs,
@@ -1125,7 +1126,6 @@ __export(operations_exports, {
1125
1126
  getSkill: () => getSkill,
1126
1127
  listAgentsMd: () => listAgentsMd,
1127
1128
  listFiles: () => listFiles,
1128
- listLogs: () => listLogs,
1129
1129
  listOutputs: () => listOutputs,
1130
1130
  listRunEvents: () => listRunEvents,
1131
1131
  listSkills: () => listSkills,
@@ -1860,10 +1860,20 @@ async function getRun(http, runId) {
1860
1860
  async function getRunUnit(http, runId) {
1861
1861
  return http.request(`/api/runs/${encodeURIComponent(runId)}`);
1862
1862
  }
1863
- async function listRunEvents(http, runId, options = {}) {
1864
- const query = options.channel && options.channel !== "event" ? { channel: options.channel } : {};
1865
- const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/events`, {}, query);
1866
- return result.events;
1863
+ var LIST_EVENTS_PAGE_BUDGET = 1e3;
1864
+ async function listRunEvents(http, runId) {
1865
+ const path = `/api/runs/${encodeURIComponent(runId)}/events`;
1866
+ const all = [];
1867
+ let cursor;
1868
+ for (let page = 0; page < LIST_EVENTS_PAGE_BUDGET; page++) {
1869
+ const query = cursor !== void 0 ? { cursor: String(cursor) } : {};
1870
+ const result = await http.request(path, {}, query);
1871
+ all.push(...result.events);
1872
+ if (typeof result.nextCursor !== "number")
1873
+ break;
1874
+ cursor = result.nextCursor;
1875
+ }
1876
+ return all;
1867
1877
  }
1868
1878
  async function getCoordinatorTicket(http, runId) {
1869
1879
  return http.request(`/api/runs/${encodeURIComponent(runId)}/events/ticket`, { method: "POST" });
@@ -1872,10 +1882,6 @@ async function listOutputs(http, runId) {
1872
1882
  const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/outputs`);
1873
1883
  return result.outputs;
1874
1884
  }
1875
- async function listLogs(http, runId) {
1876
- const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/logs`);
1877
- return result.logs.map((log) => typeof log.filename === "string" ? { ...log, filename: runArtifactRel(log.filename) } : log);
1878
- }
1879
1885
  async function createOutputLink(http, runId, outputId) {
1880
1886
  return http.request(`/api/runs/${encodeURIComponent(runId)}/outputs/${encodeURIComponent(outputId)}/link`, { method: "POST" });
1881
1887
  }
@@ -1939,7 +1945,7 @@ async function collectArtifactBytes(http, runId, items, zipPrefix, namespace2) {
1939
1945
  path: `${zipPrefix}${rel}`,
1940
1946
  bytes: new Uint8Array(await response.arrayBuffer()),
1941
1947
  ...item.contentType !== void 0 ? { contentType: item.contentType } : {},
1942
- ...namespace2 === "outputs" ? { customerContent: true } : {}
1948
+ customerContent: true
1943
1949
  });
1944
1950
  captured.push({
1945
1951
  id: item.id,
@@ -1956,23 +1962,6 @@ async function collectArtifactBytes(http, runId, items, zipPrefix, namespace2) {
1956
1962
  function eventsJsonl(events) {
1957
1963
  return strToU8(events.map((event) => JSON.stringify(event)).join("\n"));
1958
1964
  }
1959
- async function tryListOptionalRunEvents(http, runId, channel) {
1960
- try {
1961
- const events = await listRunEvents(http, runId, { channel });
1962
- if (channel === "log") {
1963
- return events.length > 0 && events.every(isLogChannelEvent) ? { status: "present", events } : { status: "unavailable", events: [] };
1964
- }
1965
- return hasUnifiedStreamEvidence(events) ? { status: "present", events } : { status: "unavailable", events: [] };
1966
- } catch {
1967
- return { status: "unavailable", events: [] };
1968
- }
1969
- }
1970
- function isLogChannelEvent(event) {
1971
- return event.channel === "log";
1972
- }
1973
- function hasUnifiedStreamEvidence(events) {
1974
- return events.some((event) => event.channel === "log" || event.channel === "event");
1975
- }
1976
1965
  function isPathSelector(selector) {
1977
1966
  return Boolean(selector && typeof selector === "object" && "path" in selector);
1978
1967
  }
@@ -1980,38 +1969,28 @@ function normalizeOutputLookupPath(path) {
1980
1969
  return path.replace(/\\/g, "/").replace(/^\/+/, "");
1981
1970
  }
1982
1971
  async function download(http, runId) {
1983
- const [run, events, logEvents, allEvents, outputs, logItems] = await Promise.all([
1972
+ const [run, events, outputs] = await Promise.all([
1984
1973
  getRun(http, runId),
1985
1974
  listRunEvents(http, runId),
1986
- tryListOptionalRunEvents(http, runId, "log"),
1987
- tryListOptionalRunEvents(http, runId, "all"),
1988
- listOutputs(http, runId),
1989
- listLogs(http, runId)
1975
+ listOutputs(http, runId)
1990
1976
  ]);
1991
1977
  const out = await collectArtifactBytes(http, runId, outputs, "outputs/", "outputs");
1992
- const logs = await collectArtifactBytes(http, runId, logItems, "logs/", "logs");
1993
1978
  const submissionSnapshot = extractSubmissionSnapshot(run);
1994
1979
  const costTelemetry = extractCostTelemetry(run);
1995
1980
  const manifest = buildRunRecordDownloadManifestV1({
1996
1981
  runId,
1997
1982
  outputs: out.captured,
1998
- logs: logs.captured,
1999
- errors: [...out.errors, ...logs.errors],
1983
+ errors: out.errors,
2000
1984
  typedEventCount: events.length,
2001
1985
  ...submissionSnapshot ? { submission: { status: "present" } } : {},
2002
- ...costTelemetry ? { cost: { status: "present" } } : {},
2003
- logEvents: { status: logEvents.status, recordCount: logEvents.events.length },
2004
- allEvents: { status: allEvents.status, recordCount: allEvents.events.length }
1986
+ ...costTelemetry ? { cost: { status: "present" } } : {}
2005
1987
  });
2006
1988
  return zipEntries([
2007
1989
  jsonEntry("metadata/run.json", run),
2008
1990
  ...submissionSnapshot ? [jsonEntry("metadata/submission.json", submissionSnapshot)] : [],
2009
1991
  ...costTelemetry ? [jsonEntry("metadata/cost.json", costTelemetry)] : [],
2010
1992
  jsonlEntry("events/events.jsonl", events),
2011
- ...logEvents.status === "present" ? [jsonlEntry("events/logs.jsonl", logEvents.events)] : [],
2012
- ...allEvents.status === "present" ? [jsonlEntry("events/all.jsonl", allEvents.events)] : [],
2013
1993
  ...out.entries,
2014
- ...logs.entries,
2015
1994
  jsonEntry("manifest.json", manifest)
2016
1995
  ]);
2017
1996
  }
@@ -2023,25 +2002,9 @@ async function downloadOutputs(http, runId) {
2023
2002
  jsonEntry("manifest.json", { runId, namespace: "outputs", outputs: captured, errors })
2024
2003
  ]);
2025
2004
  }
2026
- async function downloadLogs(http, runId) {
2027
- const logItems = await listLogs(http, runId);
2028
- const { entries, captured, errors } = await collectArtifactBytes(http, runId, logItems, "", "logs");
2029
- return zipEntries([
2030
- ...entries,
2031
- jsonEntry("manifest.json", { runId, namespace: "logs", logs: captured, errors })
2032
- ]);
2033
- }
2034
2005
  async function downloadEvents(http, runId) {
2035
- const [events, logEvents, allEvents] = await Promise.all([
2036
- listRunEvents(http, runId),
2037
- tryListOptionalRunEvents(http, runId, "log"),
2038
- tryListOptionalRunEvents(http, runId, "all")
2039
- ]);
2040
- return zipEntries([
2041
- jsonlEntry("events.jsonl", events),
2042
- ...logEvents.status === "present" ? [jsonlEntry("logs.jsonl", logEvents.events)] : [],
2043
- ...allEvents.status === "present" ? [jsonlEntry("all.jsonl", allEvents.events)] : []
2044
- ]);
2006
+ const events = await listRunEvents(http, runId);
2007
+ return zipEntries([jsonlEntry("events.jsonl", events)]);
2045
2008
  }
2046
2009
  async function downloadMetadata(http, runId) {
2047
2010
  const run = await getRun(http, runId);
@@ -2742,7 +2705,7 @@ async function runProxy(io2, rest) {
2742
2705
  const url = `${manifest.proxyBaseUrl.replace(/\/+$/, "")}/${encodeURIComponent(f.endpointName)}`;
2743
2706
  const requestHeaders = new Headers();
2744
2707
  requestHeaders.set("authorization", `Bearer ${token}`);
2745
- requestHeaders.set(PROXY_PROTOCOL_HEADER, PROXY_PROTOCOL_VERSION);
2708
+ requestHeaders.set(PROXY_PROTOCOL_HEADER, PROXY_PROTOCOL_VERSION_V2);
2746
2709
  requestHeaders.set(PROXY_METHOD_HEADER, f.method.toUpperCase());
2747
2710
  requestHeaders.set(PROXY_PATH_HEADER, f.path);
2748
2711
  if (f.query) {
@@ -2776,6 +2739,11 @@ async function runProxy(io2, rest) {
2776
2739
  });
2777
2740
  return RUNTIME_ERR;
2778
2741
  }
2742
+ if (response.headers.get(PROXY_RESP_STATUS_HEADER) !== null) {
2743
+ const envelope = await readStreamedEnvelope(response, f.endpointName);
2744
+ io2.stdout(JSON.stringify(envelope) + "\n");
2745
+ return SUCCESS;
2746
+ }
2779
2747
  const text = await response.text();
2780
2748
  let parsedBody;
2781
2749
  try {
@@ -2813,6 +2781,39 @@ async function resolveBody(io2, spec) {
2813
2781
  function emitError(io2, body) {
2814
2782
  io2.stderr(JSON.stringify(body) + "\n");
2815
2783
  }
2784
+ async function readStreamedEnvelope(response, endpointName) {
2785
+ const effectiveResponseMode = response.headers.get(PROXY_RESP_MODE_HEADER) ?? "headers_only";
2786
+ const upstreamStatus = Number.parseInt(response.headers.get(PROXY_RESP_STATUS_HEADER) ?? "0", 10);
2787
+ const remainingCalls = Number.parseInt(response.headers.get(PROXY_RESP_REMAINING_CALLS_HEADER) ?? "0", 10);
2788
+ const remainingResponseBytes = Number.parseInt(response.headers.get(PROXY_RESP_REMAINING_BYTES_HEADER) ?? "0", 10);
2789
+ let upstreamHeaders = {};
2790
+ const rawHeaders = response.headers.get(PROXY_RESP_UPSTREAM_HEADERS_HEADER);
2791
+ if (rawHeaders) {
2792
+ try {
2793
+ const parsed = JSON.parse(rawHeaders);
2794
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
2795
+ upstreamHeaders = parsed;
2796
+ }
2797
+ } catch {
2798
+ }
2799
+ }
2800
+ const truncatedRaw = response.headers.get(PROXY_RESP_TRUNCATED_HEADER);
2801
+ const bytes = new Uint8Array(await response.arrayBuffer());
2802
+ return {
2803
+ endpointName,
2804
+ upstreamStatus,
2805
+ upstreamHeaders,
2806
+ effectiveResponseMode,
2807
+ // The streamed path can't echo the request-side clamp decision (it
2808
+ // isn't carried back); the effective mode is authoritative for the
2809
+ // agent and matches what v1 surfaced for an un-clamped call.
2810
+ modeClamped: false,
2811
+ remainingCalls,
2812
+ remainingResponseBytes,
2813
+ ...effectiveResponseMode === "full" && bytes.byteLength > 0 ? { upstreamBodyBase64: Buffer.from(bytes).toString("base64") } : {},
2814
+ ...truncatedRaw === "true" ? { truncated: true } : {}
2815
+ };
2816
+ }
2816
2817
  async function tryReadManifest(io2) {
2817
2818
  try {
2818
2819
  const raw = await io2.readFile(AEX_INDEX_PATH);
@@ -3814,7 +3815,6 @@ async function runOutputsCmd(io2, argv) {
3814
3815
  import { resolve as resolvePath3 } from "node:path";
3815
3816
  var NAMESPACE_DOWNLOADERS = {
3816
3817
  outputs: operations_exports.downloadOutputs,
3817
- logs: operations_exports.downloadLogs,
3818
3818
  events: operations_exports.downloadEvents,
3819
3819
  metadata: operations_exports.downloadMetadata
3820
3820
  };
@@ -3847,7 +3847,7 @@ async function runDownloadCmd(io2, argv) {
3847
3847
  const namespace2 = onlyFlag.value;
3848
3848
  const positional = onlyFlag.remaining.filter((arg) => !arg.startsWith("--"));
3849
3849
  if (positional.length !== 1) {
3850
- io2.stderr("usage: aex download <run-id> [--only outputs|logs|events|metadata] [--out path] [common flags]\n");
3850
+ io2.stderr("usage: aex download <run-id> [--only outputs|events|metadata] [--out path] [common flags]\n");
3851
3851
  return USAGE_ERR;
3852
3852
  }
3853
3853
  const runId = positional[0];
@@ -1 +1 @@
1
- bbc00f3784013aefc17bd7b5253652f3290d1fcdef98a2302d32befb4f6bf2ec cli.mjs
1
+ 2e7ad715af0e691bcc91e7f403c611f03d6e9a1e0566889dd32fd4b956b71779 cli.mjs
package/dist/client.d.ts CHANGED
@@ -4,7 +4,7 @@ import { File } from "./file.js";
4
4
  import { McpServer } from "./mcp-server.js";
5
5
  import { ProxyEndpoint } from "./proxy-endpoint.js";
6
6
  import { Skill } from "./skill.js";
7
- export interface AexClientOptions {
7
+ export interface AgentExecutorOptions {
8
8
  /** Workspace-scoped SDK API token. */
9
9
  readonly apiToken: string;
10
10
  /**
@@ -154,34 +154,6 @@ export type OutputFileSelector = Output | OutputFileIdSelector | OutputFilePathS
154
154
  export interface OutputDownloadOptions {
155
155
  readonly to?: string;
156
156
  }
157
- /**
158
- * One captured debug artifact returned by {@link AexClient.getRunDebugLogs}.
159
- *
160
- * - `filename` is the path under `runs/{runId}/logs/` — leading
161
- * `runtime/` for runtime logs and `host/` for host logs.
162
- * - `text` is populated when the content type looks textual
163
- * (`text/*`, `application/json`); decoded as UTF-8.
164
- * - `bytesBase64` is always present so a caller that wants raw bytes
165
- * (e.g. piping into a file) can use it uniformly across textual
166
- * and binary artifacts.
167
- */
168
- export interface RunDebugLog {
169
- readonly filename: string;
170
- readonly sizeBytes: number;
171
- readonly contentType: string;
172
- readonly createdAt: string;
173
- readonly text?: string;
174
- readonly bytesBase64: string;
175
- }
176
- export interface RunDebugLogError {
177
- readonly filename: string;
178
- readonly message: string;
179
- }
180
- export interface RunDebugLogs {
181
- readonly runId: string;
182
- readonly logs: ReadonlyArray<RunDebugLog>;
183
- readonly errors: ReadonlyArray<RunDebugLogError>;
184
- }
185
157
  /**
186
158
  * Workspace skill admin operations exposed under `client.skills`.
187
159
  *
@@ -289,12 +261,12 @@ export declare class FilesClient {
289
261
  * `client.whoami()` if you want to introspect which workspace the
290
262
  * token resolves to.
291
263
  */
292
- export declare class AexClient {
264
+ export declare class AgentExecutor {
293
265
  #private;
294
266
  readonly skills: SkillsClient;
295
267
  readonly agentsMd: AgentsMdClient;
296
268
  readonly files: FilesClient;
297
- constructor(options: AexClientOptions);
269
+ constructor(options: AgentExecutorOptions);
298
270
  /**
299
271
  * Internal: forwards to `SkillsClient._uploadSkillBundle`. NOT part of
300
272
  * the public API.
@@ -412,25 +384,6 @@ export declare class AexClient {
412
384
  downloadOutput(runId: string, options?: OutputDownloadOptions): Promise<Uint8Array>;
413
385
  downloadOutput(runId: string, selector: undefined, options?: OutputDownloadOptions): Promise<Uint8Array>;
414
386
  downloadOutput(runId: string, selector: OutputFileSelector, options?: OutputDownloadOptions): Promise<Uint8Array>;
415
- /**
416
- * Bundle the per-run debug artifacts aex captures automatically:
417
- *
418
- * - `runtime/{stdout,stderr,args}.log` — runtime process diagnostics.
419
- * - `host/...` — managed host logs when the platform includes them.
420
- * These all live in the run's `logs` namespace (`runs/<id>/logs/`).
421
- * Each is downloaded through the gated `/logs/:id/download` endpoint,
422
- * decoded as UTF-8 text when the content type looks textual, and
423
- * surfaced as raw bytes (base64) otherwise. The call is best-effort: a
424
- * download failure for one file does not block the others; the failing
425
- * entry lands in `errors` with the underlying message.
426
- *
427
- * Use this when a run failed or behaved oddly and you want all the
428
- * post-mortem material in one round-trip — no need to wire
429
- * `listOutputs` + `createOutputLink` by hand.
430
- */
431
- getRunDebugLogs(runId: string): Promise<RunDebugLogs>;
432
- /** Short alias for `getRunDebugLogs`. */
433
- debugLogs(runId: string): Promise<RunDebugLogs>;
434
387
  cancelRun(runId: string): Promise<void>;
435
388
  /** Short alias for `cancelRun`. */
436
389
  cancel(runId: string): Promise<void>;
@@ -445,19 +398,16 @@ export declare class AexClient {
445
398
  deleteWorkspaceAsset(hash: string): Promise<void>;
446
399
  whoami(): Promise<WhoAmI>;
447
400
  /**
448
- * Download EVERYTHING about a run as one zip, assembled client-side
401
+ * Download EVERYTHING public about a run as one zip, assembled client-side
449
402
  * from the public read endpoints (`getRun` + `listEvents` +
450
- * `listOutputs` + per-output `/download`). Organised into the four
451
- * namespace folders: `metadata/`, `events/`, `outputs/` (deliverables),
452
- * `logs/` (`runtime/`, `host/`, `provider-proxy/`, `control-plane/`
453
- * diagnostics), plus a `manifest.json`. Pass `to` to also write the
403
+ * `listOutputs` + per-output `/download`). Organised into the namespace
404
+ * folders `metadata/`, `events/`, and `outputs/`, plus a `manifest.json`.
405
+ * Pass `to` to also write the
454
406
  * bytes to a file path while still returning the bytes.
455
407
  */
456
408
  download(runId: string, options?: OutputDownloadOptions): Promise<Uint8Array>;
457
409
  /** Download only the run's deliverables (the `outputs` namespace) as a zip. */
458
410
  downloadOutputs(runId: string, options?: OutputDownloadOptions): Promise<Uint8Array>;
459
- /** Download only the platform diagnostics (the `logs` namespace) as a zip. */
460
- downloadLogs(runId: string, options?: OutputDownloadOptions): Promise<Uint8Array>;
461
411
  /** Download only the indexed event archive (the `events` namespace) as a zip. */
462
412
  downloadEvents(runId: string, options?: OutputDownloadOptions): Promise<Uint8Array>;
463
413
  /** Download only the run record (the `metadata` namespace) as a zip. */