@aexhq/sdk 0.40.6 → 0.40.7
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 +159 -159
- package/dist/_contracts/stable.d.ts +10 -5
- package/dist/_contracts/stable.js +10 -5
- package/dist/client.js +5 -11
- package/dist/client.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/authentication.md +125 -125
- package/docs/billing.md +118 -118
- package/docs/concepts/agent-tools.md +66 -66
- package/docs/concepts/composition.md +37 -37
- package/docs/concepts/providers-and-runtimes.md +54 -54
- package/docs/concepts/runs.md +49 -49
- package/docs/concepts/subagents.md +88 -88
- package/docs/credentials.md +125 -125
- package/docs/defaults.md +64 -64
- package/docs/errors.md +196 -196
- package/docs/events.md +243 -243
- package/docs/limits-and-quotas.md +144 -144
- package/docs/limits.md +50 -50
- package/docs/mcp.md +44 -44
- package/docs/networking.md +163 -163
- package/docs/outputs.md +267 -267
- package/docs/public-surface.json +77 -77
- package/docs/quickstart.md +119 -119
- package/docs/release.md +38 -38
- package/docs/retries.md +129 -129
- package/docs/run-config.md +58 -58
- package/docs/run-record.md +55 -55
- package/docs/secrets.md +125 -125
- package/docs/testing.md +35 -35
- package/docs/vision-skills.md +91 -91
- package/docs/webhooks.md +127 -127
- package/examples/feature-tour.ts +282 -282
- package/examples/spike-settle-latency.ts +125 -125
- package/package.json +1 -1
package/docs/billing.md
CHANGED
|
@@ -1,118 +1,118 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Billing & webhook signing secret
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Billing & webhook signing secret
|
|
6
|
-
|
|
7
|
-
Workspace-level billing, subscription, and webhook verification calls are
|
|
8
|
-
token-scoped like every other client call — the workspace is derived
|
|
9
|
-
server-side from the API key.
|
|
10
|
-
|
|
11
|
-
The billing reads — `aex.billing()`, `aex.billingLedger()`, and the CLI
|
|
12
|
-
`aex billing` (and its `ledger` sub-verb) — require the **`billing:read`**
|
|
13
|
-
scope; a token without it fails with `403 insufficient_scope` (see
|
|
14
|
-
[Errors](errors.md)). This is why the [Quickstart](quickstart.md) mints
|
|
15
|
-
`billing:read` alongside `runs:read` / `runs:write` / `outputs:read`.
|
|
16
|
-
|
|
17
|
-
## Read the billing summary
|
|
18
|
-
|
|
19
|
-
`aex.billing()` returns the workspace's prepaid balance, current-month spend,
|
|
20
|
-
and the spend cap enforced on new runs, plus plan fields:
|
|
21
|
-
|
|
22
|
-
```ts
|
|
23
|
-
import { Aex } from "@aexhq/sdk";
|
|
24
|
-
|
|
25
|
-
const aex = new Aex(process.env.AEX_API_KEY!);
|
|
26
|
-
const billing = await aex.billing();
|
|
27
|
-
console.log(billing.balanceUsd, billing.monthSpendUsd, billing.spendCapUsd);
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
The returned `BillingSummary` is additive-tolerant: fields a newer deployment
|
|
31
|
-
reports that this SDK version does not know yet pass through on the object
|
|
32
|
-
instead of being rejected.
|
|
33
|
-
|
|
34
|
-
CLI equivalent:
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
aex billing # human-readable balance / month spend / spend cap
|
|
38
|
-
aex billing --json # the raw wire body for scripting
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Manage the subscription
|
|
42
|
-
|
|
43
|
-
`aex.billingCheckout({ planKey })` creates a hosted checkout session for a paid
|
|
44
|
-
plan. Open the returned URL in a browser; the workspace plan changes after
|
|
45
|
-
checkout completes and the hosted API confirms the subscription.
|
|
46
|
-
|
|
47
|
-
```ts
|
|
48
|
-
const { url } = await aex.billingCheckout({
|
|
49
|
-
planKey: "pro",
|
|
50
|
-
idempotencyKey: crypto.randomUUID()
|
|
51
|
-
});
|
|
52
|
-
console.log(url);
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
`aex.billingPortal()` creates a hosted billing portal session for the workspace:
|
|
56
|
-
|
|
57
|
-
```ts
|
|
58
|
-
const { url } = await aex.billingPortal({ returnUrl: "https://aex.dev/billing" });
|
|
59
|
-
console.log(url);
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
CLI equivalents:
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
aex billing upgrade pro
|
|
66
|
-
aex billing portal
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Read the credit ledger
|
|
70
|
-
|
|
71
|
-
`aex.billingLedger({ limit })` returns recent credit-ledger rows, newest first —
|
|
72
|
-
allowance grants, adjustments, and run charges with signed `amountUsd` (credits
|
|
73
|
-
positive, charges negative). `limit` is clamped server-side to [1, 100] (default
|
|
74
|
-
25); the read is not cursor-paged.
|
|
75
|
-
|
|
76
|
-
```ts
|
|
77
|
-
const { entries } = await aex.billingLedger({ limit: 50 });
|
|
78
|
-
for (const entry of entries) {
|
|
79
|
-
console.log(entry.createdAt, entry.entryType, entry.amountUsd);
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
CLI equivalent:
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
aex billing ledger --limit 50 # JSON rows, newest first
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
## Reveal the webhook signing secret
|
|
90
|
-
|
|
91
|
-
Run webhooks are signed Standard-Webhooks style with a per-workspace secret.
|
|
92
|
-
`aex.webhookSigningSecret()` reveals it (creating one on first use) as the
|
|
93
|
-
`whsec_<base64>` string that `verifyAexWebhook` takes as `secret`:
|
|
94
|
-
|
|
95
|
-
```ts
|
|
96
|
-
import { Aex, verifyAexWebhook } from "@aexhq/sdk";
|
|
97
|
-
|
|
98
|
-
const aex = new Aex(process.env.AEX_API_KEY!);
|
|
99
|
-
const { whsec } = await aex.webhookSigningSecret();
|
|
100
|
-
|
|
101
|
-
// In your webhook receiver:
|
|
102
|
-
const verified = await verifyAexWebhook({
|
|
103
|
-
rawBody, // the exact request body bytes as a string
|
|
104
|
-
headers, // the inbound request headers
|
|
105
|
-
secret: whsec
|
|
106
|
-
});
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
Repeat calls return the SAME value — the hosted API does not rotate the
|
|
110
|
-
signing secret. Treat the reveal as sensitive: store it in your secret manager
|
|
111
|
-
and never log it.
|
|
112
|
-
|
|
113
|
-
CLI equivalent (prints the bare `whsec_...` string, pipeable into a secret
|
|
114
|
-
store; the reveal never goes to stderr or debug traces):
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
aex webhooks secret
|
|
118
|
-
```
|
|
1
|
+
---
|
|
2
|
+
title: Billing & webhook signing secret
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Billing & webhook signing secret
|
|
6
|
+
|
|
7
|
+
Workspace-level billing, subscription, and webhook verification calls are
|
|
8
|
+
token-scoped like every other client call — the workspace is derived
|
|
9
|
+
server-side from the API key.
|
|
10
|
+
|
|
11
|
+
The billing reads — `aex.billing()`, `aex.billingLedger()`, and the CLI
|
|
12
|
+
`aex billing` (and its `ledger` sub-verb) — require the **`billing:read`**
|
|
13
|
+
scope; a token without it fails with `403 insufficient_scope` (see
|
|
14
|
+
[Errors](errors.md)). This is why the [Quickstart](quickstart.md) mints
|
|
15
|
+
`billing:read` alongside `runs:read` / `runs:write` / `outputs:read`.
|
|
16
|
+
|
|
17
|
+
## Read the billing summary
|
|
18
|
+
|
|
19
|
+
`aex.billing()` returns the workspace's prepaid balance, current-month spend,
|
|
20
|
+
and the spend cap enforced on new runs, plus plan fields:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { Aex } from "@aexhq/sdk";
|
|
24
|
+
|
|
25
|
+
const aex = new Aex(process.env.AEX_API_KEY!);
|
|
26
|
+
const billing = await aex.billing();
|
|
27
|
+
console.log(billing.balanceUsd, billing.monthSpendUsd, billing.spendCapUsd);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The returned `BillingSummary` is additive-tolerant: fields a newer deployment
|
|
31
|
+
reports that this SDK version does not know yet pass through on the object
|
|
32
|
+
instead of being rejected.
|
|
33
|
+
|
|
34
|
+
CLI equivalent:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
aex billing # human-readable balance / month spend / spend cap
|
|
38
|
+
aex billing --json # the raw wire body for scripting
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Manage the subscription
|
|
42
|
+
|
|
43
|
+
`aex.billingCheckout({ planKey })` creates a hosted checkout session for a paid
|
|
44
|
+
plan. Open the returned URL in a browser; the workspace plan changes after
|
|
45
|
+
checkout completes and the hosted API confirms the subscription.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
const { url } = await aex.billingCheckout({
|
|
49
|
+
planKey: "pro",
|
|
50
|
+
idempotencyKey: crypto.randomUUID()
|
|
51
|
+
});
|
|
52
|
+
console.log(url);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`aex.billingPortal()` creates a hosted billing portal session for the workspace:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
const { url } = await aex.billingPortal({ returnUrl: "https://aex.dev/billing" });
|
|
59
|
+
console.log(url);
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
CLI equivalents:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
aex billing upgrade pro
|
|
66
|
+
aex billing portal
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Read the credit ledger
|
|
70
|
+
|
|
71
|
+
`aex.billingLedger({ limit })` returns recent credit-ledger rows, newest first —
|
|
72
|
+
allowance grants, adjustments, and run charges with signed `amountUsd` (credits
|
|
73
|
+
positive, charges negative). `limit` is clamped server-side to [1, 100] (default
|
|
74
|
+
25); the read is not cursor-paged.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const { entries } = await aex.billingLedger({ limit: 50 });
|
|
78
|
+
for (const entry of entries) {
|
|
79
|
+
console.log(entry.createdAt, entry.entryType, entry.amountUsd);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
CLI equivalent:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
aex billing ledger --limit 50 # JSON rows, newest first
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Reveal the webhook signing secret
|
|
90
|
+
|
|
91
|
+
Run webhooks are signed Standard-Webhooks style with a per-workspace secret.
|
|
92
|
+
`aex.webhookSigningSecret()` reveals it (creating one on first use) as the
|
|
93
|
+
`whsec_<base64>` string that `verifyAexWebhook` takes as `secret`:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { Aex, verifyAexWebhook } from "@aexhq/sdk";
|
|
97
|
+
|
|
98
|
+
const aex = new Aex(process.env.AEX_API_KEY!);
|
|
99
|
+
const { whsec } = await aex.webhookSigningSecret();
|
|
100
|
+
|
|
101
|
+
// In your webhook receiver:
|
|
102
|
+
const verified = await verifyAexWebhook({
|
|
103
|
+
rawBody, // the exact request body bytes as a string
|
|
104
|
+
headers, // the inbound request headers
|
|
105
|
+
secret: whsec
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Repeat calls return the SAME value — the hosted API does not rotate the
|
|
110
|
+
signing secret. Treat the reveal as sensitive: store it in your secret manager
|
|
111
|
+
and never log it.
|
|
112
|
+
|
|
113
|
+
CLI equivalent (prints the bare `whsec_...` string, pipeable into a secret
|
|
114
|
+
store; the reveal never goes to stderr or debug traces):
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
aex webhooks secret
|
|
118
|
+
```
|
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Agent tools
|
|
3
|
-
description: The default builtin tools available inside managed runs.
|
|
4
|
-
icon: TerminalSquare
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Managed runs inject the complete builtin tool set into the agent by default:
|
|
8
|
-
|
|
9
|
-
- `bash`, `code_execution` — run shell commands / model-written snippets
|
|
10
|
-
- `read_file`, `write_file`, `edit_file` — file read/create/patch
|
|
11
|
-
- `grep`, `glob` — search file contents and paths
|
|
12
|
-
- `head`, `tail` — read bounded file slices
|
|
13
|
-
- `ls`, `stat`, `wc` — list a directory, inspect path metadata, count lines/words/bytes
|
|
14
|
-
- `web_fetch`, `web_search` — fetch a URL / managed web search
|
|
15
|
-
- `todo_write` — maintain a todo list
|
|
16
|
-
- `subagent`, `subagent_result` — delegate to and read back from child runs (see [Subagents](subagents.md))
|
|
17
|
-
- `bash_output`, `bash_kill` — manage background bash jobs
|
|
18
|
-
- `wait`, `git` — bounded idle-yield and first-class git
|
|
19
|
-
|
|
20
|
-
## Toggling builtins
|
|
21
|
-
|
|
22
|
-
Set `includeBuiltinTools: false` to inject NO builtins — useful for a pure-MCP
|
|
23
|
-
or pure-custom run where every tool comes from `mcpServers` or `tools`.
|
|
24
|
-
|
|
25
|
-
`includeBuiltinTools` defaults to `true`.
|
|
26
|
-
|
|
27
|
-
## Cherry-picking builtins
|
|
28
|
-
|
|
29
|
-
The `tools` list accepts both custom tool bundles and BUILTIN tool references
|
|
30
|
-
(bare name strings, preferably `BuiltinTools.<name>`). Use builtin references
|
|
31
|
-
to pick a narrow subset alongside `includeBuiltinTools: false`.
|
|
32
|
-
|
|
33
|
-
The final tool list is ordered: resolved builtin tools, then custom tools, then
|
|
34
|
-
MCP tools.
|
|
35
|
-
|
|
36
|
-
## Custom tools
|
|
37
|
-
|
|
38
|
-
Attach your own tool in `tools` as a bundle built with `Tool.fromFiles(...)` (an
|
|
39
|
-
explicit `{ entry, files }`) or `Tool.fromPath(dir)` (a directory with a
|
|
40
|
-
`tool.json` at its root). The bundle's **entry must be a JS module** — a
|
|
41
|
-
`.js`/`.mjs`/`.cjs` file present in the bundle that **default-exports a function
|
|
42
|
-
or an object with an `execute` method**. This is validated at authoring time, so
|
|
43
|
-
a non-JS entry (e.g. a `run.sh`) is rejected right where you build the tool, not
|
|
44
|
-
opaquely mid-run when the runtime's module loader would fail to import it.
|
|
45
|
-
|
|
46
|
-
Networking is open by default within the platform's managed egress ceiling and
|
|
47
|
-
a fixed SSRF deny-list. `web_fetch` and `web_search` reach the network over a
|
|
48
|
-
managed, SSRF-guarded path that is **not** governed by `environment.networking`,
|
|
49
|
-
so their hosts never need to be listed in a `limited` allowlist. Setting
|
|
50
|
-
`environment.networking.mode` to `limited` restricts only the agent's own
|
|
51
|
-
arbitrary egress (e.g. a `curl` in `bash`); the built-in web tools keep working.
|
|
52
|
-
See [Networking](../networking.md) for the full two-layer model.
|
|
53
|
-
|
|
54
|
-
## Disable builtins
|
|
55
|
-
|
|
56
|
-
```ts
|
|
57
|
-
import { Models } from "@aexhq/sdk";
|
|
58
|
-
|
|
59
|
-
await aex.run({
|
|
60
|
-
model: Models.CLAUDE_HAIKU_4_5,
|
|
61
|
-
message: "Use only the declared MCP tools.",
|
|
62
|
-
mcpServers,
|
|
63
|
-
includeBuiltinTools: false,
|
|
64
|
-
apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
|
|
65
|
-
});
|
|
66
|
-
```
|
|
1
|
+
---
|
|
2
|
+
title: Agent tools
|
|
3
|
+
description: The default builtin tools available inside managed runs.
|
|
4
|
+
icon: TerminalSquare
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Managed runs inject the complete builtin tool set into the agent by default:
|
|
8
|
+
|
|
9
|
+
- `bash`, `code_execution` — run shell commands / model-written snippets
|
|
10
|
+
- `read_file`, `write_file`, `edit_file` — file read/create/patch
|
|
11
|
+
- `grep`, `glob` — search file contents and paths
|
|
12
|
+
- `head`, `tail` — read bounded file slices
|
|
13
|
+
- `ls`, `stat`, `wc` — list a directory, inspect path metadata, count lines/words/bytes
|
|
14
|
+
- `web_fetch`, `web_search` — fetch a URL / managed web search
|
|
15
|
+
- `todo_write` — maintain a todo list
|
|
16
|
+
- `subagent`, `subagent_result` — delegate to and read back from child runs (see [Subagents](subagents.md))
|
|
17
|
+
- `bash_output`, `bash_kill` — manage background bash jobs
|
|
18
|
+
- `wait`, `git` — bounded idle-yield and first-class git
|
|
19
|
+
|
|
20
|
+
## Toggling builtins
|
|
21
|
+
|
|
22
|
+
Set `includeBuiltinTools: false` to inject NO builtins — useful for a pure-MCP
|
|
23
|
+
or pure-custom run where every tool comes from `mcpServers` or `tools`.
|
|
24
|
+
|
|
25
|
+
`includeBuiltinTools` defaults to `true`.
|
|
26
|
+
|
|
27
|
+
## Cherry-picking builtins
|
|
28
|
+
|
|
29
|
+
The `tools` list accepts both custom tool bundles and BUILTIN tool references
|
|
30
|
+
(bare name strings, preferably `BuiltinTools.<name>`). Use builtin references
|
|
31
|
+
to pick a narrow subset alongside `includeBuiltinTools: false`.
|
|
32
|
+
|
|
33
|
+
The final tool list is ordered: resolved builtin tools, then custom tools, then
|
|
34
|
+
MCP tools.
|
|
35
|
+
|
|
36
|
+
## Custom tools
|
|
37
|
+
|
|
38
|
+
Attach your own tool in `tools` as a bundle built with `Tool.fromFiles(...)` (an
|
|
39
|
+
explicit `{ entry, files }`) or `Tool.fromPath(dir)` (a directory with a
|
|
40
|
+
`tool.json` at its root). The bundle's **entry must be a JS module** — a
|
|
41
|
+
`.js`/`.mjs`/`.cjs` file present in the bundle that **default-exports a function
|
|
42
|
+
or an object with an `execute` method**. This is validated at authoring time, so
|
|
43
|
+
a non-JS entry (e.g. a `run.sh`) is rejected right where you build the tool, not
|
|
44
|
+
opaquely mid-run when the runtime's module loader would fail to import it.
|
|
45
|
+
|
|
46
|
+
Networking is open by default within the platform's managed egress ceiling and
|
|
47
|
+
a fixed SSRF deny-list. `web_fetch` and `web_search` reach the network over a
|
|
48
|
+
managed, SSRF-guarded path that is **not** governed by `environment.networking`,
|
|
49
|
+
so their hosts never need to be listed in a `limited` allowlist. Setting
|
|
50
|
+
`environment.networking.mode` to `limited` restricts only the agent's own
|
|
51
|
+
arbitrary egress (e.g. a `curl` in `bash`); the built-in web tools keep working.
|
|
52
|
+
See [Networking](../networking.md) for the full two-layer model.
|
|
53
|
+
|
|
54
|
+
## Disable builtins
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import { Models } from "@aexhq/sdk";
|
|
58
|
+
|
|
59
|
+
await aex.run({
|
|
60
|
+
model: Models.CLAUDE_HAIKU_4_5,
|
|
61
|
+
message: "Use only the declared MCP tools.",
|
|
62
|
+
mcpServers,
|
|
63
|
+
includeBuiltinTools: false,
|
|
64
|
+
apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
|
|
65
|
+
});
|
|
66
|
+
```
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Composition
|
|
3
|
-
description: The primitives used to assemble each run.
|
|
4
|
-
icon: Blocks
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
aex composes an agent from explicit per-session inputs. The SDK materializes local
|
|
8
|
-
bytes before the session lands and the platform mounts them into the managed
|
|
9
|
-
runtime before the first agent turn.
|
|
10
|
-
|
|
11
|
-
| Need | Primitive |
|
|
12
|
-
| --- | --- |
|
|
1
|
+
---
|
|
2
|
+
title: Composition
|
|
3
|
+
description: The primitives used to assemble each run.
|
|
4
|
+
icon: Blocks
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
aex composes an agent from explicit per-session inputs. The SDK materializes local
|
|
8
|
+
bytes before the session lands and the platform mounts them into the managed
|
|
9
|
+
runtime before the first agent turn.
|
|
10
|
+
|
|
11
|
+
| Need | Primitive |
|
|
12
|
+
| --- | --- |
|
|
13
13
|
| Instructional skill bundles | `Skill.fromDir`, `Skill.fromUrl`, `Skill.fromFiles` |
|
|
14
|
-
| Agent instructions | `AgentsMd.fromPath`, `AgentsMd.fromContent` |
|
|
15
|
-
| Reference files and folders | `File.fromPath`, `File.fromBytes` |
|
|
16
|
-
| Remote tools | `McpServer.remote`, `McpServer.fromId` |
|
|
17
|
-
| Non-secret runtime settings | `environment.variables`, `environment.packages`, `environment.networking` |
|
|
18
|
-
| Runtime secrets for your code | `Secret.value`, `Secret.ref`, `environment.secrets` |
|
|
19
|
-
|
|
20
|
-
```ts
|
|
14
|
+
| Agent instructions | `AgentsMd.fromPath`, `AgentsMd.fromContent` |
|
|
15
|
+
| Reference files and folders | `File.fromPath`, `File.fromBytes` |
|
|
16
|
+
| Remote tools | `McpServer.remote`, `McpServer.fromId` |
|
|
17
|
+
| Non-secret runtime settings | `environment.variables`, `environment.packages`, `environment.networking` |
|
|
18
|
+
| Runtime secrets for your code | `Secret.value`, `Secret.ref`, `environment.secrets` |
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
21
|
import { AgentsMd, File, McpServer, Models, Secret, Skill } from "@aexhq/sdk";
|
|
22
|
-
|
|
23
|
-
await aex.run({
|
|
24
|
-
model: Models.CLAUDE_HAIKU_4_5,
|
|
25
|
-
message: "Use the attached docs and tools to produce a report.",
|
|
26
|
-
agentsMd: [await AgentsMd.fromContent("Follow the repo conventions.", { name: "repo-rules" })],
|
|
27
|
-
files: [await File.fromPath("./input")],
|
|
22
|
+
|
|
23
|
+
await aex.run({
|
|
24
|
+
model: Models.CLAUDE_HAIKU_4_5,
|
|
25
|
+
message: "Use the attached docs and tools to produce a report.",
|
|
26
|
+
agentsMd: [await AgentsMd.fromContent("Follow the repo conventions.", { name: "repo-rules" })],
|
|
27
|
+
files: [await File.fromPath("./input")],
|
|
28
28
|
skills: [await Skill.fromDir("./skills/report-writer", { name: "report-writer" })],
|
|
29
|
-
mcpServers: [McpServer.remote({ name: "github", url: "https://example.com/mcp" })],
|
|
30
|
-
environment: {
|
|
31
|
-
secrets: { INTERNAL_API_TOKEN: Secret.value(process.env.INTERNAL_API_TOKEN!) },
|
|
32
|
-
networking: { mode: "limited", allowedHosts: ["api.example.com"] }
|
|
33
|
-
},
|
|
34
|
-
apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
|
|
35
|
-
});
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Secrets stay out of reusable configs. Provider keys go in the top-level `apiKeys`
|
|
39
|
-
map; reusable or per-run values for your own code go in `environment.secrets`.
|
|
40
|
-
Your code then makes normal HTTP calls with the standard client for that service.
|
|
29
|
+
mcpServers: [McpServer.remote({ name: "github", url: "https://example.com/mcp" })],
|
|
30
|
+
environment: {
|
|
31
|
+
secrets: { INTERNAL_API_TOKEN: Secret.value(process.env.INTERNAL_API_TOKEN!) },
|
|
32
|
+
networking: { mode: "limited", allowedHosts: ["api.example.com"] }
|
|
33
|
+
},
|
|
34
|
+
apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Secrets stay out of reusable configs. Provider keys go in the top-level `apiKeys`
|
|
39
|
+
map; reusable or per-run values for your own code go in `environment.secrets`.
|
|
40
|
+
Your code then makes normal HTTP calls with the standard client for that service.
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Providers & runtimes
|
|
3
|
-
description: How provider selection maps to managed runtime execution.
|
|
4
|
-
icon: Network
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
aex exposes one submission shape across supported providers:
|
|
8
|
-
|
|
9
|
-
| Provider | Selector |
|
|
10
|
-
| --- | --- |
|
|
11
|
-
| Anthropic | `Providers.ANTHROPIC` |
|
|
12
|
-
| DeepSeek | `Providers.DEEPSEEK` |
|
|
13
|
-
| OpenAI | `Providers.OPENAI` |
|
|
14
|
-
| Gemini | `Providers.GEMINI` |
|
|
15
|
-
| Mistral | `Providers.MISTRAL` |
|
|
16
|
-
| OpenRouter | `Providers.OPENROUTER` |
|
|
17
|
-
| Doubao | `Providers.DOUBAO` |
|
|
18
|
-
| Doubao China | `Providers.DOUBAO_CN` |
|
|
19
|
-
|
|
20
|
-
All submissions run on the managed runtime. The optional `runtime` option picks
|
|
21
|
-
a managed machine-size preset — use `Sizes.*` in TypeScript (e.g.
|
|
22
|
-
`runtime: Sizes.SHARED_0_25X_1GB`) or `--runtime-size` in the CLI. Omit it for
|
|
23
|
-
the default size; there is no alternative runtime backend to select.
|
|
24
|
-
|
|
25
|
-
## Selection
|
|
26
|
-
|
|
27
|
-
### TypeScript
|
|
28
|
-
|
|
29
|
-
```ts
|
|
30
|
-
import { Models, Providers } from "@aexhq/sdk";
|
|
31
|
-
|
|
32
|
-
await aex.run({
|
|
33
|
-
provider: Providers.OPENAI,
|
|
34
|
-
model: Models.GPT_4_1,
|
|
35
|
-
message: "Summarise the attached files.",
|
|
36
|
-
apiKeys: { openai: process.env.OPENAI_API_KEY! }
|
|
37
|
-
});
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### CLI
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
aex run \
|
|
44
|
-
--api-key "$AEX_API_KEY" \
|
|
45
|
-
--provider openai \
|
|
46
|
-
--openai-api-key "$OPENAI_API_KEY" \
|
|
47
|
-
--model gpt-4.1 \
|
|
48
|
-
--prompt "Summarise the attached files." \
|
|
49
|
-
--follow
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Events, outputs, cleanup, and downloads use the same SDK and CLI surface for
|
|
53
|
-
every provider. For the exact supported model list, use the generated
|
|
54
|
-
[provider/runtime capability matrix](../provider-runtime-capabilities.md).
|
|
1
|
+
---
|
|
2
|
+
title: Providers & runtimes
|
|
3
|
+
description: How provider selection maps to managed runtime execution.
|
|
4
|
+
icon: Network
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
aex exposes one submission shape across supported providers:
|
|
8
|
+
|
|
9
|
+
| Provider | Selector |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| Anthropic | `Providers.ANTHROPIC` |
|
|
12
|
+
| DeepSeek | `Providers.DEEPSEEK` |
|
|
13
|
+
| OpenAI | `Providers.OPENAI` |
|
|
14
|
+
| Gemini | `Providers.GEMINI` |
|
|
15
|
+
| Mistral | `Providers.MISTRAL` |
|
|
16
|
+
| OpenRouter | `Providers.OPENROUTER` |
|
|
17
|
+
| Doubao | `Providers.DOUBAO` |
|
|
18
|
+
| Doubao China | `Providers.DOUBAO_CN` |
|
|
19
|
+
|
|
20
|
+
All submissions run on the managed runtime. The optional `runtime` option picks
|
|
21
|
+
a managed machine-size preset — use `Sizes.*` in TypeScript (e.g.
|
|
22
|
+
`runtime: Sizes.SHARED_0_25X_1GB`) or `--runtime-size` in the CLI. Omit it for
|
|
23
|
+
the default size; there is no alternative runtime backend to select.
|
|
24
|
+
|
|
25
|
+
## Selection
|
|
26
|
+
|
|
27
|
+
### TypeScript
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { Models, Providers } from "@aexhq/sdk";
|
|
31
|
+
|
|
32
|
+
await aex.run({
|
|
33
|
+
provider: Providers.OPENAI,
|
|
34
|
+
model: Models.GPT_4_1,
|
|
35
|
+
message: "Summarise the attached files.",
|
|
36
|
+
apiKeys: { openai: process.env.OPENAI_API_KEY! }
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### CLI
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
aex run \
|
|
44
|
+
--api-key "$AEX_API_KEY" \
|
|
45
|
+
--provider openai \
|
|
46
|
+
--openai-api-key "$OPENAI_API_KEY" \
|
|
47
|
+
--model gpt-4.1 \
|
|
48
|
+
--prompt "Summarise the attached files." \
|
|
49
|
+
--follow
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Events, outputs, cleanup, and downloads use the same SDK and CLI surface for
|
|
53
|
+
every provider. For the exact supported model list, use the generated
|
|
54
|
+
[provider/runtime capability matrix](../provider-runtime-capabilities.md).
|
package/docs/concepts/runs.md
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Runs
|
|
3
|
-
description: The durable unit aex submits, observes, and archives.
|
|
4
|
-
icon: Play
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
A run is a durable, resumable **session**: the model, system message, composition
|
|
8
|
-
primitives, output policy, and per-provider keys you open it with, plus every
|
|
9
|
-
turn you send to it. aex snapshots the non-secret inputs, holds secrets for the
|
|
10
|
-
session lifecycle, dispatches each turn through the managed runtime, and records
|
|
11
|
-
status, typed events, and outputs. Sessions are the low-level API; `run()` is the
|
|
12
|
-
one-shot convenience wrapper over them.
|
|
13
|
-
|
|
14
|
-
```ts
|
|
15
|
-
import { Aex, Models } from "@aexhq/sdk";
|
|
16
|
-
|
|
17
|
-
const aex = new Aex({ apiKey: process.env.AEX_API_KEY! });
|
|
18
|
-
|
|
19
|
-
const session = await aex.openSession({
|
|
20
|
-
provider: "anthropic",
|
|
21
|
-
model: Models.CLAUDE_HAIKU_4_5,
|
|
22
|
-
apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
const turn = session.send("Write the report and save it as a file.");
|
|
26
|
-
for await (const event of turn) {
|
|
27
|
-
console.log(event.type);
|
|
28
|
-
}
|
|
29
|
-
await turn.done();
|
|
30
|
-
|
|
31
|
-
await session.wait();
|
|
32
|
-
await session.download({ to: "./session.zip" });
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
The same durable record backs SDK and CLI reads. From the handle use `refresh`,
|
|
36
|
-
`unit`, `wait`, and `download` for lifecycle, plus the grouped read accessors —
|
|
37
|
-
`messages()`, `events()`, and `outputs()` (each with `list()`/`last()`/`first()`,
|
|
38
|
-
and `events().stream()` / `events().streamEnvelopes()` / `outputs().read(...)` for
|
|
39
|
-
streaming and byte-capped reads) — to inspect the session live or after it parks;
|
|
40
|
-
from the client, `aex.sessions.list()` / `aex.sessions.get(id)` read across the
|
|
41
|
-
workspace (CLI mirrors: `aex sessions` and `aex runs` list the workspace's
|
|
42
|
-
sessions/runs newest-first).
|
|
43
|
-
|
|
44
|
-
Use `idempotencyKey` when retrying `openSession` or `send` from your own
|
|
45
|
-
workflow. aex hashes the normalized non-secret submission, so a retry with the
|
|
46
|
-
same key and same body returns the existing session while a mismatched body fails
|
|
47
|
-
with an idempotency conflict.
|
|
48
|
-
|
|
49
|
-
aex selects product placement server-side. There is no region selector.
|
|
1
|
+
---
|
|
2
|
+
title: Runs
|
|
3
|
+
description: The durable unit aex submits, observes, and archives.
|
|
4
|
+
icon: Play
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
A run is a durable, resumable **session**: the model, system message, composition
|
|
8
|
+
primitives, output policy, and per-provider keys you open it with, plus every
|
|
9
|
+
turn you send to it. aex snapshots the non-secret inputs, holds secrets for the
|
|
10
|
+
session lifecycle, dispatches each turn through the managed runtime, and records
|
|
11
|
+
status, typed events, and outputs. Sessions are the low-level API; `run()` is the
|
|
12
|
+
one-shot convenience wrapper over them.
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { Aex, Models } from "@aexhq/sdk";
|
|
16
|
+
|
|
17
|
+
const aex = new Aex({ apiKey: process.env.AEX_API_KEY! });
|
|
18
|
+
|
|
19
|
+
const session = await aex.openSession({
|
|
20
|
+
provider: "anthropic",
|
|
21
|
+
model: Models.CLAUDE_HAIKU_4_5,
|
|
22
|
+
apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const turn = session.send("Write the report and save it as a file.");
|
|
26
|
+
for await (const event of turn) {
|
|
27
|
+
console.log(event.type);
|
|
28
|
+
}
|
|
29
|
+
await turn.done();
|
|
30
|
+
|
|
31
|
+
await session.wait();
|
|
32
|
+
await session.download({ to: "./session.zip" });
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The same durable record backs SDK and CLI reads. From the handle use `refresh`,
|
|
36
|
+
`unit`, `wait`, and `download` for lifecycle, plus the grouped read accessors —
|
|
37
|
+
`messages()`, `events()`, and `outputs()` (each with `list()`/`last()`/`first()`,
|
|
38
|
+
and `events().stream()` / `events().streamEnvelopes()` / `outputs().read(...)` for
|
|
39
|
+
streaming and byte-capped reads) — to inspect the session live or after it parks;
|
|
40
|
+
from the client, `aex.sessions.list()` / `aex.sessions.get(id)` read across the
|
|
41
|
+
workspace (CLI mirrors: `aex sessions` and `aex runs` list the workspace's
|
|
42
|
+
sessions/runs newest-first).
|
|
43
|
+
|
|
44
|
+
Use `idempotencyKey` when retrying `openSession` or `send` from your own
|
|
45
|
+
workflow. aex hashes the normalized non-secret submission, so a retry with the
|
|
46
|
+
same key and same body returns the existing session while a mismatched body fails
|
|
47
|
+
with an idempotency conflict.
|
|
48
|
+
|
|
49
|
+
aex selects product placement server-side. There is no region selector.
|