@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/README.md
CHANGED
|
@@ -9,7 +9,7 @@ aex is an agent execution platform for launching autonomous agents from a simple
|
|
|
9
9
|
The package ships:
|
|
10
10
|
|
|
11
11
|
- `AgentExecutor` for submit, run, wait, stream, inspect, download, cancel, and delete.
|
|
12
|
-
- Typed run primitives: `Models`, `Providers`, `RuntimeSizes`, `Skill`, `AgentsMd`, `File`, `McpServer`, `ProxyEndpoint`, and `Secret`.
|
|
12
|
+
- Typed run primitives: `Models`, `Providers`, `RunRegions`, `RuntimeSizes`, `Skill`, `AgentsMd`, `File`, `McpServer`, `ProxyEndpoint`, and `Secret`.
|
|
13
13
|
- A bundled `aex` CLI with the same run, status, events, outputs, download, cancel, delete, whoami, and skills operations.
|
|
14
14
|
|
|
15
15
|
## Install
|
|
@@ -57,7 +57,7 @@ aex run \
|
|
|
57
57
|
|
|
58
58
|
## Feature Areas
|
|
59
59
|
|
|
60
|
-
- **Agent runtime:** managed autonomous runs with
|
|
60
|
+
- **Agent runtime:** managed autonomous runs with filesystem read/edit, grep/glob/head/tail, open web fetch/search defaults, optional notebook tools, and post-hook repair.
|
|
61
61
|
- **Durable infrastructure:** run records, status, wait/cancel/delete, idempotency, typed events, output capture, downloads, timeouts, and runtime sizes.
|
|
62
62
|
- **Agent composition:** skills, files, AGENTS.md, remote MCP servers, proxy endpoints, environment variables, packages, and networking controls.
|
|
63
63
|
- **Subagents:** typed parent/child lineage for async child runs, output handoff, and bounded agent delegation.
|
|
@@ -27,8 +27,10 @@ export async function* streamCoordinatorEvents(opts) {
|
|
|
27
27
|
let done = false;
|
|
28
28
|
while (!done && !opts.signal?.aborted) {
|
|
29
29
|
const ticket = await opts.fetchTicket();
|
|
30
|
-
const url =
|
|
31
|
-
|
|
30
|
+
const url = new URL(opts.wsUrl);
|
|
31
|
+
url.searchParams.set("ticket", ticket);
|
|
32
|
+
url.searchParams.set("from", String(cursor + 1));
|
|
33
|
+
const ws = makeWs(url.toString());
|
|
32
34
|
const queue = [];
|
|
33
35
|
let closed = false;
|
|
34
36
|
let disconnectReason = "";
|
|
@@ -18,7 +18,6 @@ export * from "./run-cost.js";
|
|
|
18
18
|
export * from "./run-custody.js";
|
|
19
19
|
export * from "./run-retention.js";
|
|
20
20
|
export * from "./side-effect-audit.js";
|
|
21
|
-
export * from "./managed-key.js";
|
|
22
21
|
export * from "./stable.js";
|
|
23
22
|
export * from "./sdk-secrets.js";
|
|
24
23
|
export * from "./sdk-errors.js";
|
package/dist/_contracts/index.js
CHANGED
|
@@ -18,7 +18,6 @@ export * from "./run-cost.js";
|
|
|
18
18
|
export * from "./run-custody.js";
|
|
19
19
|
export * from "./run-retention.js";
|
|
20
20
|
export * from "./side-effect-audit.js";
|
|
21
|
-
export * from "./managed-key.js";
|
|
22
21
|
export * from "./stable.js";
|
|
23
22
|
export * from "./sdk-secrets.js";
|
|
24
23
|
export * from "./sdk-errors.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { HttpClient } from "./http.js";
|
|
2
2
|
import type { RunUnit } from "./run-unit.js";
|
|
3
|
-
import type { AgentsMdRecord, FileRecord, Output, OutputFileDownload, OutputFileSelector, Run, RunEvent, SecretRecord, SecretReveal,
|
|
3
|
+
import type { AgentsMdRecord, FileRecord, Output, OutputLink, OutputLinkOptions, OutputFileDownload, OutputFileSelector, OutputFileType, OutputQuery, Run, RunEvent, SecretRecord, SecretReveal, Skill, WhoAmI } from "./runtime-types.js";
|
|
4
4
|
import type { PlatformRunSubmissionInput } from "./submission.js";
|
|
5
5
|
/**
|
|
6
6
|
* The single source of truth for SDK<->BFF transport. The SDK class
|
|
@@ -47,8 +47,13 @@ export interface CoordinatorTicket {
|
|
|
47
47
|
* coordinator is configured for the deployment (HTTP 503).
|
|
48
48
|
*/
|
|
49
49
|
export declare function getCoordinatorTicket(http: HttpClient, runId: string): Promise<CoordinatorTicket>;
|
|
50
|
-
export declare function listOutputs(http: HttpClient, runId: string): Promise<readonly Output[]>;
|
|
51
|
-
export declare function
|
|
50
|
+
export declare function listOutputs(http: HttpClient, runId: string, query?: OutputQuery): Promise<readonly Output[]>;
|
|
51
|
+
export declare function findOutputs(http: HttpClient, runId: string, query: OutputQuery): Promise<readonly Output[]>;
|
|
52
|
+
export declare function findOutput(http: HttpClient, runId: string, query: OutputQuery): Promise<Output | null>;
|
|
53
|
+
export type OutputLinkSelector = string | OutputFileSelector | OutputQuery;
|
|
54
|
+
export declare function outputLink(http: HttpClient, runId: string, selectorOrQuery: OutputLinkSelector, options?: OutputLinkOptions): Promise<OutputLink>;
|
|
55
|
+
export declare function createOutputLink(http: HttpClient, runId: string, selectorOrQuery: OutputLinkSelector, options?: OutputLinkOptions): Promise<OutputLink>;
|
|
56
|
+
export declare function eventArchiveLink(http: HttpClient, runId: string, options?: OutputLinkOptions): Promise<OutputLink>;
|
|
52
57
|
export declare function resolveOutputFileSelector(outputs: readonly Output[], selector: OutputFileSelector, runId?: string): Output;
|
|
53
58
|
export declare function downloadOutput(http: HttpClient, runId: string, selector: OutputFileSelector): Promise<OutputFileDownload>;
|
|
54
59
|
export declare function cancelRun(http: HttpClient, runId: string): Promise<void>;
|
|
@@ -61,6 +66,9 @@ export declare function deleteRun(http: HttpClient, runId: string): Promise<void
|
|
|
61
66
|
*/
|
|
62
67
|
export declare function deleteWorkspaceAsset(http: HttpClient, hash: string): Promise<void>;
|
|
63
68
|
export declare function whoami(http: HttpClient): Promise<WhoAmI>;
|
|
69
|
+
export declare function filterOutputs(outputs: readonly Output[], query: OutputQuery): readonly Output[];
|
|
70
|
+
export declare function classifyOutput(output: Pick<Output, "filename" | "contentType">): OutputFileType;
|
|
71
|
+
export declare function normalizeOutputLinkExpiresIn(input?: OutputLinkOptions["expiresIn"]): number;
|
|
64
72
|
/**
|
|
65
73
|
* Download EVERYTHING public about a run as one zip, organised into the three
|
|
66
74
|
* namespace folders:
|
|
@@ -64,12 +64,50 @@ export async function listRunEvents(http, runId) {
|
|
|
64
64
|
export async function getCoordinatorTicket(http, runId) {
|
|
65
65
|
return http.request(`/api/runs/${encodeURIComponent(runId)}/events/ticket`, { method: "POST" });
|
|
66
66
|
}
|
|
67
|
-
export async function listOutputs(http, runId) {
|
|
67
|
+
export async function listOutputs(http, runId, query) {
|
|
68
68
|
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/outputs`);
|
|
69
|
-
return result.outputs;
|
|
69
|
+
return query === undefined ? result.outputs : filterOutputs(result.outputs, query);
|
|
70
|
+
}
|
|
71
|
+
export async function findOutputs(http, runId, query) {
|
|
72
|
+
return listOutputs(http, runId, query);
|
|
73
|
+
}
|
|
74
|
+
export async function findOutput(http, runId, query) {
|
|
75
|
+
const matches = await findOutputs(http, runId, query);
|
|
76
|
+
if (matches.length === 0)
|
|
77
|
+
return null;
|
|
78
|
+
if (matches.length === 1)
|
|
79
|
+
return matches[0];
|
|
80
|
+
throw new RunStateError("findOutput: output query matched multiple files", {
|
|
81
|
+
runId,
|
|
82
|
+
matches: matches.map((output) => output.filename ?? output.id)
|
|
83
|
+
});
|
|
70
84
|
}
|
|
71
|
-
export async function
|
|
72
|
-
|
|
85
|
+
export async function outputLink(http, runId, selectorOrQuery, options) {
|
|
86
|
+
const output = await resolveOutputLinkTarget(http, runId, selectorOrQuery);
|
|
87
|
+
const expiresInSeconds = normalizeOutputLinkExpiresIn(options?.expiresIn);
|
|
88
|
+
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/outputs/${encodeURIComponent(output.id)}/link`, {
|
|
89
|
+
method: "POST",
|
|
90
|
+
body: JSON.stringify({ expiresInSeconds })
|
|
91
|
+
});
|
|
92
|
+
return {
|
|
93
|
+
...result,
|
|
94
|
+
expiresInSeconds: result.expiresInSeconds ?? expiresInSeconds,
|
|
95
|
+
output: result.output ?? output
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
export async function createOutputLink(http, runId, selectorOrQuery, options) {
|
|
99
|
+
return outputLink(http, runId, selectorOrQuery, options);
|
|
100
|
+
}
|
|
101
|
+
export async function eventArchiveLink(http, runId, options) {
|
|
102
|
+
const expiresInSeconds = normalizeOutputLinkExpiresIn(options?.expiresIn);
|
|
103
|
+
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/events/link`, {
|
|
104
|
+
method: "POST",
|
|
105
|
+
body: JSON.stringify({ expiresInSeconds })
|
|
106
|
+
});
|
|
107
|
+
return {
|
|
108
|
+
...result,
|
|
109
|
+
expiresInSeconds: result.expiresInSeconds ?? expiresInSeconds
|
|
110
|
+
};
|
|
73
111
|
}
|
|
74
112
|
export function resolveOutputFileSelector(outputs, selector, runId) {
|
|
75
113
|
if (isPathSelector(selector)) {
|
|
@@ -173,6 +211,178 @@ function isPathSelector(selector) {
|
|
|
173
211
|
function normalizeOutputLookupPath(path) {
|
|
174
212
|
return path.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
175
213
|
}
|
|
214
|
+
export function filterOutputs(outputs, query) {
|
|
215
|
+
return outputs.filter((output) => outputMatchesQuery(output, query));
|
|
216
|
+
}
|
|
217
|
+
export function classifyOutput(output) {
|
|
218
|
+
const contentType = normalizeContentType(output.contentType);
|
|
219
|
+
if (contentType) {
|
|
220
|
+
if (contentType === "application/json" || contentType.endsWith("+json") || contentType.includes("json")) {
|
|
221
|
+
return "json";
|
|
222
|
+
}
|
|
223
|
+
if (contentType.startsWith("text/"))
|
|
224
|
+
return "text";
|
|
225
|
+
if (contentType.startsWith("image/"))
|
|
226
|
+
return "image";
|
|
227
|
+
if (contentType.startsWith("audio/"))
|
|
228
|
+
return "audio";
|
|
229
|
+
if (contentType.startsWith("video/"))
|
|
230
|
+
return "video";
|
|
231
|
+
if (contentType === "application/pdf")
|
|
232
|
+
return "pdf";
|
|
233
|
+
if (contentType === "application/zip" ||
|
|
234
|
+
contentType === "application/gzip" ||
|
|
235
|
+
contentType === "application/x-gzip" ||
|
|
236
|
+
contentType === "application/x-tar" ||
|
|
237
|
+
contentType === "application/x-7z-compressed" ||
|
|
238
|
+
contentType === "application/vnd.rar" ||
|
|
239
|
+
contentType === "application/zstd") {
|
|
240
|
+
return "archive";
|
|
241
|
+
}
|
|
242
|
+
if (contentType === "application/octet-stream")
|
|
243
|
+
return "binary";
|
|
244
|
+
return "unknown";
|
|
245
|
+
}
|
|
246
|
+
const extension = extensionOf(output.filename);
|
|
247
|
+
if (!extension)
|
|
248
|
+
return "unknown";
|
|
249
|
+
if (["json", "jsonl", "ndjson"].includes(extension))
|
|
250
|
+
return "json";
|
|
251
|
+
if (["txt", "log", "md", "markdown", "csv", "tsv", "xml", "html", "htm", "yaml", "yml"].includes(extension)) {
|
|
252
|
+
return "text";
|
|
253
|
+
}
|
|
254
|
+
if (["png", "jpg", "jpeg", "gif", "webp", "avif", "bmp", "tif", "tiff", "svg"].includes(extension)) {
|
|
255
|
+
return "image";
|
|
256
|
+
}
|
|
257
|
+
if (["mp3", "wav", "flac", "m4a", "aac", "ogg", "oga", "opus"].includes(extension))
|
|
258
|
+
return "audio";
|
|
259
|
+
if (["mp4", "mov", "m4v", "webm", "mkv", "avi"].includes(extension))
|
|
260
|
+
return "video";
|
|
261
|
+
if (extension === "pdf")
|
|
262
|
+
return "pdf";
|
|
263
|
+
if (["zip", "tar", "tgz", "gz", "bz2", "xz", "7z", "rar", "zst"].includes(extension))
|
|
264
|
+
return "archive";
|
|
265
|
+
if (["bin", "exe", "dll", "so", "dylib", "dmg", "iso"].includes(extension))
|
|
266
|
+
return "binary";
|
|
267
|
+
return "unknown";
|
|
268
|
+
}
|
|
269
|
+
export function normalizeOutputLinkExpiresIn(input = "1h") {
|
|
270
|
+
if (typeof input === "number") {
|
|
271
|
+
if (!Number.isFinite(input) || input <= 0) {
|
|
272
|
+
throw new RunStateError("outputLink: expiresIn must be a positive number of seconds", {
|
|
273
|
+
expiresIn: input
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
return Math.floor(input);
|
|
277
|
+
}
|
|
278
|
+
if (input === "15m")
|
|
279
|
+
return 15 * 60;
|
|
280
|
+
if (input === "1h")
|
|
281
|
+
return 60 * 60;
|
|
282
|
+
if (input === "1d")
|
|
283
|
+
return 24 * 60 * 60;
|
|
284
|
+
throw new RunStateError("outputLink: expiresIn must be seconds, \"15m\", \"1h\", or \"1d\"", {
|
|
285
|
+
expiresIn: input
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
async function resolveOutputLinkTarget(http, runId, selectorOrQuery) {
|
|
289
|
+
if (typeof selectorOrQuery === "string") {
|
|
290
|
+
if (selectorOrQuery.length === 0) {
|
|
291
|
+
throw new RunStateError("outputLink: selector must include an output id or query", { runId });
|
|
292
|
+
}
|
|
293
|
+
return { id: selectorOrQuery };
|
|
294
|
+
}
|
|
295
|
+
if (hasOutputId(selectorOrQuery)) {
|
|
296
|
+
if (selectorOrQuery.id.length === 0) {
|
|
297
|
+
throw new RunStateError("outputLink: selector must include an output id or query", { runId });
|
|
298
|
+
}
|
|
299
|
+
return selectorOrQuery;
|
|
300
|
+
}
|
|
301
|
+
if (isPathSelector(selectorOrQuery) && selectorOrQuery.match === "suffix") {
|
|
302
|
+
return resolveOutputFileSelector(await listOutputs(http, runId), selectorOrQuery, runId);
|
|
303
|
+
}
|
|
304
|
+
const match = await findOutput(http, runId, selectorOrQuery);
|
|
305
|
+
if (match)
|
|
306
|
+
return match;
|
|
307
|
+
throw new RunStateError("outputLink: output query matched no files", { runId });
|
|
308
|
+
}
|
|
309
|
+
function outputMatchesQuery(output, query) {
|
|
310
|
+
const normalizedPath = typeof output.filename === "string" ? normalizeOutputQueryPath(output.filename) : "";
|
|
311
|
+
if (query.path !== undefined && normalizedPath !== normalizeOutputQueryPath(query.path)) {
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
if (query.filename !== undefined) {
|
|
315
|
+
const basename = basenameOf(normalizedPath);
|
|
316
|
+
if (typeof query.filename === "string") {
|
|
317
|
+
if (basename !== query.filename)
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
query.filename.lastIndex = 0;
|
|
322
|
+
if (!query.filename.test(basename))
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
if (query.dir !== undefined && !directoryMatches(normalizedPath, query.dir, query.recursive ?? true)) {
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
if (query.extension !== undefined && extensionOf(normalizedPath) !== normalizeExtension(query.extension)) {
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
if (query.contentType !== undefined && !contentTypeMatches(output.contentType, query.contentType)) {
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
if (query.type !== undefined && classifyOutput(output) !== query.type) {
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
return true;
|
|
339
|
+
}
|
|
340
|
+
function hasOutputId(value) {
|
|
341
|
+
return Boolean(value && typeof value === "object" && "id" in value && typeof value.id === "string");
|
|
342
|
+
}
|
|
343
|
+
function normalizeOutputQueryPath(path) {
|
|
344
|
+
let normalized = path.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
345
|
+
while (normalized === "outputs" || normalized.startsWith("outputs/")) {
|
|
346
|
+
normalized = normalized === "outputs" ? "" : normalized.slice("outputs/".length);
|
|
347
|
+
}
|
|
348
|
+
return normalized.replace(/\/+$/, "");
|
|
349
|
+
}
|
|
350
|
+
function basenameOf(path) {
|
|
351
|
+
return path.split("/").filter(Boolean).pop() ?? "";
|
|
352
|
+
}
|
|
353
|
+
function directoryMatches(path, dir, recursive) {
|
|
354
|
+
const normalizedDir = normalizeOutputQueryPath(dir);
|
|
355
|
+
if (normalizedDir.length === 0)
|
|
356
|
+
return true;
|
|
357
|
+
const prefix = `${normalizedDir}/`;
|
|
358
|
+
if (!path.startsWith(prefix))
|
|
359
|
+
return false;
|
|
360
|
+
const remainder = path.slice(prefix.length);
|
|
361
|
+
return remainder.length > 0 && (recursive || !remainder.includes("/"));
|
|
362
|
+
}
|
|
363
|
+
function normalizeExtension(extension) {
|
|
364
|
+
return extension.replace(/^\.+/, "").toLowerCase();
|
|
365
|
+
}
|
|
366
|
+
function extensionOf(path) {
|
|
367
|
+
if (!path)
|
|
368
|
+
return "";
|
|
369
|
+
const basename = basenameOf(normalizeOutputQueryPath(path));
|
|
370
|
+
const index = basename.lastIndexOf(".");
|
|
371
|
+
return index > 0 && index < basename.length - 1 ? basename.slice(index + 1).toLowerCase() : "";
|
|
372
|
+
}
|
|
373
|
+
function normalizeContentType(contentType) {
|
|
374
|
+
return (contentType ?? "").split(";")[0].trim().toLowerCase();
|
|
375
|
+
}
|
|
376
|
+
function contentTypeMatches(actual, expected) {
|
|
377
|
+
const normalizedActual = normalizeContentType(actual);
|
|
378
|
+
const normalizedExpected = normalizeContentType(expected);
|
|
379
|
+
if (!normalizedActual || !normalizedExpected)
|
|
380
|
+
return false;
|
|
381
|
+
if (normalizedExpected.endsWith("/*")) {
|
|
382
|
+
return normalizedActual.startsWith(normalizedExpected.slice(0, -1));
|
|
383
|
+
}
|
|
384
|
+
return normalizedActual === normalizedExpected;
|
|
385
|
+
}
|
|
176
386
|
/**
|
|
177
387
|
* Download EVERYTHING public about a run as one zip, organised into the three
|
|
178
388
|
* namespace folders:
|
|
@@ -468,7 +678,7 @@ export async function findSkillByName(http, name) {
|
|
|
468
678
|
return skills.find((skill) => skill.name === name) ?? null;
|
|
469
679
|
}
|
|
470
680
|
// ===========================================================================
|
|
471
|
-
// AgentsMd
|
|
681
|
+
// AgentsMd upload helpers. Launch submissions use content-addressed asset refs.
|
|
472
682
|
// ===========================================================================
|
|
473
683
|
/**
|
|
474
684
|
* Upload a workspace AgentsMd file as a markdown string. The BFF
|
|
@@ -505,7 +715,7 @@ function unwrapAgentsMd(result) {
|
|
|
505
715
|
return result;
|
|
506
716
|
}
|
|
507
717
|
// ===========================================================================
|
|
508
|
-
// File
|
|
718
|
+
// File upload helpers. Launch submissions use content-addressed asset refs.
|
|
509
719
|
// ===========================================================================
|
|
510
720
|
/**
|
|
511
721
|
* Upload a workspace File as a zip bundle. The BFF canonicalises the
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import type { RunProvider, RuntimeKind } from "./submission.js";
|
|
2
|
-
export declare const PROVIDER_SUPPORT_STATUSES: readonly ["supported", "rejected"];
|
|
3
|
-
export type ProviderSupportStatus = (typeof PROVIDER_SUPPORT_STATUSES)[number];
|
|
4
2
|
export interface SupportPointer {
|
|
5
3
|
readonly label: string;
|
|
6
4
|
/** Markdown href, relative to `packages/sdk/docs/provider-runtime-capabilities.md`. */
|
|
@@ -8,7 +6,6 @@ export interface SupportPointer {
|
|
|
8
6
|
}
|
|
9
7
|
export interface ProviderPublicSupport {
|
|
10
8
|
readonly displayName: string;
|
|
11
|
-
readonly status: ProviderSupportStatus;
|
|
12
9
|
readonly docsAnchor: string;
|
|
13
10
|
readonly docs: readonly SupportPointer[];
|
|
14
11
|
readonly evidence: readonly SupportPointer[];
|
|
@@ -36,13 +33,12 @@ export declare const RUNTIME_VALIDATION_SUPPORT: {
|
|
|
36
33
|
};
|
|
37
34
|
/**
|
|
38
35
|
* Public provider support facts for generated SDK docs. Keep this metadata
|
|
39
|
-
* public-facing only: provider names,
|
|
40
|
-
*
|
|
36
|
+
* public-facing only: provider names, docs anchors, and evidence pointers.
|
|
37
|
+
* Inclusion in this registry means the provider is supported.
|
|
41
38
|
*/
|
|
42
39
|
export declare const PROVIDER_PUBLIC_SUPPORT: {
|
|
43
40
|
readonly anthropic: {
|
|
44
41
|
readonly displayName: "Anthropic";
|
|
45
|
-
readonly status: "supported";
|
|
46
42
|
readonly docsAnchor: "anthropic";
|
|
47
43
|
readonly docs: readonly [{
|
|
48
44
|
readonly label: "Secrets";
|
|
@@ -79,7 +75,6 @@ export declare const PROVIDER_PUBLIC_SUPPORT: {
|
|
|
79
75
|
};
|
|
80
76
|
readonly deepseek: {
|
|
81
77
|
readonly displayName: "DeepSeek";
|
|
82
|
-
readonly status: "supported";
|
|
83
78
|
readonly docsAnchor: "deepseek";
|
|
84
79
|
readonly docs: readonly [{
|
|
85
80
|
readonly label: "Secrets";
|
|
@@ -122,7 +117,6 @@ export declare const PROVIDER_PUBLIC_SUPPORT: {
|
|
|
122
117
|
};
|
|
123
118
|
readonly openai: {
|
|
124
119
|
readonly displayName: "OpenAI";
|
|
125
|
-
readonly status: "supported";
|
|
126
120
|
readonly docsAnchor: "openai";
|
|
127
121
|
readonly docs: readonly [{
|
|
128
122
|
readonly label: "Secrets";
|
|
@@ -156,7 +150,6 @@ export declare const PROVIDER_PUBLIC_SUPPORT: {
|
|
|
156
150
|
};
|
|
157
151
|
readonly gemini: {
|
|
158
152
|
readonly displayName: "Gemini";
|
|
159
|
-
readonly status: "supported";
|
|
160
153
|
readonly docsAnchor: "gemini";
|
|
161
154
|
readonly docs: readonly [{
|
|
162
155
|
readonly label: "Secrets";
|
|
@@ -190,7 +183,6 @@ export declare const PROVIDER_PUBLIC_SUPPORT: {
|
|
|
190
183
|
};
|
|
191
184
|
readonly mistral: {
|
|
192
185
|
readonly displayName: "Mistral";
|
|
193
|
-
readonly status: "supported";
|
|
194
186
|
readonly docsAnchor: "mistral";
|
|
195
187
|
readonly docs: readonly [{
|
|
196
188
|
readonly label: "Secrets";
|
|
@@ -224,7 +216,6 @@ export declare const PROVIDER_PUBLIC_SUPPORT: {
|
|
|
224
216
|
};
|
|
225
217
|
readonly openrouter: {
|
|
226
218
|
readonly displayName: "OpenRouter";
|
|
227
|
-
readonly status: "supported";
|
|
228
219
|
readonly docsAnchor: "openrouter";
|
|
229
220
|
readonly docs: readonly [{
|
|
230
221
|
readonly label: "Secrets";
|
|
@@ -258,7 +249,6 @@ export declare const PROVIDER_PUBLIC_SUPPORT: {
|
|
|
258
249
|
};
|
|
259
250
|
readonly doubao: {
|
|
260
251
|
readonly displayName: "Doubao";
|
|
261
|
-
readonly status: "supported";
|
|
262
252
|
readonly docsAnchor: "doubao";
|
|
263
253
|
readonly docs: readonly [{
|
|
264
254
|
readonly label: "Secrets";
|
|
@@ -292,7 +282,6 @@ export declare const PROVIDER_PUBLIC_SUPPORT: {
|
|
|
292
282
|
};
|
|
293
283
|
readonly "doubao-cn": {
|
|
294
284
|
readonly displayName: "Doubao (China)";
|
|
295
|
-
readonly status: "supported";
|
|
296
285
|
readonly docsAnchor: "doubao-cn";
|
|
297
286
|
readonly docs: readonly [{
|
|
298
287
|
readonly label: "Secrets";
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
export const PROVIDER_SUPPORT_STATUSES = [
|
|
2
|
-
"supported",
|
|
3
|
-
"rejected"
|
|
4
|
-
];
|
|
5
1
|
const COMMON_DOCS = [
|
|
6
2
|
{ label: "Secrets", href: "secrets.md" },
|
|
7
3
|
{ label: "Events", href: "events.md" }
|
|
@@ -45,13 +41,12 @@ export const RUNTIME_VALIDATION_SUPPORT = {
|
|
|
45
41
|
};
|
|
46
42
|
/**
|
|
47
43
|
* Public provider support facts for generated SDK docs. Keep this metadata
|
|
48
|
-
* public-facing only: provider names,
|
|
49
|
-
*
|
|
44
|
+
* public-facing only: provider names, docs anchors, and evidence pointers.
|
|
45
|
+
* Inclusion in this registry means the provider is supported.
|
|
50
46
|
*/
|
|
51
47
|
export const PROVIDER_PUBLIC_SUPPORT = {
|
|
52
48
|
anthropic: {
|
|
53
49
|
displayName: "Anthropic",
|
|
54
|
-
status: "supported",
|
|
55
50
|
docsAnchor: "anthropic",
|
|
56
51
|
docs: COMMON_DOCS,
|
|
57
52
|
evidence: [...COMMON_EVIDENCE, ...ANTHROPIC_MANAGED_EVIDENCE],
|
|
@@ -61,7 +56,6 @@ export const PROVIDER_PUBLIC_SUPPORT = {
|
|
|
61
56
|
},
|
|
62
57
|
deepseek: {
|
|
63
58
|
displayName: "DeepSeek",
|
|
64
|
-
status: "supported",
|
|
65
59
|
docsAnchor: "deepseek",
|
|
66
60
|
docs: COMMON_DOCS,
|
|
67
61
|
evidence: [...COMMON_EVIDENCE, ...DEEPSEEK_MANAGED_EVIDENCE],
|
|
@@ -71,7 +65,6 @@ export const PROVIDER_PUBLIC_SUPPORT = {
|
|
|
71
65
|
},
|
|
72
66
|
openai: {
|
|
73
67
|
displayName: "OpenAI",
|
|
74
|
-
status: "supported",
|
|
75
68
|
docsAnchor: "openai",
|
|
76
69
|
docs: COMMON_DOCS,
|
|
77
70
|
evidence: COMMON_EVIDENCE,
|
|
@@ -81,7 +74,6 @@ export const PROVIDER_PUBLIC_SUPPORT = {
|
|
|
81
74
|
},
|
|
82
75
|
gemini: {
|
|
83
76
|
displayName: "Gemini",
|
|
84
|
-
status: "supported",
|
|
85
77
|
docsAnchor: "gemini",
|
|
86
78
|
docs: COMMON_DOCS,
|
|
87
79
|
evidence: COMMON_EVIDENCE,
|
|
@@ -91,7 +83,6 @@ export const PROVIDER_PUBLIC_SUPPORT = {
|
|
|
91
83
|
},
|
|
92
84
|
mistral: {
|
|
93
85
|
displayName: "Mistral",
|
|
94
|
-
status: "supported",
|
|
95
86
|
docsAnchor: "mistral",
|
|
96
87
|
docs: COMMON_DOCS,
|
|
97
88
|
evidence: COMMON_EVIDENCE,
|
|
@@ -101,7 +92,6 @@ export const PROVIDER_PUBLIC_SUPPORT = {
|
|
|
101
92
|
},
|
|
102
93
|
openrouter: {
|
|
103
94
|
displayName: "OpenRouter",
|
|
104
|
-
status: "supported",
|
|
105
95
|
docsAnchor: "openrouter",
|
|
106
96
|
docs: COMMON_DOCS,
|
|
107
97
|
evidence: COMMON_EVIDENCE,
|
|
@@ -112,7 +102,6 @@ export const PROVIDER_PUBLIC_SUPPORT = {
|
|
|
112
102
|
// Doubao (ByteDance) via the official Ark API — international BytePlus gateway.
|
|
113
103
|
doubao: {
|
|
114
104
|
displayName: "Doubao",
|
|
115
|
-
status: "supported",
|
|
116
105
|
docsAnchor: "doubao",
|
|
117
106
|
docs: COMMON_DOCS,
|
|
118
107
|
evidence: COMMON_EVIDENCE,
|
|
@@ -123,7 +112,6 @@ export const PROVIDER_PUBLIC_SUPPORT = {
|
|
|
123
112
|
// Doubao (ByteDance) via the official Ark API — China Volcengine gateway.
|
|
124
113
|
"doubao-cn": {
|
|
125
114
|
displayName: "Doubao (China)",
|
|
126
|
-
status: "supported",
|
|
127
115
|
docsAnchor: "doubao-cn",
|
|
128
116
|
docs: COMMON_DOCS,
|
|
129
117
|
evidence: COMMON_EVIDENCE,
|
|
@@ -134,14 +134,16 @@ export interface ProxyIndexEntry {
|
|
|
134
134
|
* default. A customer can opt into a per-response truncation cap by setting a
|
|
135
135
|
* positive value. There is no cumulative per-run call/byte budget: it needed a
|
|
136
136
|
* per-call counter on the hot path and only existed to bound memory, which
|
|
137
|
-
* streaming already does.
|
|
137
|
+
* streaming already does. The platform records named-proxy request bytes,
|
|
138
|
+
* response bytes, attempts, and retries as run-log usage telemetry only; no
|
|
139
|
+
* pricing/charging model is derived here.
|
|
138
140
|
*/
|
|
139
141
|
export declare const PROXY_ENDPOINT_DEFAULTS: {
|
|
140
142
|
readonly allowHeaders: readonly string[];
|
|
141
143
|
readonly responseMode: ProxyResponseMode;
|
|
142
144
|
readonly maxRequestBytes: number;
|
|
143
145
|
readonly maxResponseBytes: 0;
|
|
144
|
-
readonly timeoutMs:
|
|
146
|
+
readonly timeoutMs: number;
|
|
145
147
|
};
|
|
146
148
|
/**
|
|
147
149
|
* Non-secret endpoint policy the index builder consumes. Structurally a
|
|
@@ -140,16 +140,23 @@ export const PROXY_ERROR_CODES = [
|
|
|
140
140
|
* default. A customer can opt into a per-response truncation cap by setting a
|
|
141
141
|
* positive value. There is no cumulative per-run call/byte budget: it needed a
|
|
142
142
|
* per-call counter on the hot path and only existed to bound memory, which
|
|
143
|
-
* streaming already does.
|
|
143
|
+
* streaming already does. The platform records named-proxy request bytes,
|
|
144
|
+
* response bytes, attempts, and retries as run-log usage telemetry only; no
|
|
145
|
+
* pricing/charging model is derived here.
|
|
144
146
|
*/
|
|
145
147
|
export const PROXY_ENDPOINT_DEFAULTS = {
|
|
146
148
|
allowHeaders: [],
|
|
147
149
|
responseMode: "headers_only",
|
|
148
|
-
|
|
150
|
+
// 10 MiB. The body is buffered into the Worker to enforce this cap, while the
|
|
151
|
+
// launch default fits practical multimodal/tool POSTs without every endpoint
|
|
152
|
+
// needing an override.
|
|
153
|
+
maxRequestBytes: 10 * 1024 * 1024,
|
|
149
154
|
// Unlimited (0). The request body is buffered to enforce its cap, so that
|
|
150
155
|
// stays finite; the response is streamed, so it does not need one.
|
|
151
156
|
maxResponseBytes: 0,
|
|
152
|
-
|
|
157
|
+
// 5 minutes. Long-running upstream tool/model calls should not fail under a
|
|
158
|
+
// development-oriented 10s ceiling; endpoints can still set a smaller value.
|
|
159
|
+
timeoutMs: 5 * 60 * 1000
|
|
153
160
|
};
|
|
154
161
|
/**
|
|
155
162
|
* Build the per-run {@link ProxyIndexFile} mounted into the container at
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* Keep this as the public source of truth for the SDK/CLI composition
|
|
31
31
|
* boundary.
|
|
32
32
|
*/
|
|
33
|
-
import type
|
|
33
|
+
import { type JsonValue, type PlatformProxyEndpoint, type PlatformEnvironment, type RunRegion } from "./submission.js";
|
|
34
34
|
import { type RunModel } from "./models.js";
|
|
35
35
|
import type { RuntimeSize } from "./runtime-sizes.js";
|
|
36
36
|
import { type PlatformPostHookInput } from "./post-hook.js";
|
|
@@ -164,10 +164,10 @@ export declare function parseSkillRef(input: unknown, path: string): SkillRef;
|
|
|
164
164
|
*/
|
|
165
165
|
export declare function parseAssetRefFields(record: Record<string, unknown>, path: string): AssetRef;
|
|
166
166
|
/**
|
|
167
|
-
* Manifest entry persisted in `skill_bundles.manifest` and
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
167
|
+
* Manifest entry persisted in `skill_bundles.manifest` and in run-owned
|
|
168
|
+
* snapshots. `path` is forward-slash, relative, normalised. `mode` is the
|
|
169
|
+
* stored POSIX mode (sanitised, NOT the user's filesystem mode) — see
|
|
170
|
+
* `SKILL_BUNDLE_LIMITS.defaultFileMode`.
|
|
171
171
|
*/
|
|
172
172
|
export interface SkillBundleEntry {
|
|
173
173
|
readonly path: string;
|
|
@@ -308,6 +308,8 @@ export interface RunRequestConfig {
|
|
|
308
308
|
readonly environment?: PlatformEnvironment;
|
|
309
309
|
/** Managed runtime size preset (see {@link RuntimeSize}). */
|
|
310
310
|
readonly runtimeSize?: RuntimeSize;
|
|
311
|
+
/** Product placement token. Omitted lets the hosted platform infer/fallback. */
|
|
312
|
+
readonly region?: RunRegion;
|
|
311
313
|
/** Run deadline as a duration string (`"1h"`, `"30m"`); bounded [1m, 6h] server-side. */
|
|
312
314
|
readonly timeout?: string;
|
|
313
315
|
/** Post-agent-run verifier command. Empty command is treated as omitted. */
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
* Keep this as the public source of truth for the SDK/CLI composition
|
|
31
31
|
* boundary.
|
|
32
32
|
*/
|
|
33
|
+
import { parseRunRegion, } from "./submission.js";
|
|
33
34
|
import { parseRunModel } from "./models.js";
|
|
34
35
|
import { parsePostHook } from "./post-hook.js";
|
|
35
36
|
// ---------------------------------------------------------------------------
|
|
@@ -66,13 +67,13 @@ export const TOOL_NAME_PATTERN = SKILL_NAME_PATTERN;
|
|
|
66
67
|
*/
|
|
67
68
|
export const SKILL_BUNDLE_LIMITS = {
|
|
68
69
|
/** Compressed (.zip) ceiling. */
|
|
69
|
-
maxCompressedBytes: 10 * 1024 * 1024,
|
|
70
|
+
maxCompressedBytes: 10 * 1024 * 1024 * 1024,
|
|
70
71
|
/**
|
|
71
72
|
* Hard ceiling for the direct-to-storage upload path. Bytes never transit the
|
|
72
73
|
* hosted API, so its memory/request-payload limits do not cap accepted
|
|
73
74
|
* bundles; objects above this product cap are rejected before upload.
|
|
74
75
|
*/
|
|
75
|
-
maxBytes:
|
|
76
|
+
maxBytes: 10 * 1024 * 1024 * 1024,
|
|
76
77
|
/** Sum of uncompressed file sizes. */
|
|
77
78
|
maxDecompressedBytes: 50 * 1024 * 1024,
|
|
78
79
|
/** Number of regular file entries (directories don't count). */
|
|
@@ -471,11 +472,10 @@ export function rejectStdioMcpShape(record) {
|
|
|
471
472
|
/**
|
|
472
473
|
* Reasons an IP-literal host should be refused. Returns null when the
|
|
473
474
|
* literal is a routable public address (or not an IP literal at all — name
|
|
474
|
-
* resolution is the caller's concern). This
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
* `submission.parseProxyBaseUrl` all classify the same bytes.
|
|
475
|
+
* resolution is the caller's concern). This numeric-range deny-list is kept
|
|
476
|
+
* in parity across the public contract parser and platform shared parser so
|
|
477
|
+
* the MCP parser, BYOK proxy handlers, and `submission.parseProxyBaseUrl`
|
|
478
|
+
* classify the same bytes.
|
|
479
479
|
*
|
|
480
480
|
* `host` is the already-bracket-stripped, lowercased hostname.
|
|
481
481
|
*
|
|
@@ -651,6 +651,7 @@ export function parseRunRequestConfig(input) {
|
|
|
651
651
|
"mcpServers",
|
|
652
652
|
"environment",
|
|
653
653
|
"runtimeSize",
|
|
654
|
+
"region",
|
|
654
655
|
"timeout",
|
|
655
656
|
"postHook",
|
|
656
657
|
"proxyEndpoints",
|
|
@@ -669,6 +670,7 @@ export function parseRunRequestConfig(input) {
|
|
|
669
670
|
const prompt = parseRunRequestConfigPrompt(record.prompt);
|
|
670
671
|
const skills = parseRunRequestConfigSkills(record.skills);
|
|
671
672
|
const mcpServers = parseRunRequestConfigMcpServers(record.mcpServers);
|
|
673
|
+
const region = parseRunRegion(record.region);
|
|
672
674
|
const postHook = parsePostHook(record.postHook, "run request config postHook");
|
|
673
675
|
return {
|
|
674
676
|
model,
|
|
@@ -686,6 +688,7 @@ export function parseRunRequestConfig(input) {
|
|
|
686
688
|
...(record.runtimeSize !== undefined
|
|
687
689
|
? { runtimeSize: record.runtimeSize }
|
|
688
690
|
: {}),
|
|
691
|
+
...(region !== undefined ? { region } : {}),
|
|
689
692
|
...(record.timeout !== undefined
|
|
690
693
|
? { timeout: record.timeout }
|
|
691
694
|
: {}),
|