@aexhq/sdk 0.25.0 → 0.25.2
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 +2 -2
- package/dist/_contracts/event-stream-client.js +4 -2
- package/dist/_contracts/index.d.ts +0 -1
- package/dist/_contracts/index.js +0 -1
- package/dist/_contracts/operations.d.ts +11 -3
- package/dist/_contracts/operations.js +216 -6
- package/dist/_contracts/provider-support.d.ts +2 -13
- package/dist/_contracts/provider-support.js +2 -14
- package/dist/_contracts/proxy-protocol.d.ts +4 -2
- package/dist/_contracts/proxy-protocol.js +10 -3
- package/dist/_contracts/run-config.d.ts +7 -5
- package/dist/_contracts/run-config.js +10 -7
- package/dist/_contracts/run-cost.d.ts +3 -11
- package/dist/_contracts/run-cost.js +2 -57
- package/dist/_contracts/run-custody.d.ts +1 -52
- package/dist/_contracts/run-custody.js +3 -87
- package/dist/_contracts/run-retention.d.ts +1 -5
- package/dist/_contracts/run-retention.js +2 -14
- package/dist/_contracts/run-unit.d.ts +2 -2
- package/dist/_contracts/runtime-security-profile.js +1 -1
- package/dist/_contracts/runtime-types.d.ts +36 -10
- package/dist/_contracts/side-effect-audit.d.ts +4 -5
- package/dist/_contracts/side-effect-audit.js +1 -4
- package/dist/_contracts/status.d.ts +3 -4
- package/dist/_contracts/status.js +3 -8
- package/dist/_contracts/submission.d.ts +97 -42
- package/dist/_contracts/submission.js +109 -29
- package/dist/cli.mjs +256 -48
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +25 -17
- package/dist/client.js +29 -10
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/concepts/agent-tools.md +30 -23
- package/docs/concepts/runs.md +6 -0
- package/docs/credentials.md +5 -3
- package/docs/events.md +18 -0
- package/docs/limits.md +10 -1
- package/docs/outputs.md +58 -0
- package/docs/provider-runtime-capabilities.md +1 -1
- package/docs/public-surface.json +1 -1
- package/docs/release.md +1 -1
- package/docs/run-config.md +7 -2
- package/docs/skills.md +9 -8
- package/docs/vision-skills.md +11 -13
- package/package.json +2 -2
- package/dist/_contracts/managed-key.d.ts +0 -101
- package/dist/_contracts/managed-key.js +0 -181
package/dist/cli.mjs
CHANGED
|
@@ -25,11 +25,16 @@ var PROXY_RESPONSE_MODES = ["status_only", "headers_only", "full"];
|
|
|
25
25
|
var PROXY_ENDPOINT_DEFAULTS = {
|
|
26
26
|
allowHeaders: [],
|
|
27
27
|
responseMode: "headers_only",
|
|
28
|
-
|
|
28
|
+
// 10 MiB. The body is buffered into the Worker to enforce this cap, while the
|
|
29
|
+
// launch default fits practical multimodal/tool POSTs without every endpoint
|
|
30
|
+
// needing an override.
|
|
31
|
+
maxRequestBytes: 10 * 1024 * 1024,
|
|
29
32
|
// Unlimited (0). The request body is buffered to enforce its cap, so that
|
|
30
33
|
// stays finite; the response is streamed, so it does not need one.
|
|
31
34
|
maxResponseBytes: 0,
|
|
32
|
-
|
|
35
|
+
// 5 minutes. Long-running upstream tool/model calls should not fail under a
|
|
36
|
+
// development-oriented 10s ceiling; endpoints can still set a smaller value.
|
|
37
|
+
timeoutMs: 5 * 60 * 1e3
|
|
33
38
|
};
|
|
34
39
|
|
|
35
40
|
// ../contracts/dist/provider-support.js
|
|
@@ -69,7 +74,6 @@ var DEEPSEEK_MANAGED_EVIDENCE = [
|
|
|
69
74
|
var PROVIDER_PUBLIC_SUPPORT = {
|
|
70
75
|
anthropic: {
|
|
71
76
|
displayName: "Anthropic",
|
|
72
|
-
status: "supported",
|
|
73
77
|
docsAnchor: "anthropic",
|
|
74
78
|
docs: COMMON_DOCS,
|
|
75
79
|
evidence: [...COMMON_EVIDENCE, ...ANTHROPIC_MANAGED_EVIDENCE],
|
|
@@ -79,7 +83,6 @@ var PROVIDER_PUBLIC_SUPPORT = {
|
|
|
79
83
|
},
|
|
80
84
|
deepseek: {
|
|
81
85
|
displayName: "DeepSeek",
|
|
82
|
-
status: "supported",
|
|
83
86
|
docsAnchor: "deepseek",
|
|
84
87
|
docs: COMMON_DOCS,
|
|
85
88
|
evidence: [...COMMON_EVIDENCE, ...DEEPSEEK_MANAGED_EVIDENCE],
|
|
@@ -89,7 +92,6 @@ var PROVIDER_PUBLIC_SUPPORT = {
|
|
|
89
92
|
},
|
|
90
93
|
openai: {
|
|
91
94
|
displayName: "OpenAI",
|
|
92
|
-
status: "supported",
|
|
93
95
|
docsAnchor: "openai",
|
|
94
96
|
docs: COMMON_DOCS,
|
|
95
97
|
evidence: COMMON_EVIDENCE,
|
|
@@ -99,7 +101,6 @@ var PROVIDER_PUBLIC_SUPPORT = {
|
|
|
99
101
|
},
|
|
100
102
|
gemini: {
|
|
101
103
|
displayName: "Gemini",
|
|
102
|
-
status: "supported",
|
|
103
104
|
docsAnchor: "gemini",
|
|
104
105
|
docs: COMMON_DOCS,
|
|
105
106
|
evidence: COMMON_EVIDENCE,
|
|
@@ -109,7 +110,6 @@ var PROVIDER_PUBLIC_SUPPORT = {
|
|
|
109
110
|
},
|
|
110
111
|
mistral: {
|
|
111
112
|
displayName: "Mistral",
|
|
112
|
-
status: "supported",
|
|
113
113
|
docsAnchor: "mistral",
|
|
114
114
|
docs: COMMON_DOCS,
|
|
115
115
|
evidence: COMMON_EVIDENCE,
|
|
@@ -119,7 +119,6 @@ var PROVIDER_PUBLIC_SUPPORT = {
|
|
|
119
119
|
},
|
|
120
120
|
openrouter: {
|
|
121
121
|
displayName: "OpenRouter",
|
|
122
|
-
status: "supported",
|
|
123
122
|
docsAnchor: "openrouter",
|
|
124
123
|
docs: COMMON_DOCS,
|
|
125
124
|
evidence: COMMON_EVIDENCE,
|
|
@@ -130,7 +129,6 @@ var PROVIDER_PUBLIC_SUPPORT = {
|
|
|
130
129
|
// Doubao (ByteDance) via the official Ark API — international BytePlus gateway.
|
|
131
130
|
doubao: {
|
|
132
131
|
displayName: "Doubao",
|
|
133
|
-
status: "supported",
|
|
134
132
|
docsAnchor: "doubao",
|
|
135
133
|
docs: COMMON_DOCS,
|
|
136
134
|
evidence: COMMON_EVIDENCE,
|
|
@@ -141,7 +139,6 @@ var PROVIDER_PUBLIC_SUPPORT = {
|
|
|
141
139
|
// Doubao (ByteDance) via the official Ark API — China Volcengine gateway.
|
|
142
140
|
"doubao-cn": {
|
|
143
141
|
displayName: "Doubao (China)",
|
|
144
|
-
status: "supported",
|
|
145
142
|
docsAnchor: "doubao-cn",
|
|
146
143
|
docs: COMMON_DOCS,
|
|
147
144
|
evidence: COMMON_EVIDENCE,
|
|
@@ -215,9 +212,7 @@ var TERMINAL_RUN_STATUSES = [
|
|
|
215
212
|
"failed",
|
|
216
213
|
"timed_out",
|
|
217
214
|
"cancelled",
|
|
218
|
-
"cleanup_failed"
|
|
219
|
-
"pending_delete",
|
|
220
|
-
"deleted"
|
|
215
|
+
"cleanup_failed"
|
|
221
216
|
];
|
|
222
217
|
var terminalRunStatuses = new Set(TERMINAL_RUN_STATUSES);
|
|
223
218
|
|
|
@@ -323,13 +318,13 @@ function requirePostHookRecord(input, path) {
|
|
|
323
318
|
// ../contracts/dist/run-config.js
|
|
324
319
|
var SKILL_BUNDLE_LIMITS = {
|
|
325
320
|
/** Compressed (.zip) ceiling. */
|
|
326
|
-
maxCompressedBytes: 10 * 1024 * 1024,
|
|
321
|
+
maxCompressedBytes: 10 * 1024 * 1024 * 1024,
|
|
327
322
|
/**
|
|
328
323
|
* Hard ceiling for the direct-to-storage upload path. Bytes never transit the
|
|
329
324
|
* hosted API, so its memory/request-payload limits do not cap accepted
|
|
330
325
|
* bundles; objects above this product cap are rejected before upload.
|
|
331
326
|
*/
|
|
332
|
-
maxBytes:
|
|
327
|
+
maxBytes: 10 * 1024 * 1024 * 1024,
|
|
333
328
|
/** Sum of uncompressed file sizes. */
|
|
334
329
|
maxDecompressedBytes: 50 * 1024 * 1024,
|
|
335
330
|
/** Number of regular file entries (directories don't count). */
|
|
@@ -655,6 +650,7 @@ function parseRunRequestConfig(input) {
|
|
|
655
650
|
"mcpServers",
|
|
656
651
|
"environment",
|
|
657
652
|
"runtimeSize",
|
|
653
|
+
"region",
|
|
658
654
|
"timeout",
|
|
659
655
|
"postHook",
|
|
660
656
|
"proxyEndpoints",
|
|
@@ -673,6 +669,7 @@ function parseRunRequestConfig(input) {
|
|
|
673
669
|
const prompt = parseRunRequestConfigPrompt(record.prompt);
|
|
674
670
|
const skills = parseRunRequestConfigSkills(record.skills);
|
|
675
671
|
const mcpServers = parseRunRequestConfigMcpServers(record.mcpServers);
|
|
672
|
+
const region = parseRunRegion(record.region);
|
|
676
673
|
const postHook = parsePostHook(record.postHook, "run request config postHook");
|
|
677
674
|
return {
|
|
678
675
|
model,
|
|
@@ -686,6 +683,7 @@ function parseRunRequestConfig(input) {
|
|
|
686
683
|
// of truth. The CLI surfaces structural errors at submission time.
|
|
687
684
|
...record.environment !== void 0 ? { environment: record.environment } : {},
|
|
688
685
|
...record.runtimeSize !== void 0 ? { runtimeSize: record.runtimeSize } : {},
|
|
686
|
+
...region !== void 0 ? { region } : {},
|
|
689
687
|
...record.timeout !== void 0 ? { timeout: record.timeout } : {},
|
|
690
688
|
...postHook !== void 0 ? { postHook: record.postHook } : {},
|
|
691
689
|
...record.proxyEndpoints !== void 0 ? { proxyEndpoints: record.proxyEndpoints } : {},
|
|
@@ -755,7 +753,7 @@ var RUNTIME_SECURITY_PROFILE_CONFIG = Object.freeze({
|
|
|
755
753
|
}),
|
|
756
754
|
standard: Object.freeze({
|
|
757
755
|
name: "standard",
|
|
758
|
-
defaultNetworkingMode: "
|
|
756
|
+
defaultNetworkingMode: "open",
|
|
759
757
|
allowOpenNetworking: true,
|
|
760
758
|
allowRuntimePackages: true,
|
|
761
759
|
allowCustomerEnvVars: true,
|
|
@@ -773,27 +771,6 @@ var RUNTIME_SECURITY_PROFILE_CONFIG = Object.freeze({
|
|
|
773
771
|
})
|
|
774
772
|
});
|
|
775
773
|
|
|
776
|
-
// ../contracts/dist/managed-key.js
|
|
777
|
-
var MANAGED_KEY_POLICY_SCHEMA_VERSION = 1;
|
|
778
|
-
var BLOCKED_MANAGED_KEY_FEATURE_POLICY_V1 = Object.freeze({
|
|
779
|
-
files: "disabled",
|
|
780
|
-
packages: "disabled",
|
|
781
|
-
builtins: "disabled",
|
|
782
|
-
mcpServers: "disabled",
|
|
783
|
-
proxyEndpoints: "disabled",
|
|
784
|
-
openNetworking: "disabled"
|
|
785
|
-
});
|
|
786
|
-
var BLOCKED_MANAGED_KEY_POLICY_V1 = Object.freeze({
|
|
787
|
-
schemaVersion: MANAGED_KEY_POLICY_SCHEMA_VERSION,
|
|
788
|
-
credentialMode: "managed",
|
|
789
|
-
launchStage: "blocked",
|
|
790
|
-
privateImplementationAvailable: false,
|
|
791
|
-
billingRequired: true,
|
|
792
|
-
providers: Object.freeze([]),
|
|
793
|
-
runtimes: Object.freeze([]),
|
|
794
|
-
features: BLOCKED_MANAGED_KEY_FEATURE_POLICY_V1
|
|
795
|
-
});
|
|
796
|
-
|
|
797
774
|
// ../contracts/dist/submission.js
|
|
798
775
|
var RUN_PROVIDERS = [
|
|
799
776
|
"anthropic",
|
|
@@ -806,10 +783,20 @@ var RUN_PROVIDERS = [
|
|
|
806
783
|
"doubao-cn"
|
|
807
784
|
];
|
|
808
785
|
var DEFAULT_RUN_PROVIDER = "anthropic";
|
|
786
|
+
var RUN_REGIONS = ["lhr", "iad", "sfo", "bom"];
|
|
809
787
|
var RUNTIME_KINDS = ["managed"];
|
|
810
788
|
var MIN_REDACTION_TARGET_BYTES = 4;
|
|
811
789
|
var MIN_PROXY_SECRET_BYTES = 8;
|
|
812
790
|
var _MIN_PROXY_SECRET_BYTES_OK = MIN_PROXY_SECRET_BYTES >= MIN_REDACTION_TARGET_BYTES;
|
|
791
|
+
function parseRunRegion(input) {
|
|
792
|
+
if (input === void 0) {
|
|
793
|
+
return void 0;
|
|
794
|
+
}
|
|
795
|
+
if (typeof input !== "string" || !RUN_REGIONS.includes(input)) {
|
|
796
|
+
throw new Error(`region must be one of: ${RUN_REGIONS.join(", ")} (got ${JSON.stringify(input)})`);
|
|
797
|
+
}
|
|
798
|
+
return input;
|
|
799
|
+
}
|
|
813
800
|
var MAX_OUTPUT_CAPTURE_TIMEOUT_MS = 6 * 60 * 60 * 1e3;
|
|
814
801
|
|
|
815
802
|
// ../contracts/dist/connection-ticket.js
|
|
@@ -897,13 +884,9 @@ var forbiddenStringPatterns = Object.freeze([
|
|
|
897
884
|
{
|
|
898
885
|
reason: "private_resource_handle",
|
|
899
886
|
// `<keyword><sep><id>` opaque handles (`session_a1B2c3D4e5`, `file_9f8e7d…`).
|
|
900
|
-
// The keyword set overlaps ordinary
|
|
901
|
-
//
|
|
902
|
-
//
|
|
903
|
-
// `session_handoff_contract`, `agent-judgment` — read straight out of a
|
|
904
|
-
// skill-pack doc in tool-result text). The `accept` predicate keeps the shape
|
|
905
|
-
// but requires the id segment to look minted rather than spelled — i.e. carry
|
|
906
|
-
// a digit — so genuine handles stay flagged while dictionary-word prose does not.
|
|
887
|
+
// The keyword set overlaps ordinary prose, so require the id segment to
|
|
888
|
+
// carry a digit. That keeps genuine minted handles flagged while avoiding
|
|
889
|
+
// dictionary-word chains such as `agent_decision_failure`.
|
|
907
890
|
regex: /\b(?:machine|session|agent|file|skill|env|resource|handle|token_hash|bearer_hash)[_:-][A-Za-z0-9][A-Za-z0-9_-]{7,}\b/i,
|
|
908
891
|
accept: isMintedResourceHandle
|
|
909
892
|
},
|
|
@@ -1390,6 +1373,7 @@ function extractErrorMessage(body) {
|
|
|
1390
1373
|
var operations_exports = {};
|
|
1391
1374
|
__export(operations_exports, {
|
|
1392
1375
|
cancelRun: () => cancelRun,
|
|
1376
|
+
classifyOutput: () => classifyOutput,
|
|
1393
1377
|
createAgentsMd: () => createAgentsMd,
|
|
1394
1378
|
createFile: () => createFile,
|
|
1395
1379
|
createOutputLink: () => createOutputLink,
|
|
@@ -1407,6 +1391,10 @@ __export(operations_exports, {
|
|
|
1407
1391
|
downloadMetadata: () => downloadMetadata,
|
|
1408
1392
|
downloadOutput: () => downloadOutput,
|
|
1409
1393
|
downloadOutputs: () => downloadOutputs,
|
|
1394
|
+
eventArchiveLink: () => eventArchiveLink,
|
|
1395
|
+
filterOutputs: () => filterOutputs,
|
|
1396
|
+
findOutput: () => findOutput,
|
|
1397
|
+
findOutputs: () => findOutputs,
|
|
1410
1398
|
findSkillByHash: () => findSkillByHash,
|
|
1411
1399
|
findSkillByName: () => findSkillByName,
|
|
1412
1400
|
getAgentsMd: () => getAgentsMd,
|
|
@@ -1423,6 +1411,8 @@ __export(operations_exports, {
|
|
|
1423
1411
|
listRunEvents: () => listRunEvents,
|
|
1424
1412
|
listSecrets: () => listSecrets,
|
|
1425
1413
|
listSkills: () => listSkills,
|
|
1414
|
+
normalizeOutputLinkExpiresIn: () => normalizeOutputLinkExpiresIn,
|
|
1415
|
+
outputLink: () => outputLink,
|
|
1426
1416
|
resolveOutputFileSelector: () => resolveOutputFileSelector,
|
|
1427
1417
|
rotateSecret: () => rotateSecret,
|
|
1428
1418
|
submitRun: () => submitRun,
|
|
@@ -2173,12 +2163,50 @@ async function listRunEvents(http, runId) {
|
|
|
2173
2163
|
async function getCoordinatorTicket(http, runId) {
|
|
2174
2164
|
return http.request(`/api/runs/${encodeURIComponent(runId)}/events/ticket`, { method: "POST" });
|
|
2175
2165
|
}
|
|
2176
|
-
async function listOutputs(http, runId) {
|
|
2166
|
+
async function listOutputs(http, runId, query) {
|
|
2177
2167
|
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/outputs`);
|
|
2178
|
-
return result.outputs;
|
|
2168
|
+
return query === void 0 ? result.outputs : filterOutputs(result.outputs, query);
|
|
2179
2169
|
}
|
|
2180
|
-
async function
|
|
2181
|
-
return http
|
|
2170
|
+
async function findOutputs(http, runId, query) {
|
|
2171
|
+
return listOutputs(http, runId, query);
|
|
2172
|
+
}
|
|
2173
|
+
async function findOutput(http, runId, query) {
|
|
2174
|
+
const matches = await findOutputs(http, runId, query);
|
|
2175
|
+
if (matches.length === 0)
|
|
2176
|
+
return null;
|
|
2177
|
+
if (matches.length === 1)
|
|
2178
|
+
return matches[0];
|
|
2179
|
+
throw new RunStateError("findOutput: output query matched multiple files", {
|
|
2180
|
+
runId,
|
|
2181
|
+
matches: matches.map((output) => output.filename ?? output.id)
|
|
2182
|
+
});
|
|
2183
|
+
}
|
|
2184
|
+
async function outputLink(http, runId, selectorOrQuery, options) {
|
|
2185
|
+
const output = await resolveOutputLinkTarget(http, runId, selectorOrQuery);
|
|
2186
|
+
const expiresInSeconds = normalizeOutputLinkExpiresIn(options?.expiresIn);
|
|
2187
|
+
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/outputs/${encodeURIComponent(output.id)}/link`, {
|
|
2188
|
+
method: "POST",
|
|
2189
|
+
body: JSON.stringify({ expiresInSeconds })
|
|
2190
|
+
});
|
|
2191
|
+
return {
|
|
2192
|
+
...result,
|
|
2193
|
+
expiresInSeconds: result.expiresInSeconds ?? expiresInSeconds,
|
|
2194
|
+
output: result.output ?? output
|
|
2195
|
+
};
|
|
2196
|
+
}
|
|
2197
|
+
async function createOutputLink(http, runId, selectorOrQuery, options) {
|
|
2198
|
+
return outputLink(http, runId, selectorOrQuery, options);
|
|
2199
|
+
}
|
|
2200
|
+
async function eventArchiveLink(http, runId, options) {
|
|
2201
|
+
const expiresInSeconds = normalizeOutputLinkExpiresIn(options?.expiresIn);
|
|
2202
|
+
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/events/link`, {
|
|
2203
|
+
method: "POST",
|
|
2204
|
+
body: JSON.stringify({ expiresInSeconds })
|
|
2205
|
+
});
|
|
2206
|
+
return {
|
|
2207
|
+
...result,
|
|
2208
|
+
expiresInSeconds: result.expiresInSeconds ?? expiresInSeconds
|
|
2209
|
+
};
|
|
2182
2210
|
}
|
|
2183
2211
|
function resolveOutputFileSelector(outputs, selector, runId) {
|
|
2184
2212
|
if (isPathSelector(selector)) {
|
|
@@ -2263,6 +2291,171 @@ function isPathSelector(selector) {
|
|
|
2263
2291
|
function normalizeOutputLookupPath(path) {
|
|
2264
2292
|
return path.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
2265
2293
|
}
|
|
2294
|
+
function filterOutputs(outputs, query) {
|
|
2295
|
+
return outputs.filter((output) => outputMatchesQuery(output, query));
|
|
2296
|
+
}
|
|
2297
|
+
function classifyOutput(output) {
|
|
2298
|
+
const contentType = normalizeContentType(output.contentType);
|
|
2299
|
+
if (contentType) {
|
|
2300
|
+
if (contentType === "application/json" || contentType.endsWith("+json") || contentType.includes("json")) {
|
|
2301
|
+
return "json";
|
|
2302
|
+
}
|
|
2303
|
+
if (contentType.startsWith("text/"))
|
|
2304
|
+
return "text";
|
|
2305
|
+
if (contentType.startsWith("image/"))
|
|
2306
|
+
return "image";
|
|
2307
|
+
if (contentType.startsWith("audio/"))
|
|
2308
|
+
return "audio";
|
|
2309
|
+
if (contentType.startsWith("video/"))
|
|
2310
|
+
return "video";
|
|
2311
|
+
if (contentType === "application/pdf")
|
|
2312
|
+
return "pdf";
|
|
2313
|
+
if (contentType === "application/zip" || contentType === "application/gzip" || contentType === "application/x-gzip" || contentType === "application/x-tar" || contentType === "application/x-7z-compressed" || contentType === "application/vnd.rar" || contentType === "application/zstd") {
|
|
2314
|
+
return "archive";
|
|
2315
|
+
}
|
|
2316
|
+
if (contentType === "application/octet-stream")
|
|
2317
|
+
return "binary";
|
|
2318
|
+
return "unknown";
|
|
2319
|
+
}
|
|
2320
|
+
const extension = extensionOf(output.filename);
|
|
2321
|
+
if (!extension)
|
|
2322
|
+
return "unknown";
|
|
2323
|
+
if (["json", "jsonl", "ndjson"].includes(extension))
|
|
2324
|
+
return "json";
|
|
2325
|
+
if (["txt", "log", "md", "markdown", "csv", "tsv", "xml", "html", "htm", "yaml", "yml"].includes(extension)) {
|
|
2326
|
+
return "text";
|
|
2327
|
+
}
|
|
2328
|
+
if (["png", "jpg", "jpeg", "gif", "webp", "avif", "bmp", "tif", "tiff", "svg"].includes(extension)) {
|
|
2329
|
+
return "image";
|
|
2330
|
+
}
|
|
2331
|
+
if (["mp3", "wav", "flac", "m4a", "aac", "ogg", "oga", "opus"].includes(extension))
|
|
2332
|
+
return "audio";
|
|
2333
|
+
if (["mp4", "mov", "m4v", "webm", "mkv", "avi"].includes(extension))
|
|
2334
|
+
return "video";
|
|
2335
|
+
if (extension === "pdf")
|
|
2336
|
+
return "pdf";
|
|
2337
|
+
if (["zip", "tar", "tgz", "gz", "bz2", "xz", "7z", "rar", "zst"].includes(extension))
|
|
2338
|
+
return "archive";
|
|
2339
|
+
if (["bin", "exe", "dll", "so", "dylib", "dmg", "iso"].includes(extension))
|
|
2340
|
+
return "binary";
|
|
2341
|
+
return "unknown";
|
|
2342
|
+
}
|
|
2343
|
+
function normalizeOutputLinkExpiresIn(input = "1h") {
|
|
2344
|
+
if (typeof input === "number") {
|
|
2345
|
+
if (!Number.isFinite(input) || input <= 0) {
|
|
2346
|
+
throw new RunStateError("outputLink: expiresIn must be a positive number of seconds", {
|
|
2347
|
+
expiresIn: input
|
|
2348
|
+
});
|
|
2349
|
+
}
|
|
2350
|
+
return Math.floor(input);
|
|
2351
|
+
}
|
|
2352
|
+
if (input === "15m")
|
|
2353
|
+
return 15 * 60;
|
|
2354
|
+
if (input === "1h")
|
|
2355
|
+
return 60 * 60;
|
|
2356
|
+
if (input === "1d")
|
|
2357
|
+
return 24 * 60 * 60;
|
|
2358
|
+
throw new RunStateError('outputLink: expiresIn must be seconds, "15m", "1h", or "1d"', {
|
|
2359
|
+
expiresIn: input
|
|
2360
|
+
});
|
|
2361
|
+
}
|
|
2362
|
+
async function resolveOutputLinkTarget(http, runId, selectorOrQuery) {
|
|
2363
|
+
if (typeof selectorOrQuery === "string") {
|
|
2364
|
+
if (selectorOrQuery.length === 0) {
|
|
2365
|
+
throw new RunStateError("outputLink: selector must include an output id or query", { runId });
|
|
2366
|
+
}
|
|
2367
|
+
return { id: selectorOrQuery };
|
|
2368
|
+
}
|
|
2369
|
+
if (hasOutputId(selectorOrQuery)) {
|
|
2370
|
+
if (selectorOrQuery.id.length === 0) {
|
|
2371
|
+
throw new RunStateError("outputLink: selector must include an output id or query", { runId });
|
|
2372
|
+
}
|
|
2373
|
+
return selectorOrQuery;
|
|
2374
|
+
}
|
|
2375
|
+
if (isPathSelector(selectorOrQuery) && selectorOrQuery.match === "suffix") {
|
|
2376
|
+
return resolveOutputFileSelector(await listOutputs(http, runId), selectorOrQuery, runId);
|
|
2377
|
+
}
|
|
2378
|
+
const match = await findOutput(http, runId, selectorOrQuery);
|
|
2379
|
+
if (match)
|
|
2380
|
+
return match;
|
|
2381
|
+
throw new RunStateError("outputLink: output query matched no files", { runId });
|
|
2382
|
+
}
|
|
2383
|
+
function outputMatchesQuery(output, query) {
|
|
2384
|
+
const normalizedPath = typeof output.filename === "string" ? normalizeOutputQueryPath(output.filename) : "";
|
|
2385
|
+
if (query.path !== void 0 && normalizedPath !== normalizeOutputQueryPath(query.path)) {
|
|
2386
|
+
return false;
|
|
2387
|
+
}
|
|
2388
|
+
if (query.filename !== void 0) {
|
|
2389
|
+
const basename2 = basenameOf(normalizedPath);
|
|
2390
|
+
if (typeof query.filename === "string") {
|
|
2391
|
+
if (basename2 !== query.filename)
|
|
2392
|
+
return false;
|
|
2393
|
+
} else {
|
|
2394
|
+
query.filename.lastIndex = 0;
|
|
2395
|
+
if (!query.filename.test(basename2))
|
|
2396
|
+
return false;
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
if (query.dir !== void 0 && !directoryMatches(normalizedPath, query.dir, query.recursive ?? true)) {
|
|
2400
|
+
return false;
|
|
2401
|
+
}
|
|
2402
|
+
if (query.extension !== void 0 && extensionOf(normalizedPath) !== normalizeExtension(query.extension)) {
|
|
2403
|
+
return false;
|
|
2404
|
+
}
|
|
2405
|
+
if (query.contentType !== void 0 && !contentTypeMatches(output.contentType, query.contentType)) {
|
|
2406
|
+
return false;
|
|
2407
|
+
}
|
|
2408
|
+
if (query.type !== void 0 && classifyOutput(output) !== query.type) {
|
|
2409
|
+
return false;
|
|
2410
|
+
}
|
|
2411
|
+
return true;
|
|
2412
|
+
}
|
|
2413
|
+
function hasOutputId(value) {
|
|
2414
|
+
return Boolean(value && typeof value === "object" && "id" in value && typeof value.id === "string");
|
|
2415
|
+
}
|
|
2416
|
+
function normalizeOutputQueryPath(path) {
|
|
2417
|
+
let normalized = path.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
2418
|
+
while (normalized === "outputs" || normalized.startsWith("outputs/")) {
|
|
2419
|
+
normalized = normalized === "outputs" ? "" : normalized.slice("outputs/".length);
|
|
2420
|
+
}
|
|
2421
|
+
return normalized.replace(/\/+$/, "");
|
|
2422
|
+
}
|
|
2423
|
+
function basenameOf(path) {
|
|
2424
|
+
return path.split("/").filter(Boolean).pop() ?? "";
|
|
2425
|
+
}
|
|
2426
|
+
function directoryMatches(path, dir, recursive) {
|
|
2427
|
+
const normalizedDir = normalizeOutputQueryPath(dir);
|
|
2428
|
+
if (normalizedDir.length === 0)
|
|
2429
|
+
return true;
|
|
2430
|
+
const prefix = `${normalizedDir}/`;
|
|
2431
|
+
if (!path.startsWith(prefix))
|
|
2432
|
+
return false;
|
|
2433
|
+
const remainder = path.slice(prefix.length);
|
|
2434
|
+
return remainder.length > 0 && (recursive || !remainder.includes("/"));
|
|
2435
|
+
}
|
|
2436
|
+
function normalizeExtension(extension) {
|
|
2437
|
+
return extension.replace(/^\.+/, "").toLowerCase();
|
|
2438
|
+
}
|
|
2439
|
+
function extensionOf(path) {
|
|
2440
|
+
if (!path)
|
|
2441
|
+
return "";
|
|
2442
|
+
const basename2 = basenameOf(normalizeOutputQueryPath(path));
|
|
2443
|
+
const index = basename2.lastIndexOf(".");
|
|
2444
|
+
return index > 0 && index < basename2.length - 1 ? basename2.slice(index + 1).toLowerCase() : "";
|
|
2445
|
+
}
|
|
2446
|
+
function normalizeContentType(contentType) {
|
|
2447
|
+
return (contentType ?? "").split(";")[0].trim().toLowerCase();
|
|
2448
|
+
}
|
|
2449
|
+
function contentTypeMatches(actual, expected) {
|
|
2450
|
+
const normalizedActual = normalizeContentType(actual);
|
|
2451
|
+
const normalizedExpected = normalizeContentType(expected);
|
|
2452
|
+
if (!normalizedActual || !normalizedExpected)
|
|
2453
|
+
return false;
|
|
2454
|
+
if (normalizedExpected.endsWith("/*")) {
|
|
2455
|
+
return normalizedActual.startsWith(normalizedExpected.slice(0, -1));
|
|
2456
|
+
}
|
|
2457
|
+
return normalizedActual === normalizedExpected;
|
|
2458
|
+
}
|
|
2266
2459
|
async function download(http, runId) {
|
|
2267
2460
|
const [run, events, outputs] = await Promise.all([
|
|
2268
2461
|
getRun(http, runId),
|
|
@@ -3227,6 +3420,18 @@ async function runRunCmd(io2, argv) {
|
|
|
3227
3420
|
}
|
|
3228
3421
|
runtime = runtimeFlag.value;
|
|
3229
3422
|
}
|
|
3423
|
+
const regionFlag = takeFlagValue(rest, "--region");
|
|
3424
|
+
if (regionFlag.error) {
|
|
3425
|
+
io2.stderr(`${regionFlag.error}
|
|
3426
|
+
`);
|
|
3427
|
+
return USAGE_ERR;
|
|
3428
|
+
}
|
|
3429
|
+
rest = regionFlag.remaining;
|
|
3430
|
+
if (regionFlag.value && !RUN_REGIONS.includes(regionFlag.value)) {
|
|
3431
|
+
io2.stderr(`--region must be one of: ${RUN_REGIONS.join(", ")}
|
|
3432
|
+
`);
|
|
3433
|
+
return USAGE_ERR;
|
|
3434
|
+
}
|
|
3230
3435
|
const idempotency = takeFlagValue(rest, "--idempotency-key");
|
|
3231
3436
|
if (idempotency.error) {
|
|
3232
3437
|
io2.stderr(`${idempotency.error}
|
|
@@ -3506,6 +3711,7 @@ async function runRunCmd(io2, argv) {
|
|
|
3506
3711
|
...runtime ? { runtime } : {},
|
|
3507
3712
|
submission,
|
|
3508
3713
|
secrets,
|
|
3714
|
+
...regionFlag.value ? { region: regionFlag.value } : runConfig.region ? { region: runConfig.region } : {},
|
|
3509
3715
|
...runtimeSizeFlag.value ? { runtimeSize: runtimeSizeFlag.value } : runConfig.runtimeSize ? { runtimeSize: runConfig.runtimeSize } : {},
|
|
3510
3716
|
...runTimeoutFlag.value ? { timeout: runTimeoutFlag.value } : runConfig.timeout ? { timeout: runConfig.timeout } : {},
|
|
3511
3717
|
...runConfig.postHook ? { postHook: runConfig.postHook } : {},
|
|
@@ -4430,6 +4636,8 @@ Protocol version: ${manifest.protocolVersion}
|
|
|
4430
4636
|
io2.stdout(" --metadata key=value Submission metadata entry (repeatable)\n");
|
|
4431
4637
|
io2.stdout(" --proxy-endpoint '<json>' PlatformProxyEndpoint JSON (repeatable)\n");
|
|
4432
4638
|
io2.stdout(" --proxy-auth name=<spec> bearer:tok | basic:u:p | header:v | query:v (repeatable)\n");
|
|
4639
|
+
io2.stdout(` --region <region> Product placement token; one of: ${RUN_REGIONS.join(", ")}
|
|
4640
|
+
`);
|
|
4433
4641
|
io2.stdout(" --runtime-size <size> managed runtime preset\n");
|
|
4434
4642
|
io2.stdout(" --run-timeout <dur> Server-side run deadline (e.g. 1h); distinct from --timeout\n");
|
|
4435
4643
|
io2.stdout(" --idempotency-key <key> Optional; defaults to a fresh UUID\n");
|
package/dist/cli.mjs.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
731645495d2d705531e428f4e587cb0cbc7e3e3324e6fcdaa20154ef04572466 cli.mjs
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HttpClient, SecretString, type AexEvent, type AgentsMdRecord, type CredentialMode, type DebugSink, type FetchLike, type FileRecord, type Output, type OutputMode, type PlatformEnvironmentInput, type PlatformSubmission, type PlatformInlineSecrets, type PlatformProxyEndpoint, type PlatformProxyEndpointAuth, type PlatformPostHookInput, type Run, type RunModel, type RunEvent, type RunProvider, type SecretRecord, type SecretReveal, type RunUnit, type Builtin, type RuntimeSize, type RuntimeKind, type
|
|
1
|
+
import { HttpClient, SecretString, type AexEvent, type AgentsMdRecord, type CredentialMode, type DebugSink, type FetchLike, type FileRecord, type Output, type OutputFileType, type OutputLink, type OutputLinkOptions, type OutputQuery, type OutputMode, type PlatformEnvironmentInput, type PlatformSubmission, type PlatformInlineSecrets, type PlatformProxyEndpoint, type PlatformProxyEndpointAuth, type PlatformPostHookInput, type Run, type RunModel, type RunEvent, type RunProvider, type RunRegion, type SecretRecord, type SecretReveal, type RunUnit, type Builtin, type RuntimeSize, type RuntimeKind, type Skill as SkillRecord, type WhoAmI } from "./_contracts/index.js";
|
|
2
2
|
import { AgentsMd } from "./agents-md.js";
|
|
3
3
|
import { type UploadedAsset } from "./asset-upload.js";
|
|
4
4
|
import { File } from "./file.js";
|
|
@@ -51,8 +51,6 @@ export interface SubmitOptions {
|
|
|
51
51
|
/**
|
|
52
52
|
* Credential source for upstream provider access. Omitted defaults to
|
|
53
53
|
* `"byok"`, which requires `secrets.apiKey`.
|
|
54
|
-
* `"managed"` is reserved for paid managed-key mode and currently fails
|
|
55
|
-
* closed until the hosted private implementation is wired.
|
|
56
54
|
*/
|
|
57
55
|
readonly credentialMode?: CredentialMode;
|
|
58
56
|
/**
|
|
@@ -75,6 +73,12 @@ export interface SubmitOptions {
|
|
|
75
73
|
* is no longer accepted.
|
|
76
74
|
*/
|
|
77
75
|
readonly runtime?: RuntimeKind;
|
|
76
|
+
/**
|
|
77
|
+
* Optional hosted-platform placement token for this run. These are product
|
|
78
|
+
* region tokens, not exact city guarantees; omit to let the platform infer a
|
|
79
|
+
* configured region and fall back when no hint matches.
|
|
80
|
+
*/
|
|
81
|
+
readonly region?: RunRegion;
|
|
78
82
|
/**
|
|
79
83
|
* Closed public model id. Prefer the {@link Models} symbol const, e.g.
|
|
80
84
|
* `Models.CLAUDE_HAIKU_4_5`. Pair it with an explicit {@link Providers} value
|
|
@@ -139,19 +143,17 @@ export interface SubmitOptions {
|
|
|
139
143
|
readonly maxFiles?: number;
|
|
140
144
|
};
|
|
141
145
|
/**
|
|
142
|
-
* Override the managed runtime
|
|
146
|
+
* Override the managed runtime builtins enabled inside the runner.
|
|
143
147
|
* Each entry is one of the closed {@link Builtin} set — prefer the
|
|
144
148
|
* {@link Builtins} symbol const so a typo is a compile error.
|
|
145
149
|
*
|
|
146
|
-
* - Omitted (default): the runner enables `
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
* - Empty array: the agent runs with zero
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* `[Builtins.DEVELOPER, Builtins.COMPUTER_CONTROLLER]` to add
|
|
154
|
-
* web fetch/scrape alongside the default shell/edit toolkit.
|
|
150
|
+
* - Omitted (default): the runner enables `DEFAULT_BUILTINS`
|
|
151
|
+
* (`web_search`, `web_fetch`, `read`, `edit`, `glob`, `grep`, `head`,
|
|
152
|
+
* `tail`).
|
|
153
|
+
* - Empty array: the agent runs with zero builtins — useful for pure-MCP
|
|
154
|
+
* setups where every tool comes from a submitted `mcpServers` entry.
|
|
155
|
+
* - Custom list: narrows or extends the surface, e.g.
|
|
156
|
+
* `[Builtins.WEB_SEARCH, Builtins.NOTEBOOK]`.
|
|
155
157
|
*
|
|
156
158
|
* Validation: each entry must be a member of {@link Builtins}, max 16
|
|
157
159
|
* entries, deduplicated server-side.
|
|
@@ -213,6 +215,7 @@ export interface OutputFileIdSelector {
|
|
|
213
215
|
readonly id: string;
|
|
214
216
|
}
|
|
215
217
|
export type OutputFileSelector = Output | OutputFileIdSelector | OutputFilePathSelector;
|
|
218
|
+
export type OutputLinkSelector = string | OutputFileSelector | OutputQuery;
|
|
216
219
|
export interface OutputDownloadOptions {
|
|
217
220
|
readonly to?: string;
|
|
218
221
|
}
|
|
@@ -505,10 +508,15 @@ export declare class AgentExecutor {
|
|
|
505
508
|
waitForRun(runId: string, options?: WaitForRunOptions): Promise<Run>;
|
|
506
509
|
/** Short alias for `waitForRun`. */
|
|
507
510
|
wait(runId: string, options?: WaitForRunOptions): Promise<Run>;
|
|
508
|
-
listOutputs(runId: string): Promise<readonly Output[]>;
|
|
511
|
+
listOutputs(runId: string, query?: OutputQuery): Promise<readonly Output[]>;
|
|
509
512
|
/** Short alias for `listOutputs`. */
|
|
510
|
-
outputs(runId: string): Promise<readonly Output[]>;
|
|
511
|
-
|
|
513
|
+
outputs(runId: string, query?: OutputQuery): Promise<readonly Output[]>;
|
|
514
|
+
findOutputs(runId: string, query: OutputQuery): Promise<readonly Output[]>;
|
|
515
|
+
findOutput(runId: string, query: OutputQuery): Promise<Output | null>;
|
|
516
|
+
outputLink(runId: string, selectorOrQuery: OutputLinkSelector, options?: OutputLinkOptions): Promise<OutputLink>;
|
|
517
|
+
createOutputLink(runId: string, selectorOrQuery: OutputLinkSelector, options?: OutputLinkOptions): Promise<OutputLink>;
|
|
518
|
+
fetchOutput(runId: string, selectorOrQuery: OutputLinkSelector, options?: OutputLinkOptions): Promise<Response>;
|
|
519
|
+
eventArchiveLink(runId: string, options?: OutputLinkOptions): Promise<OutputLink>;
|
|
512
520
|
/**
|
|
513
521
|
* Download captured deliverables. Omit `selector` to receive the full
|
|
514
522
|
* outputs namespace as a zip; pass an id, Output object, or path selector
|
|
@@ -546,4 +554,4 @@ export declare class AgentExecutor {
|
|
|
546
554
|
/** Download only the run record (the `metadata` namespace) as a zip. */
|
|
547
555
|
downloadMetadata(runId: string, options?: OutputDownloadOptions): Promise<Uint8Array>;
|
|
548
556
|
}
|
|
549
|
-
export type { PlatformProxyEndpoint, PlatformProxyEndpointAuth };
|
|
557
|
+
export type { OutputFileType, OutputLink, OutputLinkOptions, OutputQuery, PlatformProxyEndpoint, PlatformProxyEndpointAuth };
|
package/dist/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AexError, DEFAULT_CREDENTIAL_MODE, DEFAULT_RUN_PROVIDER, HttpClient, RUNTIME_KINDS, RunStateError, SecretString, isRunSettled, operations, parseCredentialMode, providersForModel, streamCoordinatorEvents, TERMINAL_RUN_STATUSES } from "./_contracts/index.js";
|
|
1
|
+
import { AexError, DEFAULT_CREDENTIAL_MODE, DEFAULT_RUN_PROVIDER, HttpClient, RUN_REGIONS, RUNTIME_KINDS, RunStateError, SecretString, isRunSettled, operations, parseCredentialMode, providersForModel, streamCoordinatorEvents, TERMINAL_RUN_STATUSES } from "./_contracts/index.js";
|
|
2
2
|
import { AgentsMd } from "./agents-md.js";
|
|
3
3
|
import { uploadAsset } from "./asset-upload.js";
|
|
4
4
|
import { File } from "./file.js";
|
|
@@ -332,9 +332,6 @@ export class AgentExecutor {
|
|
|
332
332
|
}
|
|
333
333
|
const provider = options.provider ?? supportedProviders[0] ?? DEFAULT_RUN_PROVIDER;
|
|
334
334
|
const credentialMode = parseCredentialMode(options.credentialMode);
|
|
335
|
-
if (credentialMode === "managed") {
|
|
336
|
-
throw new AexError("CREDENTIAL_INVALID", "AgentExecutor.submit: credentialMode \"managed\" is not available without a private managed-key implementation");
|
|
337
|
-
}
|
|
338
335
|
if (!options.secrets) {
|
|
339
336
|
throw new Error("AgentExecutor.submit: secrets is required");
|
|
340
337
|
}
|
|
@@ -361,6 +358,11 @@ export class AgentExecutor {
|
|
|
361
358
|
throw new AexError("RUNTIME_UNSUPPORTED", `AgentExecutor.submit: runtime must be one of: ${RUNTIME_KINDS.join(", ")} ` +
|
|
362
359
|
`(got ${JSON.stringify(options.runtime)})`);
|
|
363
360
|
}
|
|
361
|
+
if (options.region !== undefined &&
|
|
362
|
+
!RUN_REGIONS.includes(options.region)) {
|
|
363
|
+
throw new AexError("RUN_CONFIG_INVALID", `AgentExecutor.submit: region must be one of: ${RUN_REGIONS.join(", ")} ` +
|
|
364
|
+
`(got ${JSON.stringify(options.region)})`);
|
|
365
|
+
}
|
|
364
366
|
// Walk Skill / Tool / AgentsMd / File instances. Inline drafts are eagerly
|
|
365
367
|
// uploaded to the content-addressable asset store here (before POST /runs)
|
|
366
368
|
// and referenced as plain `kind:"asset"` refs. Already-materialized asset
|
|
@@ -423,6 +425,7 @@ export class AgentExecutor {
|
|
|
423
425
|
// dispatcher auto-route. Only emit it when the caller asked for
|
|
424
426
|
// a specific runtime so the wire shape stays minimal.
|
|
425
427
|
...(options.runtime ? { runtime: options.runtime } : {}),
|
|
428
|
+
...(options.region ? { region: options.region } : {}),
|
|
426
429
|
submission,
|
|
427
430
|
...(options.runtimeSize ? { runtimeSize: options.runtimeSize } : {}),
|
|
428
431
|
...(options.timeout ? { timeout: options.timeout } : {}),
|
|
@@ -550,15 +553,31 @@ export class AgentExecutor {
|
|
|
550
553
|
wait(runId, options) {
|
|
551
554
|
return this.waitForRun(runId, options);
|
|
552
555
|
}
|
|
553
|
-
listOutputs(runId) {
|
|
554
|
-
return operations.listOutputs(this.#http, runId);
|
|
556
|
+
listOutputs(runId, query) {
|
|
557
|
+
return operations.listOutputs(this.#http, runId, query);
|
|
555
558
|
}
|
|
556
559
|
/** Short alias for `listOutputs`. */
|
|
557
|
-
outputs(runId) {
|
|
558
|
-
return this.listOutputs(runId);
|
|
560
|
+
outputs(runId, query) {
|
|
561
|
+
return this.listOutputs(runId, query);
|
|
562
|
+
}
|
|
563
|
+
findOutputs(runId, query) {
|
|
564
|
+
return operations.findOutputs(this.#http, runId, query);
|
|
565
|
+
}
|
|
566
|
+
findOutput(runId, query) {
|
|
567
|
+
return operations.findOutput(this.#http, runId, query);
|
|
568
|
+
}
|
|
569
|
+
outputLink(runId, selectorOrQuery, options) {
|
|
570
|
+
return operations.outputLink(this.#http, runId, selectorOrQuery, options);
|
|
571
|
+
}
|
|
572
|
+
createOutputLink(runId, selectorOrQuery, options) {
|
|
573
|
+
return this.outputLink(runId, selectorOrQuery, options);
|
|
574
|
+
}
|
|
575
|
+
async fetchOutput(runId, selectorOrQuery, options) {
|
|
576
|
+
const link = await this.outputLink(runId, selectorOrQuery, options);
|
|
577
|
+
return (this.#fetch ?? fetch)(link.url);
|
|
559
578
|
}
|
|
560
|
-
|
|
561
|
-
return operations.
|
|
579
|
+
eventArchiveLink(runId, options) {
|
|
580
|
+
return operations.eventArchiveLink(this.#http, runId, options);
|
|
562
581
|
}
|
|
563
582
|
async downloadOutput(runId, selectorOrOptions, options) {
|
|
564
583
|
const hasSelector = selectorOrOptions !== undefined && !isOutputDownloadOptionsOnly(selectorOrOptions);
|