@aexhq/sdk 0.24.0 → 0.25.1
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 +36 -125
- package/dist/_contracts/index.d.ts +0 -1
- package/dist/_contracts/index.js +0 -1
- package/dist/_contracts/models.js +1 -2
- package/dist/_contracts/operations.d.ts +13 -5
- package/dist/_contracts/operations.js +220 -10
- package/dist/_contracts/provider-support.d.ts +18 -29
- package/dist/_contracts/provider-support.js +3 -22
- package/dist/_contracts/proxy-protocol.d.ts +4 -2
- package/dist/_contracts/proxy-protocol.js +10 -3
- package/dist/_contracts/run-config.d.ts +28 -4
- package/dist/_contracts/run-config.js +10 -5
- 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/run-unit.js +3 -1
- package/dist/_contracts/runtime-security-profile.js +1 -1
- package/dist/_contracts/runtime-types.d.ts +38 -12
- 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 +68 -42
- package/dist/_contracts/submission.js +144 -30
- package/dist/bundle.d.ts +13 -0
- package/dist/bundle.js +51 -0
- package/dist/bundle.js.map +1 -1
- package/dist/cli.mjs +232 -58
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +25 -21
- package/dist/client.js +59 -15
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/tool.d.ts +41 -0
- package/dist/tool.js +138 -0
- package/dist/tool.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/concepts/agent-tools.md +53 -0
- package/docs/concepts/composition.md +43 -0
- package/docs/concepts/providers-and-runtimes.md +53 -0
- package/docs/concepts/runs.md +40 -0
- package/docs/credentials.md +8 -4
- package/docs/events.md +12 -0
- package/docs/limits.md +53 -0
- package/docs/outputs.md +58 -0
- package/docs/provider-runtime-capabilities.md +53 -55
- package/docs/public-surface.json +81 -0
- package/docs/quickstart.md +28 -105
- package/docs/release.md +1 -1
- package/docs/run-config.md +2 -2
- package/docs/secrets.md +123 -0
- package/docs/skills.md +3 -3
- package/docs/vision-skills.md +14 -19
- package/package.json +2 -2
- package/dist/_contracts/managed-key.d.ts +0 -101
- package/dist/_contracts/managed-key.js +0 -181
- package/docs/product-boundaries.md +0 -57
package/docs/quickstart.md
CHANGED
|
@@ -1,137 +1,60 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
2
|
+
title: Quickstart
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# Quickstart
|
|
6
6
|
|
|
7
|
-
1.
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
## 1. Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @aexhq/sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 2. Submit a run
|
|
10
14
|
|
|
11
15
|
```ts
|
|
12
|
-
import { AgentExecutor,
|
|
16
|
+
import { AgentExecutor, Models, Providers } from "@aexhq/sdk";
|
|
13
17
|
|
|
14
18
|
const aex = new AgentExecutor({
|
|
15
|
-
apiToken: process.env.AEX_API_TOKEN
|
|
16
|
-
// baseUrl defaults to https://api.aex.dev - set it for local or staging planes.
|
|
19
|
+
apiToken: process.env.AEX_API_TOKEN!
|
|
17
20
|
});
|
|
18
21
|
|
|
19
22
|
const runId = await aex.submit({
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
provider: Providers.ANTHROPIC,
|
|
24
|
+
model: Models.CLAUDE_HAIKU_4_5,
|
|
25
|
+
prompt: "Write a short report and save it as a file.",
|
|
22
26
|
secrets: { apiKey: process.env.ANTHROPIC_API_KEY! }
|
|
23
27
|
});
|
|
24
|
-
|
|
25
|
-
const run = await aex.wait(runId);
|
|
26
|
-
console.log(run.status);
|
|
27
|
-
console.log(await aex.outputs(runId));
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
## 3. Stream, wait, and download
|
|
31
31
|
|
|
32
32
|
```ts
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
model: RunModels.CLAUDE_HAIKU_4_5,
|
|
36
|
-
prompt: `Write a short answer about ${topic}.`
|
|
37
|
-
};
|
|
33
|
+
for await (const event of aex.stream(runId)) {
|
|
34
|
+
console.log(event.type);
|
|
38
35
|
}
|
|
39
36
|
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
});
|
|
37
|
+
const run = await aex.wait(runId);
|
|
38
|
+
console.log(run.status);
|
|
39
|
+
|
|
40
|
+
await aex.download(runId, { to: "./run.zip" });
|
|
44
41
|
```
|
|
45
42
|
|
|
46
|
-
|
|
43
|
+
The same run from the CLI:
|
|
47
44
|
|
|
48
45
|
```bash
|
|
49
46
|
aex run \
|
|
50
47
|
--api-token "$AEX_API_TOKEN" \
|
|
51
48
|
--anthropic-api-key "$ANTHROPIC_API_KEY" \
|
|
52
49
|
--model claude-haiku-4-5 \
|
|
53
|
-
--prompt "Write a short
|
|
50
|
+
--prompt "Write a short report and save it as a file." \
|
|
54
51
|
--follow
|
|
55
52
|
```
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
## Runtime controls
|
|
60
|
-
|
|
61
|
-
`submit` also accepts per-run controls that are not secrets:
|
|
62
|
-
|
|
63
|
-
- `runtimeSize` - a closed managed-runtime preset. Prefer `RuntimeSizes`, e.g. `RuntimeSizes.SHARED_2X_2GB`.
|
|
64
|
-
- `timeout` - run deadline as a duration string such as `"30m"` or `"2h"`; bounded server-side.
|
|
65
|
-
- `postHook` - optional post-agent verifier, e.g. `{ command: "pnpm test", timeout: "5m", maxTurns: 3, maxChars: 12000 }`. It runs after the agent process exits successfully; failures are sent back to the agent for repair until `maxTurns` is exhausted. Empty `command` is treated as omitted.
|
|
66
|
-
- `builtins` - managed-runtime builtin extensions. Omit it to use the default `["developer"]` toolkit. Pass `[]` for a pure-MCP run with no builtins.
|
|
67
|
-
- `outputMode` - `"buffered"` by default; pass `"stream"` for per-token assistant text deltas.
|
|
68
|
-
|
|
69
|
-
## Where things go: customer → primitive mapping
|
|
70
|
-
|
|
71
|
-
Every kind of thing you want to ship at run time has exactly one right primitive in the SDK. Reach for the right one rather than rolling your own wrapper.
|
|
72
|
-
|
|
73
|
-
| What you have | Primitive | What it does |
|
|
74
|
-
|---|---|---|
|
|
75
|
-
| Non-secret paths or config (`BROLL_STORE`, mode flags) | `environment.envVars` | Mounted as `RUNTIME.env` / `RUNTIME.json`; `__KEY__` substitution in agent-facing markdown; echoed back as `run.runtimeManifest.envVars` |
|
|
76
|
-
| Upstream HTTPS API keys (TMDB, Brave, Tavily, …) | `ProxyEndpoint` | Credentials live server-side; aex proxy injects them on outbound calls. The key never enters the container. |
|
|
77
|
-
| MCP server credentials | `secrets.mcpServers` | Held in run-scoped custody, attached per run |
|
|
78
|
-
| Provider API key | `secrets.apiKey` | Required on every `submit`; held in run-scoped custody. Carries the BYOK key for the selected `provider` |
|
|
79
|
-
| Non-secret reference data files or folders (transcripts, persona docs, PDFs) | `File.fromPath('./subtitles.srt')` / `File.fromPath('./customer-folder/')` | Unzipped into the `mountPath` directory (default `/workspace`, the agent's cwd), preserving the real filename + extension — e.g. `/workspace/subtitles.srt`. See [Files: where they land](#files-where-they-land). |
|
|
80
|
-
| Executable skill code (a `.pyz` wrapper, scripts, prompts) | `Skill.fromPath('./skills/my-skill/')` | Mounted under `skills/<name>/`; the bundle's `SKILL.md` is composed into the agent's instructions |
|
|
81
|
-
| Agent instructions file | `AgentsMd.fromPath('./AGENTS.md')` | Prepended as the first user turn |
|
|
82
|
-
|
|
83
|
-
`Skill`, `AgentsMd`, and `File` values are materialized for the run before the first agent turn. `environment.envVars` values surface in runtime metadata and can be referenced by `__KEY__` placeholders in agent-facing markdown.
|
|
84
|
-
|
|
85
|
-
### Files: where they land
|
|
86
|
-
|
|
87
|
-
A `File` is uploaded as a content-addressed archive and **unzipped on the runtime into a directory**, preserving the real filename + extension — the agent sees the actual file, never a `.zip` to unpack.
|
|
88
|
-
|
|
89
|
-
- **`mountPath` is the directory the archive unzips into.** It must be an absolute container path (`/...`, no `..` traversal). It defaults to **`/workspace`**, which is also the agent's default working directory — so a file handed with no `mountPath` lands directly in the agent's cwd.
|
|
90
|
-
- **A single file keeps its real basename.** `File.fromPath('./source-video-subtitles.srt')` lands at `/workspace/source-video-subtitles.srt` (not a slug, not a `.zip`). `File.fromBytes({ name: 'data.csv', bytes })` lands at `/workspace/data.csv` — `name` is the real filename here.
|
|
91
|
-
- **A folder lands its entries under the mount directory.** `File.fromPath('./repo/', { mountPath: '/workspace/repo' })` puts each file at `/workspace/repo/<relative-path>`.
|
|
92
|
-
- **The resolved mount directory is surfaced back on the run.** Read `run.runtimeManifest.mountedFiles` (an array of `{ name, mountPath }`) to learn where each handed file landed.
|
|
93
|
-
|
|
94
|
-
```ts
|
|
95
|
-
const subtitles = await File.fromPath('./source-video-subtitles.srt'); // → /workspace/source-video-subtitles.srt
|
|
96
|
-
const dataset = await File.fromPath('./data/', { mountPath: '/workspace/input' }); // → /workspace/input/<files>
|
|
97
|
-
const run = await client.submit({ model, prompt, files: [subtitles, dataset], secrets: { apiKey } });
|
|
98
|
-
const resolved = (await client.getRun(run.id)).runtimeManifest?.mountedFiles;
|
|
99
|
-
// [{ name: 'source-video-subtitles', mountPath: '/workspace' }, { name: 'data', mountPath: '/workspace/input' }]
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## Safe retries with `idempotencyKey`
|
|
103
|
-
|
|
104
|
-
Every `submit` call carries an `idempotencyKey`. When omitted the SDK auto-generates a UUID per call. Supplying your own key makes retries deterministic:
|
|
105
|
-
|
|
106
|
-
| Submit shape | Server response |
|
|
107
|
-
| --- | --- |
|
|
108
|
-
| New `idempotencyKey` | HTTP 202 — returns the new run id. |
|
|
109
|
-
| Same key + identical request body hash | HTTP 200 — returns the original run id. The SDK call resolves with that id. |
|
|
110
|
-
| Same key + **different** request body hash | HTTP 409 — body `{ error: { message, code: "idempotency_conflict", details: { existingRunId } } }`. The SDK throws an `HttpError` carrying that body. Use `details.existingRunId` to adopt the pre-existing run, or pick a fresh key. |
|
|
111
|
-
| Omitted `idempotencyKey` | A new UUID is generated on every call — repeat submissions create new runs. |
|
|
112
|
-
|
|
113
|
-
The request hash is computed server-side over the canonical submission JSON (model, prompt, system, environment, skill refs, MCP server descriptors, proxy endpoints, `outputs`, etc.) so reordering JSON keys, adding whitespace, or rotating the inline secret bundle does **not** change the hash. Changing the prompt, model, system, or any other non-secret field does.
|
|
114
|
-
|
|
115
|
-
Pattern for safe retries:
|
|
116
|
-
|
|
117
|
-
```ts
|
|
118
|
-
const idempotencyKey = crypto.randomUUID();
|
|
119
|
-
async function submitWithRetry() {
|
|
120
|
-
for (let attempt = 0; attempt < 3; attempt++) {
|
|
121
|
-
try {
|
|
122
|
-
return await aex.submit({
|
|
123
|
-
model: RunModels.CLAUDE_HAIKU_4_5,
|
|
124
|
-
prompt: "...",
|
|
125
|
-
idempotencyKey,
|
|
126
|
-
secrets: { apiKey: process.env.ANTHROPIC_API_KEY! }
|
|
127
|
-
});
|
|
128
|
-
} catch (err) {
|
|
129
|
-
if (err instanceof Error && err.message.includes("network")) continue;
|
|
130
|
-
throw err;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
throw new Error("submit failed after retries");
|
|
134
|
-
}
|
|
135
|
-
```
|
|
54
|
+
## Add capabilities
|
|
136
55
|
|
|
137
|
-
|
|
56
|
+
- Add files, skills, AGENTS.md, MCP servers, proxy endpoints, packages, and networking controls with [Composition](concepts/composition.md).
|
|
57
|
+
- Inspect runtime tools with [Agent tools](concepts/agent-tools.md).
|
|
58
|
+
- Use parent/child run delegation from the [Features](https://aex.dev/docs/features/#subagents) page.
|
|
59
|
+
- Narrow output capture or download individual files with [Outputs](outputs.md).
|
|
60
|
+
- Check supported providers and models in the [provider/runtime capability matrix](provider-runtime-capabilities.md).
|
package/docs/release.md
CHANGED
|
@@ -29,7 +29,7 @@ publish.
|
|
|
29
29
|
publishes `@aexhq/sdk@<version>` under the `canary` tag — `latest` is
|
|
30
30
|
untouched, so `npm install @aexhq/sdk` users are unaffected.
|
|
31
31
|
5. Run the platform release against the canary: in **aex-platform**, dispatch
|
|
32
|
-
`deploy.yml` with `sdk_version=<version>` (threads `
|
|
32
|
+
`deploy.yml` with `sdk_version=<version>` (threads `AEX_USER_TEST_VERSION`
|
|
33
33
|
into the suite). The local plane gates prod, and both planes' user-tests run
|
|
34
34
|
against `@aexhq/sdk@<version>`.
|
|
35
35
|
6. On a green platform release, run the **Promote** workflow
|
package/docs/run-config.md
CHANGED
|
@@ -13,7 +13,7 @@ Allowed fields:
|
|
|
13
13
|
- `system` - optional system message.
|
|
14
14
|
- `skills` - array of storage-neutral `kind:"asset"` refs. Config files cannot carry local draft bytes; use `Skill.fromPath(...)` / `Skill.fromFiles(...)` in SDK code first, or reference an existing asset/catalog skill.
|
|
15
15
|
- `mcpServers` - array of `McpServerRef`; headers are split into `secrets.mcpServers` server-side.
|
|
16
|
-
- `environment` - `{ networking?, packages?, envVars? }`. `envVars` are merged into the in-container `RUNTIME.env` / `RUNTIME.json` mounts.
|
|
16
|
+
- `environment` - `{ networking?, packages?, envVars? }`. Networking is open by default; set `networking.mode` to `limited` only when you want an allowlist. `envVars` are merged into the in-container `RUNTIME.env` / `RUNTIME.json` mounts.
|
|
17
17
|
- `runtimeSize` - optional managed-runtime preset. Prefer `RuntimeSizes` in TypeScript.
|
|
18
18
|
- `timeout` - optional run deadline duration string such as `"30m"` or `"2h"`.
|
|
19
19
|
- `postHook` - optional post-agent verifier `{ command, timeout?, maxTurns?, maxChars? }`. It runs after a successful agent process; a failing or timed-out command is sent back to the agent for repair until `maxTurns` is exhausted. Empty `command` is treated as omitted.
|
|
@@ -22,7 +22,7 @@ Allowed fields:
|
|
|
22
22
|
|
|
23
23
|
`agentsMd`, `files`, `outputs`, `builtins`, and `outputMode` are top-level `submit` options, not run-config fields. They carry bytes, capture behavior, or agent tool/output controls that belong on a concrete run submission.
|
|
24
24
|
|
|
25
|
-
Secrets never live in run config. Pass credentials through `submit({ ...config, secrets })` in the SDK or the equivalent host-mode flags (`--anthropic-api-key`, `--mcp-auth`, `--proxy-auth`) in the CLI. See [Credentials](credentials.md) for the proxy endpoint policy/auth split and retry fields.
|
|
25
|
+
Secrets never live in run config. Pass credentials through `submit({ ...config, secrets })` in the SDK or the equivalent host-mode flags (`--anthropic-api-key`, `--mcp-auth`, `--proxy-auth`) in the CLI. See [Secrets](secrets.md) for secret lifecycles and [Credentials](credentials.md) for the proxy endpoint policy/auth split and retry fields.
|
|
26
26
|
|
|
27
27
|
## Reuse in code
|
|
28
28
|
|
package/docs/secrets.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Secrets
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Secrets
|
|
6
|
+
|
|
7
|
+
aex supports BYOK provider keys, per-run credentials, and reusable workspace
|
|
8
|
+
secrets. Secret values are excluded from the idempotency fingerprint and do not
|
|
9
|
+
belong in run config.
|
|
10
|
+
|
|
11
|
+
## Use A Provider Key For One Run
|
|
12
|
+
|
|
13
|
+
### TypeScript
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { AgentExecutor, Models, Providers } from "@aexhq/sdk";
|
|
17
|
+
|
|
18
|
+
const aex = new AgentExecutor({ apiToken: process.env.AEX_API_TOKEN! });
|
|
19
|
+
|
|
20
|
+
await aex.submit({
|
|
21
|
+
provider: Providers.ANTHROPIC,
|
|
22
|
+
model: Models.CLAUDE_HAIKU_4_5,
|
|
23
|
+
prompt: "Write the report and save outputs.",
|
|
24
|
+
secrets: { apiKey: process.env.ANTHROPIC_API_KEY! }
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### CLI
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
aex run \
|
|
32
|
+
--api-token "$AEX_API_TOKEN" \
|
|
33
|
+
--anthropic-api-key "$ANTHROPIC_API_KEY" \
|
|
34
|
+
--model claude-haiku-4-5 \
|
|
35
|
+
--prompt "Write the report and save outputs."
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Upload An Env Secret
|
|
39
|
+
|
|
40
|
+
Use `Secret.value(...).upload(...)` when you start with an ephemeral value and
|
|
41
|
+
want to persist it as a named workspace secret for later runs.
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { AgentExecutor, Models, Providers, Secret } from "@aexhq/sdk";
|
|
45
|
+
|
|
46
|
+
const aex = new AgentExecutor({ apiToken: process.env.AEX_API_TOKEN! });
|
|
47
|
+
|
|
48
|
+
const githubToken = await Secret.value(process.env.GITHUB_TOKEN!).upload(aex, {
|
|
49
|
+
name: "github-token"
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
await aex.submit({
|
|
53
|
+
provider: Providers.ANTHROPIC,
|
|
54
|
+
model: Models.CLAUDE_HAIKU_4_5,
|
|
55
|
+
prompt: "Inspect the repository issues.",
|
|
56
|
+
secretEnv: { GITHUB_TOKEN: githubToken },
|
|
57
|
+
secrets: { apiKey: process.env.ANTHROPIC_API_KEY! }
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Set Or Rotate A Workspace Secret
|
|
62
|
+
|
|
63
|
+
Use `client.secrets.set(...)` to create a named secret directly. Use
|
|
64
|
+
`client.secrets.rotate(...)` to replace its value while keeping the same name.
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
await aex.secrets.set({
|
|
68
|
+
name: "serper-api-key",
|
|
69
|
+
value: process.env.SERPER_API_KEY!
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
await aex.secrets.rotate({
|
|
73
|
+
name: "serper-api-key",
|
|
74
|
+
value: process.env.SERPER_API_KEY_NEXT!
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Retrieve Secret Metadata
|
|
79
|
+
|
|
80
|
+
`list` and `get` return metadata only. They never return the secret value.
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
const secrets = await aex.secrets.list();
|
|
84
|
+
const metadata = await aex.secrets.get("serper-api-key");
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Get A Secret Value
|
|
88
|
+
|
|
89
|
+
Use `get_value` only when the value is intentionally needed outside a run. It is
|
|
90
|
+
the explicit audited value-read path.
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
const secretValue = await aex.secrets.get_value("serper-api-key");
|
|
94
|
+
console.log(secretValue.value);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Inject A Workspace Secret Into A Run
|
|
98
|
+
|
|
99
|
+
Reference workspace secrets with `Secret.ref(name)`. The value resolves
|
|
100
|
+
server-side and is injected as the named environment variable.
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { Models, Providers, Secret } from "@aexhq/sdk";
|
|
104
|
+
|
|
105
|
+
await aex.submit({
|
|
106
|
+
provider: Providers.ANTHROPIC,
|
|
107
|
+
model: Models.CLAUDE_HAIKU_4_5,
|
|
108
|
+
prompt: "Use SERPER_API_KEY for web search.",
|
|
109
|
+
secretEnv: {
|
|
110
|
+
SERPER_API_KEY: Secret.ref("serper-api-key")
|
|
111
|
+
},
|
|
112
|
+
secrets: { apiKey: process.env.ANTHROPIC_API_KEY! }
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Delete A Workspace Secret
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
await aex.secrets.delete("serper-api-key");
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The CLI supports per-run provider, MCP, and proxy credentials. Workspace secret
|
|
123
|
+
administration is exposed through the SDK.
|
package/docs/skills.md
CHANGED
|
@@ -7,7 +7,7 @@ title: Skills
|
|
|
7
7
|
A skill is executable or instructional content that is mounted into a run before
|
|
8
8
|
the first agent turn. Every accepted skill ends up as a storage-neutral
|
|
9
9
|
`kind:"asset"` reference in the run submission, and the hosted platform snapshots
|
|
10
|
-
that asset into
|
|
10
|
+
that asset into durable run asset storage before dispatch.
|
|
11
11
|
|
|
12
12
|
There are three sources for skill bytes:
|
|
13
13
|
|
|
@@ -32,8 +32,8 @@ an aex asset instead.
|
|
|
32
32
|
|
|
33
33
|
## Materialization
|
|
34
34
|
|
|
35
|
-
For each run, the platform copies referenced skill assets into
|
|
36
|
-
|
|
35
|
+
For each run, the platform copies referenced skill assets into durable run asset
|
|
36
|
+
storage (`runs/<runId>/assets/<hash>`) and the runner downloads them into the
|
|
37
37
|
workspace under `skills/<name>/`.
|
|
38
38
|
|
|
39
39
|
A bundle's `SKILL.md` is composed into the agent's instructions, so the agent is
|
package/docs/vision-skills.md
CHANGED
|
@@ -32,7 +32,7 @@ a raised `maxRequestBytes` (so the base64 image fits):
|
|
|
32
32
|
```ts
|
|
33
33
|
import { AgentExecutor, RunModels, Skill, ProxyEndpoint, validateProxyAuth } from "@aexhq/sdk";
|
|
34
34
|
|
|
35
|
-
const aex = new AgentExecutor({ apiToken: process.env.
|
|
35
|
+
const aex = new AgentExecutor({ apiToken: process.env.AEX_API_TOKEN! });
|
|
36
36
|
|
|
37
37
|
const proxyEndpoints = [
|
|
38
38
|
ProxyEndpoint.bearer({
|
|
@@ -124,33 +124,28 @@ upstream = json.loads(base64.b64decode(envelope["upstreamBodyBase64"]).decode())
|
|
|
124
124
|
content = upstream["choices"][0]["message"]["content"] # the model's JSON answer
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
-
The key is injected by the
|
|
127
|
+
The key is injected by the hosted proxy on the outbound call; it never appears on disk in
|
|
128
128
|
the container or in the model's context.
|
|
129
129
|
|
|
130
|
-
## `maxRequestBytes`
|
|
130
|
+
## `maxRequestBytes` and timeout defaults
|
|
131
131
|
|
|
132
|
-
The per-endpoint `maxRequestBytes` default is **
|
|
133
|
-
is
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
rejects it before any upstream call with an explicit error naming the observed
|
|
138
|
-
size, the configured cap, and how to raise it:
|
|
132
|
+
The per-endpoint `maxRequestBytes` default is **10 MiB** and the default timeout
|
|
133
|
+
is **5 minutes**. That fits typical base64 image/model POSTs without extra
|
|
134
|
+
configuration. If a body does exceed the cap, the proxy rejects it before any
|
|
135
|
+
upstream call with an explicit error naming the observed size, the configured
|
|
136
|
+
cap, and how to raise it:
|
|
139
137
|
|
|
140
138
|
> request body is 2400000 bytes, which exceeds this endpoint's maxRequestBytes
|
|
141
|
-
> (
|
|
139
|
+
> (10485760). Raise the per-endpoint maxRequestBytes in the proxy endpoint policy …
|
|
142
140
|
|
|
143
|
-
Two ways to stay under the cap: raise `maxRequestBytes`, and/or scale frames
|
|
144
|
-
|
|
145
|
-
|
|
141
|
+
Two ways to stay under the cap: raise `maxRequestBytes`, and/or scale frames
|
|
142
|
+
before captioning (`ffmpeg -i source.mp4 -vf fps=1,scale=960:-1 frame_%03d.jpg`)
|
|
143
|
+
so full-res frames do not add payload and model cost without useful signal.
|
|
146
144
|
|
|
147
145
|
## Notes
|
|
148
146
|
|
|
149
|
-
- **
|
|
150
|
-
|
|
151
|
-
BytePlus host (`ark.ap-southeast.bytepluses.com`) is a normal public host. The
|
|
152
|
-
China host (`ark.cn-beijing.volces.com`) is reachable in principle but the
|
|
153
|
-
platform's egress to Beijing is currently unverified — prefer the BytePlus host.
|
|
147
|
+
- **Host selection.** Use the provider endpoint that matches your account and
|
|
148
|
+
declare it as the proxy endpoint `baseUrl`.
|
|
154
149
|
- **Keyless model hosts.** If the upstream takes no credential, declare the
|
|
155
150
|
endpoint with `authShape: { type: "none" }` and omit the `proxyEndpointAuth`
|
|
156
151
|
entry (see `credentials.md`).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aexhq/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.1",
|
|
4
4
|
"description": "TypeScript SDK for running autonomous agent sessions across providers (Anthropic, OpenAI, DeepSeek, Gemini, Mistral) behind one interface.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"examples"
|
|
27
27
|
],
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@aexhq/contracts": "0.
|
|
29
|
+
"@aexhq/contracts": "0.25.1"
|
|
30
30
|
},
|
|
31
31
|
"engines": {
|
|
32
32
|
"node": ">=20"
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import type { RunProvider, RuntimeKind } from "./submission.js";
|
|
2
|
-
import type { RunModel } from "./models.js";
|
|
3
|
-
export declare const CREDENTIAL_MODES: readonly ["byok", "managed"];
|
|
4
|
-
export type CredentialMode = (typeof CREDENTIAL_MODES)[number];
|
|
5
|
-
export declare const DEFAULT_CREDENTIAL_MODE: CredentialMode;
|
|
6
|
-
export declare const MANAGED_KEY_POLICY_SCHEMA_VERSION = 1;
|
|
7
|
-
export declare const MANAGED_KEY_RESERVATION_SCHEMA_VERSION = 1;
|
|
8
|
-
export declare const MANAGED_KEY_LAUNCH_STAGES: readonly ["blocked", "pilot", "ga"];
|
|
9
|
-
export type ManagedKeyLaunchStage = (typeof MANAGED_KEY_LAUNCH_STAGES)[number];
|
|
10
|
-
export declare const MANAGED_KEY_FEATURE_DECISIONS: readonly ["disabled", "allowed"];
|
|
11
|
-
export type ManagedKeyFeatureDecision = (typeof MANAGED_KEY_FEATURE_DECISIONS)[number];
|
|
12
|
-
export declare const MANAGED_KEY_RESERVATION_STATUSES: readonly ["open", "settled", "released"];
|
|
13
|
-
export type ManagedKeyReservationStatus = (typeof MANAGED_KEY_RESERVATION_STATUSES)[number];
|
|
14
|
-
export interface ManagedKeyFeaturePolicyV1 {
|
|
15
|
-
readonly files: ManagedKeyFeatureDecision;
|
|
16
|
-
readonly packages: ManagedKeyFeatureDecision;
|
|
17
|
-
readonly builtins: ManagedKeyFeatureDecision;
|
|
18
|
-
readonly mcpServers: ManagedKeyFeatureDecision;
|
|
19
|
-
readonly proxyEndpoints: ManagedKeyFeatureDecision;
|
|
20
|
-
readonly openNetworking: ManagedKeyFeatureDecision;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Public managed-key policy contract. Concrete policy values, account
|
|
24
|
-
* selection, financial calculation, and deployment wiring live outside this
|
|
25
|
-
* public module.
|
|
26
|
-
*/
|
|
27
|
-
export interface ManagedKeyPolicyV1 {
|
|
28
|
-
readonly schemaVersion: typeof MANAGED_KEY_POLICY_SCHEMA_VERSION;
|
|
29
|
-
readonly credentialMode: "managed";
|
|
30
|
-
readonly launchStage: ManagedKeyLaunchStage;
|
|
31
|
-
readonly privateImplementationAvailable: boolean;
|
|
32
|
-
readonly billingRequired: true;
|
|
33
|
-
readonly providers: readonly RunProvider[];
|
|
34
|
-
readonly runtimes: readonly RuntimeKind[];
|
|
35
|
-
readonly models?: readonly RunModel[];
|
|
36
|
-
readonly features: ManagedKeyFeaturePolicyV1;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Public-safe reservation lifecycle summary. It intentionally carries only
|
|
40
|
-
* credit-unit invariants and public row identifiers; private key handles,
|
|
41
|
-
* account selection, rate cards, margins, and payment-provider references
|
|
42
|
-
* remain outside this contract.
|
|
43
|
-
*/
|
|
44
|
-
export interface ManagedKeyReservationLifecycleV1 {
|
|
45
|
-
readonly schemaVersion: typeof MANAGED_KEY_RESERVATION_SCHEMA_VERSION;
|
|
46
|
-
readonly reservationId: string;
|
|
47
|
-
readonly workspaceId: string;
|
|
48
|
-
readonly runId: string;
|
|
49
|
-
readonly credentialMode: "managed";
|
|
50
|
-
readonly status: ManagedKeyReservationStatus;
|
|
51
|
-
readonly reservedCreditUnits: number;
|
|
52
|
-
readonly chargedCreditUnits: number;
|
|
53
|
-
readonly releasedCreditUnits: number;
|
|
54
|
-
readonly createdAt?: string;
|
|
55
|
-
readonly closedAt?: string;
|
|
56
|
-
}
|
|
57
|
-
export type ManagedKeyReservationLifecycleInput = Omit<ManagedKeyReservationLifecycleV1, "schemaVersion" | "credentialMode"> & {
|
|
58
|
-
readonly credentialMode?: "managed";
|
|
59
|
-
};
|
|
60
|
-
export declare const BLOCKED_MANAGED_KEY_FEATURE_POLICY_V1: ManagedKeyFeaturePolicyV1;
|
|
61
|
-
export declare const BLOCKED_MANAGED_KEY_POLICY_V1: ManagedKeyPolicyV1;
|
|
62
|
-
export declare class ManagedKeyUnavailableError extends Error {
|
|
63
|
-
readonly code = "managed_key_unavailable";
|
|
64
|
-
constructor(message?: string);
|
|
65
|
-
}
|
|
66
|
-
export declare function parseCredentialMode(input: unknown): CredentialMode;
|
|
67
|
-
export declare function credentialModeOrDefault(input: CredentialMode | undefined): CredentialMode;
|
|
68
|
-
export declare function isCredentialMode(input: unknown): input is CredentialMode;
|
|
69
|
-
export declare function buildManagedKeyReservationLifecycle(input: ManagedKeyReservationLifecycleInput): ManagedKeyReservationLifecycleV1;
|
|
70
|
-
export declare function isManagedKeyGenerallyAvailable(policy: ManagedKeyPolicyV1): boolean;
|
|
71
|
-
export declare function isManagedKeyAdmissionAllowed(policy: ManagedKeyPolicyV1): boolean;
|
|
72
|
-
export declare function assertManagedKeyModeAvailable(policy?: ManagedKeyPolicyV1): void;
|
|
73
|
-
export declare function assertManagedKeyAdmissionAllowed(policy?: ManagedKeyPolicyV1): void;
|
|
74
|
-
export interface ManagedCredentialResolutionInput {
|
|
75
|
-
readonly workspaceId: string;
|
|
76
|
-
readonly runId: string;
|
|
77
|
-
readonly provider: RunProvider;
|
|
78
|
-
readonly runtime: RuntimeKind;
|
|
79
|
-
readonly model: RunModel;
|
|
80
|
-
readonly policy: ManagedKeyPolicyV1;
|
|
81
|
-
}
|
|
82
|
-
export interface ManagedCredentialLease {
|
|
83
|
-
readonly credentialMode: "managed";
|
|
84
|
-
readonly provider: RunProvider;
|
|
85
|
-
readonly runtime: RuntimeKind;
|
|
86
|
-
readonly custodyClass: "managed-provider-credential";
|
|
87
|
-
}
|
|
88
|
-
export type ManagedCredentialResolution = {
|
|
89
|
-
readonly ok: true;
|
|
90
|
-
readonly lease: ManagedCredentialLease;
|
|
91
|
-
} | {
|
|
92
|
-
readonly ok: false;
|
|
93
|
-
readonly code: "managed_key_unavailable" | "provider_not_allowed" | "runtime_not_allowed" | "model_not_allowed";
|
|
94
|
-
readonly message: string;
|
|
95
|
-
};
|
|
96
|
-
export interface ManagedCredentialResolver {
|
|
97
|
-
resolveManagedCredential(input: ManagedCredentialResolutionInput): Promise<ManagedCredentialResolution>;
|
|
98
|
-
}
|
|
99
|
-
export declare class FakeManagedCredentialResolver implements ManagedCredentialResolver {
|
|
100
|
-
resolveManagedCredential(input: ManagedCredentialResolutionInput): Promise<ManagedCredentialResolution>;
|
|
101
|
-
}
|