@aexhq/sdk 0.30.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -9
- package/dist/_contracts/connection-ticket.d.ts +1 -1
- package/dist/_contracts/connection-ticket.js +1 -1
- package/dist/_contracts/event-envelope.d.ts +5 -8
- package/dist/_contracts/event-envelope.js +5 -6
- package/dist/_contracts/event-stream-client.d.ts +1 -1
- package/dist/_contracts/http.js +1 -1
- package/dist/_contracts/models.d.ts +0 -76
- package/dist/_contracts/models.js +0 -20
- package/dist/_contracts/operations.d.ts +2 -64
- package/dist/_contracts/operations.js +9 -152
- package/dist/_contracts/provider-support.d.ts +48 -138
- package/dist/_contracts/provider-support.js +10 -41
- package/dist/_contracts/proxy-protocol.d.ts +7 -7
- package/dist/_contracts/proxy-protocol.js +8 -8
- package/dist/_contracts/run-config.d.ts +7 -20
- package/dist/_contracts/run-config.js +8 -46
- package/dist/_contracts/run-cost.d.ts +1 -5
- package/dist/_contracts/run-cost.js +0 -8
- package/dist/_contracts/run-custody.d.ts +4 -6
- package/dist/_contracts/run-custody.js +0 -8
- package/dist/_contracts/run-unit.d.ts +1 -1
- package/dist/_contracts/run-unit.js +6 -6
- package/dist/_contracts/runner-event.d.ts +1 -1
- package/dist/_contracts/runner-event.js +1 -1
- package/dist/_contracts/runtime-manifest.d.ts +13 -26
- package/dist/_contracts/runtime-manifest.js +6 -35
- package/dist/_contracts/runtime-types.d.ts +1 -3
- package/dist/_contracts/sdk-secrets.js +4 -4
- package/dist/_contracts/side-effect-audit.d.ts +2 -4
- package/dist/_contracts/side-effect-audit.js +2 -4
- package/dist/_contracts/status.d.ts +1 -1
- package/dist/_contracts/status.js +1 -1
- package/dist/_contracts/submission.d.ts +5 -126
- package/dist/_contracts/submission.js +10 -182
- package/dist/_contracts/webhook-verify.d.ts +1 -1
- package/dist/_contracts/webhook-verify.js +1 -1
- package/dist/asset-upload.d.ts +4 -10
- package/dist/asset-upload.js +4 -47
- package/dist/asset-upload.js.map +1 -1
- package/dist/cli.mjs +27 -231
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +10 -107
- package/dist/client.js +23 -132
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/skill.d.ts +1 -1
- package/dist/skill.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/cleanup.md +4 -4
- package/docs/concepts/agent-tools.md +2 -2
- package/docs/concepts/composition.md +1 -1
- package/docs/concepts/providers-and-runtimes.md +2 -4
- package/docs/concepts/runs.md +3 -6
- package/docs/credentials.md +5 -8
- package/docs/defaults.md +22 -22
- package/docs/limits-and-quotas.md +40 -40
- package/docs/limits.md +1 -1
- package/docs/networking.md +2 -2
- package/docs/outputs.md +3 -3
- package/docs/provider-runtime-capabilities.md +37 -65
- package/docs/public-surface.json +4 -5
- package/docs/quickstart.md +19 -6
- package/docs/run-config.md +5 -6
- package/docs/secrets.md +9 -7
- package/docs/skills.md +8 -16
- package/docs/vision-skills.md +3 -3
- package/package.json +2 -2
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`, `
|
|
12
|
+
- Typed run primitives: `Models`, `Providers`, `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
|
|
@@ -18,6 +18,15 @@ The package ships:
|
|
|
18
18
|
bun add @aexhq/sdk
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
+
This installs the TypeScript SDK exports and the bundled `aex` CLI. Set both
|
|
22
|
+
credentials before running the examples: `AEX_API_TOKEN` authenticates to aex,
|
|
23
|
+
and `ANTHROPIC_API_KEY` is your BYOK provider key for Claude.
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
export AEX_API_TOKEN="<your-aex-token>"
|
|
27
|
+
export ANTHROPIC_API_KEY="<your-anthropic-api-key>"
|
|
28
|
+
```
|
|
29
|
+
|
|
21
30
|
## First Run
|
|
22
31
|
|
|
23
32
|
```ts
|
|
@@ -29,7 +38,7 @@ const aex = new AgentExecutor({ apiToken: process.env.AEX_API_TOKEN! });
|
|
|
29
38
|
// no manual poll loop. `provider` is derived from the model.
|
|
30
39
|
const { text, ok } = await aex.run({
|
|
31
40
|
model: Models.CLAUDE_HAIKU_4_5,
|
|
32
|
-
|
|
41
|
+
secrets: { apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! } },
|
|
33
42
|
prompt: "Summarize this repo."
|
|
34
43
|
});
|
|
35
44
|
|
|
@@ -41,7 +50,7 @@ Need the run id, live events, or downloads? Use `submit` + `stream` + `wait`:
|
|
|
41
50
|
```ts
|
|
42
51
|
const runId = await aex.submit({
|
|
43
52
|
model: Models.CLAUDE_HAIKU_4_5,
|
|
44
|
-
|
|
53
|
+
secrets: { apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! } },
|
|
45
54
|
prompt: "Write the report and save outputs."
|
|
46
55
|
});
|
|
47
56
|
|
|
@@ -55,18 +64,23 @@ console.log(run.status);
|
|
|
55
64
|
await aex.download(runId, { to: "./run.zip" });
|
|
56
65
|
```
|
|
57
66
|
|
|
58
|
-
For multiple providers (e.g. subagents on a different model family),
|
|
59
|
-
|
|
67
|
+
For multiple providers (e.g. subagents on a different model family), include
|
|
68
|
+
each BYOK key in `secrets.apiKeys`:
|
|
60
69
|
|
|
61
70
|
```ts
|
|
62
71
|
await aex.run({
|
|
63
72
|
model: Models.CLAUDE_HAIKU_4_5,
|
|
64
|
-
|
|
73
|
+
secrets: {
|
|
74
|
+
apiKeys: {
|
|
75
|
+
anthropic: process.env.ANTHROPIC_API_KEY!,
|
|
76
|
+
openai: process.env.OPENAI_API_KEY!
|
|
77
|
+
}
|
|
78
|
+
},
|
|
65
79
|
prompt: "Delegate research to a subagent."
|
|
66
80
|
});
|
|
67
81
|
```
|
|
68
82
|
|
|
69
|
-
The same request can run from the CLI:
|
|
83
|
+
The same request can run from the bundled CLI:
|
|
70
84
|
|
|
71
85
|
```bash
|
|
72
86
|
aex run \
|
|
@@ -104,8 +118,8 @@ aex runtime-sizes list # managed runtime presets (cpus / memory / default)
|
|
|
104
118
|
Errors are typed and actionable. Every `submit()` config-validation failure throws
|
|
105
119
|
a `RunConfigValidationError` (`err.code === "RUN_CONFIG_INVALID"`) you can `catch`
|
|
106
120
|
by code; CLI failures print a JSON envelope carrying the HTTP `status`, a one-line
|
|
107
|
-
`remedy`, and the `runId` where known, and a wrong `--model
|
|
108
|
-
`--runtime-size
|
|
121
|
+
`remedy`, and the `runId` where known, and a wrong `--model`, `--provider`, or
|
|
122
|
+
`--runtime-size` gets a "did you mean?" suggestion.
|
|
109
123
|
|
|
110
124
|
## Chat over a corpus of runs
|
|
111
125
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* This lives in shared so the coordinator (which verifies) and the API
|
|
12
12
|
* hosted API's ticket broker (which mints, on behalf of a workspace token) use
|
|
13
|
-
* ONE implementation. Pure Web Crypto — identical under Bun
|
|
13
|
+
* ONE implementation. Pure Web Crypto — identical under Bun and Node.
|
|
14
14
|
*/
|
|
15
15
|
export type ConnectionTicketChannel = "event" | "log" | "all";
|
|
16
16
|
/** Mint a `${channel}.${exp}.${mac}` ticket valid for `ttlMs` from `nowMs`. */
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* This lives in shared so the coordinator (which verifies) and the API
|
|
12
12
|
* hosted API's ticket broker (which mints, on behalf of a workspace token) use
|
|
13
|
-
* ONE implementation. Pure Web Crypto — identical under Bun
|
|
13
|
+
* ONE implementation. Pure Web Crypto — identical under Bun and Node.
|
|
14
14
|
*/
|
|
15
15
|
const DEFAULT_TICKET_TTL_MS = 60_000;
|
|
16
16
|
const encoder = new TextEncoder();
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* coordinator:
|
|
22
22
|
* - `channel` — "event" (the typed AG-UI stream) or "log" (a verbose log
|
|
23
23
|
* line). The single axis a consumer splits the unified stream
|
|
24
|
-
* on.
|
|
24
|
+
* on.
|
|
25
25
|
* - `sourceSeq` — a per-SOURCE monotonic counter assigned AT the source. The
|
|
26
26
|
* DO's hard guarantee is that records of the same source are
|
|
27
27
|
* never reordered relative to their `sourceSeq`.
|
|
@@ -33,9 +33,8 @@
|
|
|
33
33
|
* `sequence` on arrival, which is the canonical stream order. `sourceSeq` /
|
|
34
34
|
* `emittedAt` are CARRIED through broadcast + archive, not used to reorder.
|
|
35
35
|
*
|
|
36
|
-
* This module is
|
|
37
|
-
*
|
|
38
|
-
* AG-UI projection for consumers.
|
|
36
|
+
* This module is a pure projection plus honest guards and a strict AG-UI
|
|
37
|
+
* projection for consumers.
|
|
39
38
|
*/
|
|
40
39
|
import type { JsonValue } from "./submission.js";
|
|
41
40
|
import type { RunnerEvent } from "./runner-event.js";
|
|
@@ -51,7 +50,7 @@ export declare const AEX_EVENT_MAP_VERSION: 1;
|
|
|
51
50
|
/**
|
|
52
51
|
* Coarse origin classifier — the first axis a consumer filters on.
|
|
53
52
|
* - `agent` — the model: text, reasoning, builtin tool calls/results.
|
|
54
|
-
* - `
|
|
53
|
+
* - `api` — the hosted aex API path.
|
|
55
54
|
* - `runtime` — the execution runtime: lifecycle, diagnostics, non-fatal
|
|
56
55
|
* stream errors.
|
|
57
56
|
* - `mcp` — an MCP server (a tool call/result routed through MCP).
|
|
@@ -60,7 +59,7 @@ export declare const AEX_EVENT_MAP_VERSION: 1;
|
|
|
60
59
|
* - `host` — the managed host the runtime executes on; distinct from the
|
|
61
60
|
* runtime process itself.
|
|
62
61
|
*/
|
|
63
|
-
export declare const AEX_EVENT_SOURCES: readonly ["agent", "
|
|
62
|
+
export declare const AEX_EVENT_SOURCES: readonly ["agent", "api", "runtime", "mcp", "aex", "workflow", "host"];
|
|
64
63
|
export type AexEventSource = (typeof AEX_EVENT_SOURCES)[number];
|
|
65
64
|
/**
|
|
66
65
|
* The channel a record rides on the unified per-run stream:
|
|
@@ -134,8 +133,6 @@ export interface AexEvent {
|
|
|
134
133
|
* as the authoritative receive marker. It does NOT need to exceed `emittedAt`:
|
|
135
134
|
* the source runs on a different host with an independent clock, so cross-host
|
|
136
135
|
* drift can leave `receivedAt < emittedAt` and that is expected, not an error.
|
|
137
|
-
* Absent on records produced before this field existed (back-compat with
|
|
138
|
-
* archived records).
|
|
139
136
|
*/
|
|
140
137
|
readonly receivedAt?: number;
|
|
141
138
|
/**
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* coordinator:
|
|
22
22
|
* - `channel` — "event" (the typed AG-UI stream) or "log" (a verbose log
|
|
23
23
|
* line). The single axis a consumer splits the unified stream
|
|
24
|
-
* on.
|
|
24
|
+
* on.
|
|
25
25
|
* - `sourceSeq` — a per-SOURCE monotonic counter assigned AT the source. The
|
|
26
26
|
* DO's hard guarantee is that records of the same source are
|
|
27
27
|
* never reordered relative to their `sourceSeq`.
|
|
@@ -33,9 +33,8 @@
|
|
|
33
33
|
* `sequence` on arrival, which is the canonical stream order. `sourceSeq` /
|
|
34
34
|
* `emittedAt` are CARRIED through broadcast + archive, not used to reorder.
|
|
35
35
|
*
|
|
36
|
-
* This module is
|
|
37
|
-
*
|
|
38
|
-
* AG-UI projection for consumers.
|
|
36
|
+
* This module is a pure projection plus honest guards and a strict AG-UI
|
|
37
|
+
* projection for consumers.
|
|
39
38
|
*/
|
|
40
39
|
/** CloudEvents `specversion` the envelope conforms to. */
|
|
41
40
|
export const AEX_EVENT_SPECVERSION = "1.0";
|
|
@@ -49,7 +48,7 @@ export const AEX_EVENT_MAP_VERSION = 1;
|
|
|
49
48
|
/**
|
|
50
49
|
* Coarse origin classifier — the first axis a consumer filters on.
|
|
51
50
|
* - `agent` — the model: text, reasoning, builtin tool calls/results.
|
|
52
|
-
* - `
|
|
51
|
+
* - `api` — the hosted aex API path.
|
|
53
52
|
* - `runtime` — the execution runtime: lifecycle, diagnostics, non-fatal
|
|
54
53
|
* stream errors.
|
|
55
54
|
* - `mcp` — an MCP server (a tool call/result routed through MCP).
|
|
@@ -58,7 +57,7 @@ export const AEX_EVENT_MAP_VERSION = 1;
|
|
|
58
57
|
* - `host` — the managed host the runtime executes on; distinct from the
|
|
59
58
|
* runtime process itself.
|
|
60
59
|
*/
|
|
61
|
-
export const AEX_EVENT_SOURCES = ["agent", "
|
|
60
|
+
export const AEX_EVENT_SOURCES = ["agent", "api", "runtime", "mcp", "aex", "workflow", "host"];
|
|
62
61
|
/**
|
|
63
62
|
* The channel a record rides on the unified per-run stream:
|
|
64
63
|
* - `event` — the typed, low-volume, fully-replayed AG-UI event stream.
|
|
@@ -65,7 +65,7 @@ export interface CoordinatorStreamOptions {
|
|
|
65
65
|
readonly idleTimeoutMs?: number;
|
|
66
66
|
/**
|
|
67
67
|
* Client keep-alive ping cadence. The client sends {@link COORDINATOR_PING},
|
|
68
|
-
* which the coordinator auto-responds to WITHOUT waking the
|
|
68
|
+
* which the coordinator auto-responds to WITHOUT waking the stateful coordinator, so
|
|
69
69
|
* a legitimately quiet run keeps the socket measurably alive and does not trip
|
|
70
70
|
* the watchdog. Default 15s. Set 0 to disable (then only real events reset the
|
|
71
71
|
* watchdog → quiet runs may reconnect).
|
package/dist/_contracts/http.js
CHANGED
|
@@ -103,7 +103,7 @@ function extractErrorMessage(body) {
|
|
|
103
103
|
if (typeof message === "string")
|
|
104
104
|
return message;
|
|
105
105
|
}
|
|
106
|
-
// aex
|
|
106
|
+
// aex API error envelope: `{ ok:false, code, message }`. Surface
|
|
107
107
|
// the server's message so structured rejections (e.g. runtime support)
|
|
108
108
|
// aren't flattened to the generic fallback below.
|
|
109
109
|
if (typeof obj.message === "string")
|
|
@@ -36,12 +36,6 @@ export declare const MODEL_PROVIDER_IDS: {
|
|
|
36
36
|
readonly "deepseek-v4-pro": {
|
|
37
37
|
readonly deepseek: "deepseek-v4-pro";
|
|
38
38
|
};
|
|
39
|
-
readonly "deepseek-chat": {
|
|
40
|
-
readonly deepseek: "deepseek-chat";
|
|
41
|
-
};
|
|
42
|
-
readonly "deepseek-reasoner": {
|
|
43
|
-
readonly deepseek: "deepseek-reasoner";
|
|
44
|
-
};
|
|
45
39
|
readonly "gpt-4.1": {
|
|
46
40
|
readonly openai: "gpt-4.1";
|
|
47
41
|
};
|
|
@@ -102,76 +96,6 @@ export declare const Models: {
|
|
|
102
96
|
readonly DEEPSEEK_V4_FLASH: "deepseek-v4-flash";
|
|
103
97
|
/** DeepSeek V4 Pro — DeepSeek (reasoning-heavy). */
|
|
104
98
|
readonly DEEPSEEK_V4_PRO: "deepseek-v4-pro";
|
|
105
|
-
/**
|
|
106
|
-
* @deprecated Legacy alias DeepSeek routes to `deepseek-v4-flash` (non-thinking).
|
|
107
|
-
* DeepSeek removes this name on 2026-07-24 15:59 UTC — migrate to
|
|
108
|
-
* {@link Models.DEEPSEEK_V4_FLASH}.
|
|
109
|
-
*/
|
|
110
|
-
readonly DEEPSEEK_CHAT: "deepseek-chat";
|
|
111
|
-
/**
|
|
112
|
-
* @deprecated Legacy alias DeepSeek routes to `deepseek-v4-flash` (thinking).
|
|
113
|
-
* DeepSeek removes this name on 2026-07-24 15:59 UTC — migrate to
|
|
114
|
-
* {@link Models.DEEPSEEK_V4_FLASH} (or {@link Models.DEEPSEEK_V4_PRO} for
|
|
115
|
-
* heavier reasoning).
|
|
116
|
-
*/
|
|
117
|
-
readonly DEEPSEEK_REASONER: "deepseek-reasoner";
|
|
118
|
-
/** GPT-4.1 — OpenAI. */
|
|
119
|
-
readonly GPT_4_1: "gpt-4.1";
|
|
120
|
-
/** GPT-4o mini — OpenAI, or via OpenRouter (`provider: Providers.OPENROUTER`). */
|
|
121
|
-
readonly GPT_4O_MINI: "gpt-4o-mini";
|
|
122
|
-
/** GPT-4o — via OpenRouter (`provider: Providers.OPENROUTER`). */
|
|
123
|
-
readonly GPT_4O: "gpt-4o";
|
|
124
|
-
/** Gemini 2.0 Flash — Gemini, or via OpenRouter (`provider: Providers.OPENROUTER`). */
|
|
125
|
-
readonly GEMINI_2_0_FLASH: "gemini-2.0-flash";
|
|
126
|
-
/** Gemini 2.5 Flash — Gemini. */
|
|
127
|
-
readonly GEMINI_2_5_FLASH: "gemini-2.5-flash";
|
|
128
|
-
/** Mistral Large (latest) — Mistral. */
|
|
129
|
-
readonly MISTRAL_LARGE_LATEST: "mistral-large-latest";
|
|
130
|
-
/** Mistral Small (latest) — Mistral. */
|
|
131
|
-
readonly MISTRAL_SMALL_LATEST: "mistral-small-latest";
|
|
132
|
-
/**
|
|
133
|
-
* Doubao Seed 1.8 — ByteDance, via the official Ark API. Default routes
|
|
134
|
-
* through the international BytePlus gateway (`Providers.DOUBAO`); pair with
|
|
135
|
-
* `Providers.DOUBAO_CN` for the China Volcengine gateway.
|
|
136
|
-
*/
|
|
137
|
-
readonly DOUBAO_SEED_PRO: "doubao-seed-pro";
|
|
138
|
-
/**
|
|
139
|
-
* Doubao Seed 1.6 Flash — ByteDance, via the official Ark API (fast/cheap).
|
|
140
|
-
* Default `Providers.DOUBAO` (international); pair with `Providers.DOUBAO_CN`
|
|
141
|
-
* for China.
|
|
142
|
-
*/
|
|
143
|
-
readonly DOUBAO_SEED_FLASH: "doubao-seed-flash";
|
|
144
|
-
};
|
|
145
|
-
/**
|
|
146
|
-
* Back-compat alias for {@link Models}. Existing imports of `RunModels`
|
|
147
|
-
* keep working; new code should prefer `Models`.
|
|
148
|
-
*/
|
|
149
|
-
export declare const RunModels: {
|
|
150
|
-
/** Claude Haiku 4.5 — Anthropic. */
|
|
151
|
-
readonly CLAUDE_HAIKU_4_5: "claude-haiku-4-5";
|
|
152
|
-
/** Claude 3.5 Haiku (latest) — Anthropic. */
|
|
153
|
-
readonly CLAUDE_3_5_HAIKU_LATEST: "claude-3-5-haiku-latest";
|
|
154
|
-
/** Claude 3.5 Sonnet (latest) — Anthropic. */
|
|
155
|
-
readonly CLAUDE_3_5_SONNET_LATEST: "claude-3-5-sonnet-latest";
|
|
156
|
-
/** Claude Sonnet 4.6 — Anthropic (1M context, reasoning-capable). */
|
|
157
|
-
readonly CLAUDE_SONNET_4_6: "claude-sonnet-4-6";
|
|
158
|
-
/** DeepSeek V4 Flash — DeepSeek (non-thinking, fast). */
|
|
159
|
-
readonly DEEPSEEK_V4_FLASH: "deepseek-v4-flash";
|
|
160
|
-
/** DeepSeek V4 Pro — DeepSeek (reasoning-heavy). */
|
|
161
|
-
readonly DEEPSEEK_V4_PRO: "deepseek-v4-pro";
|
|
162
|
-
/**
|
|
163
|
-
* @deprecated Legacy alias DeepSeek routes to `deepseek-v4-flash` (non-thinking).
|
|
164
|
-
* DeepSeek removes this name on 2026-07-24 15:59 UTC — migrate to
|
|
165
|
-
* {@link Models.DEEPSEEK_V4_FLASH}.
|
|
166
|
-
*/
|
|
167
|
-
readonly DEEPSEEK_CHAT: "deepseek-chat";
|
|
168
|
-
/**
|
|
169
|
-
* @deprecated Legacy alias DeepSeek routes to `deepseek-v4-flash` (thinking).
|
|
170
|
-
* DeepSeek removes this name on 2026-07-24 15:59 UTC — migrate to
|
|
171
|
-
* {@link Models.DEEPSEEK_V4_FLASH} (or {@link Models.DEEPSEEK_V4_PRO} for
|
|
172
|
-
* heavier reasoning).
|
|
173
|
-
*/
|
|
174
|
-
readonly DEEPSEEK_REASONER: "deepseek-reasoner";
|
|
175
99
|
/** GPT-4.1 — OpenAI. */
|
|
176
100
|
readonly GPT_4_1: "gpt-4.1";
|
|
177
101
|
/** GPT-4o mini — OpenAI, or via OpenRouter (`provider: Providers.OPENROUTER`). */
|
|
@@ -23,8 +23,6 @@ export const MODEL_PROVIDER_IDS = {
|
|
|
23
23
|
"claude-sonnet-4-6": { anthropic: "claude-sonnet-4-6" },
|
|
24
24
|
"deepseek-v4-flash": { deepseek: "deepseek-v4-flash" },
|
|
25
25
|
"deepseek-v4-pro": { deepseek: "deepseek-v4-pro" },
|
|
26
|
-
"deepseek-chat": { deepseek: "deepseek-chat" },
|
|
27
|
-
"deepseek-reasoner": { deepseek: "deepseek-reasoner" },
|
|
28
26
|
"gpt-4.1": { openai: "gpt-4.1" },
|
|
29
27
|
"gpt-4o-mini": { openai: "gpt-4o-mini", openrouter: "openai/gpt-4o-mini" },
|
|
30
28
|
"gpt-4o": { openrouter: "openai/gpt-4o" },
|
|
@@ -69,19 +67,6 @@ export const Models = {
|
|
|
69
67
|
DEEPSEEK_V4_FLASH: "deepseek-v4-flash",
|
|
70
68
|
/** DeepSeek V4 Pro — DeepSeek (reasoning-heavy). */
|
|
71
69
|
DEEPSEEK_V4_PRO: "deepseek-v4-pro",
|
|
72
|
-
/**
|
|
73
|
-
* @deprecated Legacy alias DeepSeek routes to `deepseek-v4-flash` (non-thinking).
|
|
74
|
-
* DeepSeek removes this name on 2026-07-24 15:59 UTC — migrate to
|
|
75
|
-
* {@link Models.DEEPSEEK_V4_FLASH}.
|
|
76
|
-
*/
|
|
77
|
-
DEEPSEEK_CHAT: "deepseek-chat",
|
|
78
|
-
/**
|
|
79
|
-
* @deprecated Legacy alias DeepSeek routes to `deepseek-v4-flash` (thinking).
|
|
80
|
-
* DeepSeek removes this name on 2026-07-24 15:59 UTC — migrate to
|
|
81
|
-
* {@link Models.DEEPSEEK_V4_FLASH} (or {@link Models.DEEPSEEK_V4_PRO} for
|
|
82
|
-
* heavier reasoning).
|
|
83
|
-
*/
|
|
84
|
-
DEEPSEEK_REASONER: "deepseek-reasoner",
|
|
85
70
|
/** GPT-4.1 — OpenAI. */
|
|
86
71
|
GPT_4_1: "gpt-4.1",
|
|
87
72
|
/** GPT-4o mini — OpenAI, or via OpenRouter (`provider: Providers.OPENROUTER`). */
|
|
@@ -109,11 +94,6 @@ export const Models = {
|
|
|
109
94
|
*/
|
|
110
95
|
DOUBAO_SEED_FLASH: "doubao-seed-flash"
|
|
111
96
|
};
|
|
112
|
-
/**
|
|
113
|
-
* Back-compat alias for {@link Models}. Existing imports of `RunModels`
|
|
114
|
-
* keep working; new code should prefer `Models`.
|
|
115
|
-
*/
|
|
116
|
-
export const RunModels = Models;
|
|
117
97
|
/**
|
|
118
98
|
* Per-model provider lists, in declaration order. Derived from
|
|
119
99
|
* {@link MODEL_PROVIDER_IDS} so the two never drift.
|
|
@@ -132,62 +132,17 @@ export declare function downloadEvents(http: HttpClient, runId: string): Promise
|
|
|
132
132
|
*/
|
|
133
133
|
export declare function downloadMetadata(http: HttpClient, runId: string): Promise<Uint8Array>;
|
|
134
134
|
export declare function submitRun(http: HttpClient, request: PlatformRunSubmissionInput): Promise<Run>;
|
|
135
|
-
/**
|
|
136
|
-
* Multipart variant of `submitRun` for runs that carry transient
|
|
137
|
-
* (per-run) skill bundles and/or transient AgentsMd content.
|
|
138
|
-
*
|
|
139
|
-
* The JSON submission travels as the `submission` part; each
|
|
140
|
-
* `InlineSkillRef.slot` in `request.submission.skills` MUST be
|
|
141
|
-
* mirrored by exactly one `skill:<slot>` part with the bundle bytes.
|
|
142
|
-
* Each `InlineAgentsMdRef.slot` in `request.submission.agentsMd`
|
|
143
|
-
* MUST be mirrored by exactly one `agentsmd:<slot>` part with the
|
|
144
|
-
* markdown text.
|
|
145
|
-
*
|
|
146
|
-
* The BFF re-canonicalises and re-hashes each bundle/file; a
|
|
147
|
-
* `contentHash` mismatch is rejected with a deterministic error.
|
|
148
|
-
*
|
|
149
|
-
* At least one of `bundles` or `agentsMdParts` must be non-empty.
|
|
150
|
-
*/
|
|
151
|
-
export declare function submitRunMultipart(http: HttpClient, request: PlatformRunSubmissionInput, bundles: ReadonlyArray<{
|
|
152
|
-
readonly slot: string;
|
|
153
|
-
readonly bytes: Uint8Array;
|
|
154
|
-
readonly filename: string;
|
|
155
|
-
}>, agentsMdParts?: ReadonlyArray<{
|
|
156
|
-
readonly slot: string;
|
|
157
|
-
readonly content: string;
|
|
158
|
-
readonly filename: string;
|
|
159
|
-
}>, fileParts?: ReadonlyArray<{
|
|
160
|
-
readonly slot: string;
|
|
161
|
-
readonly bytes: Uint8Array;
|
|
162
|
-
readonly filename: string;
|
|
163
|
-
}>): Promise<Run>;
|
|
164
|
-
/**
|
|
165
|
-
* Upload a workspace skill bundle as a zip blob. The hosted API runs
|
|
166
|
-
* the two-phase flow internally (insert pending row, stream bytes into
|
|
167
|
-
* object storage, validate manifest, transition to ready) and returns
|
|
168
|
-
* the finalized `Skill`. Use `Skill.fromPath` / `Skill.upload` in the
|
|
169
|
-
* SDK to build the body; this transport function only knows about
|
|
170
|
-
* bytes.
|
|
171
|
-
*/
|
|
172
|
-
export declare function createSkillBundle(http: HttpClient, args: {
|
|
173
|
-
readonly name: string;
|
|
174
|
-
readonly body: Blob | ArrayBuffer | Uint8Array;
|
|
175
|
-
readonly contentType?: string;
|
|
176
|
-
readonly filename?: string;
|
|
177
|
-
}): Promise<Skill>;
|
|
178
135
|
/**
|
|
179
136
|
* Upload a workspace skill bundle DIRECTLY to object storage via the presign
|
|
180
137
|
* flow, so the bytes never transit the hosted API (bundle size bounded by the
|
|
181
|
-
* object store, not API memory).
|
|
182
|
-
* `createSkillBundle` when the hosted API has no object-store upload
|
|
183
|
-
* credentials (503 `presign_unconfigured`).
|
|
138
|
+
* object store, not API memory). Presign errors are terminal.
|
|
184
139
|
*
|
|
185
140
|
* 1. POST /api/skills/presign { name, hash, sizeBytes } → { uploadUrl, requiredHeaders, skillId }
|
|
186
141
|
* 2. PUT bytes → uploadUrl (signed checksum; the store rejects a mismatch)
|
|
187
142
|
* 3. POST /api/skills/:id/finalize { manifest } → finalized Skill
|
|
188
143
|
*
|
|
189
144
|
* `manifest` is the client-computed bundle manifest (the caller already
|
|
190
|
-
* validated the zip shape before hashing); the
|
|
145
|
+
* validated the zip shape before hashing); the hosted API records it on finalize
|
|
191
146
|
* without re-buffering the object.
|
|
192
147
|
*/
|
|
193
148
|
export declare function createSkillBundleDirect(http: HttpClient, fetchImpl: (input: string, init?: RequestInit) => Promise<{
|
|
@@ -228,26 +183,9 @@ export declare function findSkillByHash(http: HttpClient, args: {
|
|
|
228
183
|
* indexed by-hash route is reserved for `uploadIfChanged`.
|
|
229
184
|
*/
|
|
230
185
|
export declare function findSkillByName(http: HttpClient, name: string): Promise<Skill | null>;
|
|
231
|
-
/**
|
|
232
|
-
* Upload a workspace AgentsMd file as a markdown string. The BFF
|
|
233
|
-
* canonicalises the content into a deterministic zip with AGENTS.md at
|
|
234
|
-
* root and runs the two-phase pending → ready upload.
|
|
235
|
-
*/
|
|
236
|
-
export declare function createAgentsMd(http: HttpClient, args: {
|
|
237
|
-
readonly name: string;
|
|
238
|
-
readonly content: string;
|
|
239
|
-
}): Promise<AgentsMdRecord>;
|
|
240
186
|
export declare function listAgentsMd(http: HttpClient): Promise<readonly AgentsMdRecord[]>;
|
|
241
187
|
export declare function getAgentsMd(http: HttpClient, agentsMdId: string): Promise<AgentsMdRecord>;
|
|
242
188
|
export declare function deleteAgentsMd(http: HttpClient, agentsMdId: string): Promise<void>;
|
|
243
|
-
/**
|
|
244
|
-
* Upload a workspace File as a zip bundle. The BFF canonicalises the
|
|
245
|
-
* content and runs the two-phase pending → ready upload.
|
|
246
|
-
*/
|
|
247
|
-
export declare function createFile(http: HttpClient, args: {
|
|
248
|
-
readonly name: string;
|
|
249
|
-
readonly bytes: Uint8Array;
|
|
250
|
-
}): Promise<FileRecord>;
|
|
251
189
|
export declare function listFiles(http: HttpClient): Promise<readonly FileRecord[]>;
|
|
252
190
|
export declare function getFile(http: HttpClient, fileId: string): Promise<FileRecord>;
|
|
253
191
|
export declare function deleteFile(http: HttpClient, fileId: string): Promise<void>;
|
|
@@ -628,130 +628,25 @@ export async function submitRun(http, request) {
|
|
|
628
628
|
body: JSON.stringify(request)
|
|
629
629
|
});
|
|
630
630
|
}
|
|
631
|
-
/**
|
|
632
|
-
* Multipart variant of `submitRun` for runs that carry transient
|
|
633
|
-
* (per-run) skill bundles and/or transient AgentsMd content.
|
|
634
|
-
*
|
|
635
|
-
* The JSON submission travels as the `submission` part; each
|
|
636
|
-
* `InlineSkillRef.slot` in `request.submission.skills` MUST be
|
|
637
|
-
* mirrored by exactly one `skill:<slot>` part with the bundle bytes.
|
|
638
|
-
* Each `InlineAgentsMdRef.slot` in `request.submission.agentsMd`
|
|
639
|
-
* MUST be mirrored by exactly one `agentsmd:<slot>` part with the
|
|
640
|
-
* markdown text.
|
|
641
|
-
*
|
|
642
|
-
* The BFF re-canonicalises and re-hashes each bundle/file; a
|
|
643
|
-
* `contentHash` mismatch is rejected with a deterministic error.
|
|
644
|
-
*
|
|
645
|
-
* At least one of `bundles` or `agentsMdParts` must be non-empty.
|
|
646
|
-
*/
|
|
647
|
-
export async function submitRunMultipart(http, request, bundles, agentsMdParts, fileParts) {
|
|
648
|
-
const hasBundles = Array.isArray(bundles) && bundles.length > 0;
|
|
649
|
-
const hasAgentsMd = Array.isArray(agentsMdParts) && agentsMdParts.length > 0;
|
|
650
|
-
const hasFiles = Array.isArray(fileParts) && fileParts.length > 0;
|
|
651
|
-
if (!hasBundles && !hasAgentsMd && !hasFiles) {
|
|
652
|
-
throw new Error("submitRunMultipart: bundles, agentsMdParts, or fileParts must be non-empty");
|
|
653
|
-
}
|
|
654
|
-
const form = new FormData();
|
|
655
|
-
// Submission rides as a typed JSON Blob so the BFF reads
|
|
656
|
-
// `multipart["submission"]` with the right content-type and never
|
|
657
|
-
// has to re-detect the body shape.
|
|
658
|
-
form.append("submission", new Blob([JSON.stringify(request)], { type: "application/json" }), "submission.json");
|
|
659
|
-
const seen = new Set();
|
|
660
|
-
for (const bundle of bundles) {
|
|
661
|
-
if (typeof bundle.slot !== "string" || !bundle.slot) {
|
|
662
|
-
throw new Error("submitRunMultipart: each bundle must have a non-empty slot id");
|
|
663
|
-
}
|
|
664
|
-
if (seen.has(bundle.slot)) {
|
|
665
|
-
throw new Error(`submitRunMultipart: duplicate inline skill slot "${bundle.slot}"`);
|
|
666
|
-
}
|
|
667
|
-
seen.add(bundle.slot);
|
|
668
|
-
const blob = toBlob(bundle.bytes, "application/zip");
|
|
669
|
-
form.append(`skill:${bundle.slot}`, blob, bundle.filename);
|
|
670
|
-
}
|
|
671
|
-
for (const part of agentsMdParts ?? []) {
|
|
672
|
-
if (typeof part.slot !== "string" || !part.slot) {
|
|
673
|
-
throw new Error("submitRunMultipart: each agentsMd part must have a non-empty slot id");
|
|
674
|
-
}
|
|
675
|
-
const partKey = `agentsmd:${part.slot}`;
|
|
676
|
-
if (seen.has(partKey)) {
|
|
677
|
-
throw new Error(`submitRunMultipart: duplicate agentsMd slot "${part.slot}"`);
|
|
678
|
-
}
|
|
679
|
-
seen.add(partKey);
|
|
680
|
-
const blob = new Blob([part.content], { type: "text/plain" });
|
|
681
|
-
form.append(partKey, blob, part.filename);
|
|
682
|
-
}
|
|
683
|
-
for (const part of fileParts ?? []) {
|
|
684
|
-
if (typeof part.slot !== "string" || !part.slot) {
|
|
685
|
-
throw new Error("submitRunMultipart: each file part must have a non-empty slot id");
|
|
686
|
-
}
|
|
687
|
-
const partKey = `file:${part.slot}`;
|
|
688
|
-
if (seen.has(partKey)) {
|
|
689
|
-
throw new Error(`submitRunMultipart: duplicate file slot "${part.slot}"`);
|
|
690
|
-
}
|
|
691
|
-
seen.add(partKey);
|
|
692
|
-
const blob = toBlob(part.bytes, "application/zip");
|
|
693
|
-
form.append(partKey, blob, part.filename);
|
|
694
|
-
}
|
|
695
|
-
return http.request("/api/runs", {
|
|
696
|
-
method: "POST",
|
|
697
|
-
body: form
|
|
698
|
-
});
|
|
699
|
-
}
|
|
700
|
-
/**
|
|
701
|
-
* Upload a workspace skill bundle as a zip blob. The hosted API runs
|
|
702
|
-
* the two-phase flow internally (insert pending row, stream bytes into
|
|
703
|
-
* object storage, validate manifest, transition to ready) and returns
|
|
704
|
-
* the finalized `Skill`. Use `Skill.fromPath` / `Skill.upload` in the
|
|
705
|
-
* SDK to build the body; this transport function only knows about
|
|
706
|
-
* bytes.
|
|
707
|
-
*/
|
|
708
|
-
export async function createSkillBundle(http, args) {
|
|
709
|
-
const form = new FormData();
|
|
710
|
-
form.append("name", args.name);
|
|
711
|
-
const blobBody = toBlob(args.body, args.contentType ?? "application/zip");
|
|
712
|
-
form.append("bundle", blobBody, args.filename ?? `${args.name}.zip`);
|
|
713
|
-
const result = await http.request("/api/skills", {
|
|
714
|
-
method: "POST",
|
|
715
|
-
body: form
|
|
716
|
-
});
|
|
717
|
-
return unwrapSkill(result);
|
|
718
|
-
}
|
|
719
631
|
/**
|
|
720
632
|
* Upload a workspace skill bundle DIRECTLY to object storage via the presign
|
|
721
633
|
* flow, so the bytes never transit the hosted API (bundle size bounded by the
|
|
722
|
-
* object store, not API memory).
|
|
723
|
-
* `createSkillBundle` when the hosted API has no object-store upload
|
|
724
|
-
* credentials (503 `presign_unconfigured`).
|
|
634
|
+
* object store, not API memory). Presign errors are terminal.
|
|
725
635
|
*
|
|
726
636
|
* 1. POST /api/skills/presign { name, hash, sizeBytes } → { uploadUrl, requiredHeaders, skillId }
|
|
727
637
|
* 2. PUT bytes → uploadUrl (signed checksum; the store rejects a mismatch)
|
|
728
638
|
* 3. POST /api/skills/:id/finalize { manifest } → finalized Skill
|
|
729
639
|
*
|
|
730
640
|
* `manifest` is the client-computed bundle manifest (the caller already
|
|
731
|
-
* validated the zip shape before hashing); the
|
|
641
|
+
* validated the zip shape before hashing); the hosted API records it on finalize
|
|
732
642
|
* without re-buffering the object.
|
|
733
643
|
*/
|
|
734
644
|
export async function createSkillBundleDirect(http, fetchImpl, args) {
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
body: JSON.stringify({ name: args.name, hash: args.contentHash, sizeBytes: args.body.byteLength })
|
|
741
|
-
});
|
|
742
|
-
}
|
|
743
|
-
catch (err) {
|
|
744
|
-
const status = err.status;
|
|
745
|
-
const code = (err.details ?? {}).code;
|
|
746
|
-
if (status === 503 && code === "presign_unconfigured") {
|
|
747
|
-
return createSkillBundle(http, {
|
|
748
|
-
name: args.name,
|
|
749
|
-
body: args.body,
|
|
750
|
-
...(args.contentType ? { contentType: args.contentType } : {})
|
|
751
|
-
});
|
|
752
|
-
}
|
|
753
|
-
throw err;
|
|
754
|
-
}
|
|
645
|
+
const presign = await http.request("/api/skills/presign", {
|
|
646
|
+
method: "POST",
|
|
647
|
+
headers: { "content-type": "application/json" },
|
|
648
|
+
body: JSON.stringify({ name: args.name, hash: args.contentHash, sizeBytes: args.body.byteLength })
|
|
649
|
+
});
|
|
755
650
|
const putRes = await fetchImpl(presign.uploadUrl, {
|
|
756
651
|
method: "PUT",
|
|
757
652
|
headers: { "content-type": args.contentType ?? "application/zip", ...(presign.requiredHeaders ?? {}) },
|
|
@@ -812,20 +707,8 @@ export async function findSkillByName(http, name) {
|
|
|
812
707
|
return skills.find((skill) => skill.name === name) ?? null;
|
|
813
708
|
}
|
|
814
709
|
// ===========================================================================
|
|
815
|
-
// AgentsMd
|
|
710
|
+
// AgentsMd read/delete helpers. Launch submissions use content-addressed asset refs.
|
|
816
711
|
// ===========================================================================
|
|
817
|
-
/**
|
|
818
|
-
* Upload a workspace AgentsMd file as a markdown string. The BFF
|
|
819
|
-
* canonicalises the content into a deterministic zip with AGENTS.md at
|
|
820
|
-
* root and runs the two-phase pending → ready upload.
|
|
821
|
-
*/
|
|
822
|
-
export async function createAgentsMd(http, args) {
|
|
823
|
-
const form = new FormData();
|
|
824
|
-
form.append("name", args.name);
|
|
825
|
-
form.append("content", new Blob([args.content], { type: "text/plain" }), "AGENTS.md");
|
|
826
|
-
const result = await http.request("/api/agentsmd", { method: "POST", body: form });
|
|
827
|
-
return unwrapAgentsMd(result);
|
|
828
|
-
}
|
|
829
712
|
export async function listAgentsMd(http) {
|
|
830
713
|
const result = await http.request("/api/agentsmd");
|
|
831
714
|
if (Array.isArray(result)) {
|
|
@@ -849,20 +732,8 @@ function unwrapAgentsMd(result) {
|
|
|
849
732
|
return result;
|
|
850
733
|
}
|
|
851
734
|
// ===========================================================================
|
|
852
|
-
// File
|
|
735
|
+
// File read/delete helpers. Launch submissions use content-addressed asset refs.
|
|
853
736
|
// ===========================================================================
|
|
854
|
-
/**
|
|
855
|
-
* Upload a workspace File as a zip bundle. The BFF canonicalises the
|
|
856
|
-
* content and runs the two-phase pending → ready upload.
|
|
857
|
-
*/
|
|
858
|
-
export async function createFile(http, args) {
|
|
859
|
-
const form = new FormData();
|
|
860
|
-
form.append("name", args.name);
|
|
861
|
-
const blob = toBlob(args.bytes, "application/zip");
|
|
862
|
-
form.append("bundle", blob, `${args.name}.zip`);
|
|
863
|
-
const result = await http.request("/api/files", { method: "POST", body: form });
|
|
864
|
-
return unwrapFile(result);
|
|
865
|
-
}
|
|
866
737
|
export async function listFiles(http) {
|
|
867
738
|
const result = await http.request("/api/files");
|
|
868
739
|
if (Array.isArray(result)) {
|
|
@@ -941,20 +812,6 @@ function unwrapSkill(result) {
|
|
|
941
812
|
}
|
|
942
813
|
return result;
|
|
943
814
|
}
|
|
944
|
-
function toBlob(input, contentType) {
|
|
945
|
-
if (input instanceof Blob) {
|
|
946
|
-
return input;
|
|
947
|
-
}
|
|
948
|
-
if (input instanceof Uint8Array) {
|
|
949
|
-
// BlobPart accepts ArrayBufferView, but lib.dom's overload set
|
|
950
|
-
// narrows on the underlying buffer kind. Slice into a fresh
|
|
951
|
-
// ArrayBuffer so a SharedArrayBuffer-backed Uint8Array works.
|
|
952
|
-
const copy = new Uint8Array(input.byteLength);
|
|
953
|
-
copy.set(input);
|
|
954
|
-
return new Blob([copy.buffer], { type: contentType });
|
|
955
|
-
}
|
|
956
|
-
return new Blob([input], { type: contentType });
|
|
957
|
-
}
|
|
958
815
|
function hasRun(value) {
|
|
959
816
|
return Boolean(value && typeof value === "object" && "run" in value);
|
|
960
817
|
}
|