@aexhq/sdk 0.40.6 → 0.40.8

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.
Files changed (53) hide show
  1. package/README.md +159 -159
  2. package/dist/_contracts/asset-upload-helper.d.ts +38 -0
  3. package/dist/_contracts/asset-upload-helper.js +111 -0
  4. package/dist/_contracts/internal.d.ts +5 -9
  5. package/dist/_contracts/internal.js +5 -79
  6. package/dist/_contracts/operations.d.ts +9 -2
  7. package/dist/_contracts/operations.js +141 -16
  8. package/dist/_contracts/retry-core.d.ts +27 -0
  9. package/dist/_contracts/retry-core.js +75 -0
  10. package/dist/_contracts/runtime-types.d.ts +6 -0
  11. package/dist/_contracts/stable.d.ts +10 -5
  12. package/dist/_contracts/stable.js +10 -5
  13. package/dist/asset-upload.d.ts +2 -1
  14. package/dist/asset-upload.js +28 -61
  15. package/dist/asset-upload.js.map +1 -1
  16. package/dist/cli.mjs +297 -80
  17. package/dist/cli.mjs.sha256 +1 -1
  18. package/dist/client.d.ts +5 -0
  19. package/dist/client.js +8 -13
  20. package/dist/client.js.map +1 -1
  21. package/dist/retry.js +13 -41
  22. package/dist/retry.js.map +1 -1
  23. package/dist/version.d.ts +1 -1
  24. package/dist/version.js +1 -1
  25. package/docs/authentication.md +125 -125
  26. package/docs/billing.md +118 -118
  27. package/docs/concepts/agent-tools.md +66 -66
  28. package/docs/concepts/composition.md +37 -37
  29. package/docs/concepts/providers-and-runtimes.md +54 -54
  30. package/docs/concepts/runs.md +49 -49
  31. package/docs/concepts/subagents.md +88 -88
  32. package/docs/credentials.md +125 -125
  33. package/docs/defaults.md +64 -64
  34. package/docs/errors.md +196 -196
  35. package/docs/events.md +243 -243
  36. package/docs/limits-and-quotas.md +144 -144
  37. package/docs/limits.md +50 -50
  38. package/docs/mcp.md +44 -44
  39. package/docs/networking.md +163 -163
  40. package/docs/outputs.md +267 -267
  41. package/docs/public-surface.json +77 -77
  42. package/docs/quickstart.md +119 -119
  43. package/docs/release.md +38 -38
  44. package/docs/retries.md +129 -129
  45. package/docs/run-config.md +58 -58
  46. package/docs/run-record.md +55 -55
  47. package/docs/secrets.md +125 -125
  48. package/docs/testing.md +35 -35
  49. package/docs/vision-skills.md +91 -91
  50. package/docs/webhooks.md +127 -127
  51. package/examples/feature-tour.ts +282 -282
  52. package/examples/spike-settle-latency.ts +125 -125
  53. package/package.json +1 -1
@@ -1,125 +1,125 @@
1
- ---
2
- title: Authentication
3
- ---
4
-
5
- # Authentication
6
-
7
- Every SDK and CLI call authenticates with an **aex API key**: a bearer
8
- credential that is **workspace-scoped** — the workspace is derived server-side
9
- from the token, so there is no workspace parameter anywhere in the API. A
10
- request either carries a valid token for a workspace or it is rejected with
11
- `401 unauthorized` (see [Errors](errors.md)).
12
-
13
- ## Getting a token (invite-only beta)
14
-
15
- aex is currently in **invite-only beta**. Workspaces and their initial API
16
- tokens are provisioned by the aex team — contact <support@aex.dev> for beta
17
- access. Once your workspace exists, you can create and delete additional tokens
18
- in the dashboard at <https://aex.dev>.
19
-
20
- ## Using a token
21
-
22
- Pass the token to the SDK constructor, the CLI's `--api-key` flag, or persist
23
- it once with `aex login`:
24
-
25
- ```ts
26
- import { Aex } from "@aexhq/sdk";
27
-
28
- const aex = new Aex(process.env.AEX_API_KEY!);
29
- ```
30
-
31
- ```bash
32
- npx aex whoami --api-key "$AEX_API_KEY"
33
-
34
- # or persist it once, then omit --api-key on later commands:
35
- npx aex login --api-key "$AEX_API_KEY"
36
- npx aex whoami
37
- ```
38
-
39
- (`new Aex(apiKey)` is the canonical constructor; the equivalent options form is
40
- documented once in [Credentials](credentials.md).)
41
-
42
- The token travels as a standard `Authorization: Bearer` header. Treat it like
43
- any other secret: keep it in environment variables or a secret manager, never
44
- in run config, prompts, or committed files.
45
-
46
- ## Plane routing and the `baseUrl` guard
47
-
48
- An aex API key is **self-describing**: it embeds the plane (`dev` / `prd`) and
49
- region it was minted for. The constructor parses the key and routes accordingly,
50
- with **zero network**:
51
-
52
- - **Omit `baseUrl`** and a `prd` key routes to the canonical hosted API plane
53
- (`https://api.aex.dev`). A `dev` key has no stable public host yet, so a dev
54
- key with no `baseUrl` throws `CredentialValidationError` asking you to pass one.
55
- - **Supply a `baseUrl` whose plane disagrees with the key** (e.g. a `dev` key
56
- pointed at `https://api.aex.dev`) and the constructor throws
57
- `CredentialValidationError` **before any request** — you no longer discover the
58
- mismatch as a late `401 token_invalid` after a full round-trip.
59
-
60
- ```ts
61
- // prd key → routes to https://api.aex.dev automatically:
62
- const prd = new Aex(process.env.AEX_PRD_KEY!);
63
-
64
- // dev key → pass the dev plane's baseUrl explicitly:
65
- const dev = new Aex(process.env.AEX_DEV_KEY!, { baseUrl: process.env.AEX_DEV_URL! });
66
- ```
67
-
68
- ## Scopes
69
-
70
- A token carries a set of **scopes**; every API route requires one, and a token
71
- that lacks the route's scope fails with `403 insufficient_scope` naming the
72
- missing scope. The customer-grantable scopes:
73
-
74
- | Scope | Grants |
75
- | --- | --- |
76
- | `runs:read` | Read sessions/runs, their events and event archives, and webhook delivery ledgers. |
77
- | `runs:write` | Open sessions, send turns, submit runs, suspend/resume, redeliver webhooks, reveal the webhook signing secret. |
78
- | `runs:cancel` | Cancel a session/run. |
79
- | `runs:delete` | Delete a session/run record. |
80
- | `outputs:read` | List, read, download, and mint links for captured outputs. |
81
- | `files:write` | Upload asset bytes (files, skills, AGENTS.md) staged for a run. |
82
- | `files:delete` | Delete workspace asset-store entries. |
83
- | `secrets:read` | List workspace secrets and read their metadata (never values). |
84
- | `secrets:write` | Create, rotate, and delete workspace secrets. |
85
- | `mcp:read` | List and read workspace MCP server configurations. |
86
- | `mcp:write` | Create workspace MCP server configurations. |
87
- | `mcp:delete` | Delete workspace MCP server configurations. |
88
- | `billing:read` | Read billing state and create hosted billing sessions. |
89
- | `workspaces:delete` | Owner self-service workspace hard-erase. |
90
-
91
- Tokens may additionally carry the reserved scopes `skills:read` /
92
- `skills:write` / `skills:delete`, `agentsmd:read` / `agentsmd:write` /
93
- `agentsmd:delete`, and `files:read`. No API route requires them today — skill
94
- and AGENTS.md asset uploads are covered by `files:write` — so treat them as
95
- inert placeholders for future per-asset-type routes.
96
-
97
- A typical automation token carries `runs:read`, `runs:write`, and
98
- `outputs:read`. Grant the rest only where the workload needs them — a read-only
99
- reporting token, for example, needs no `runs:write`.
100
-
101
- ## Introspection: `whoami`
102
-
103
- `aex.whoami()` (CLI: `aex whoami`) validates the token and returns the
104
- workspace id, the token's scopes, and — on current platform deployments — a
105
- `limits` object with the workspace's effective admission caps
106
- (`maxConcurrentRuns`, `submitRatePerMinute`, `spendCapUsd`, `monthSpendUsd`,
107
- `balanceUsd`, `balanceGraceFloorUsd`, `paymentMethodStatus`), resolved by the
108
- same code the submit gates enforce. Use it as a cheap credential check and to
109
- anticipate `429`/`402` rejections before submitting — see
110
- [Limits & quotas](limits-and-quotas.md) and [Errors](errors.md).
111
-
112
- ## Rotation and revocation
113
-
114
- - **Rotate** by creating a new token in the dashboard, switching your
115
- deployment to it, then deleting the old one. Tokens are independent — both
116
- stay valid during the switch, so rotation needs no downtime.
117
- - **Revoke** by deleting the token in the dashboard; deletion takes effect
118
- immediately (allow up to a minute for in-flight caches to expire).
119
- - Token create/delete are rate-limited per workspace (see
120
- [Limits & quotas](limits-and-quotas.md)).
121
- - If you cannot reach the dashboard (or suspect workspace-level compromise),
122
- contact <support@aex.dev>.
123
-
124
- Provider keys (`apiKeys`) and runtime secrets are a separate, per-call surface —
125
- see [Credentials](credentials.md) and [Secrets](secrets.md).
1
+ ---
2
+ title: Authentication
3
+ ---
4
+
5
+ # Authentication
6
+
7
+ Every SDK and CLI call authenticates with an **aex API key**: a bearer
8
+ credential that is **workspace-scoped** — the workspace is derived server-side
9
+ from the token, so there is no workspace parameter anywhere in the API. A
10
+ request either carries a valid token for a workspace or it is rejected with
11
+ `401 unauthorized` (see [Errors](errors.md)).
12
+
13
+ ## Getting a token (invite-only beta)
14
+
15
+ aex is currently in **invite-only beta**. Workspaces and their initial API
16
+ tokens are provisioned by the aex team — contact <support@aex.dev> for beta
17
+ access. Once your workspace exists, you can create and delete additional tokens
18
+ in the dashboard at <https://aex.dev>.
19
+
20
+ ## Using a token
21
+
22
+ Pass the token to the SDK constructor, the CLI's `--api-key` flag, or persist
23
+ it once with `aex login`:
24
+
25
+ ```ts
26
+ import { Aex } from "@aexhq/sdk";
27
+
28
+ const aex = new Aex(process.env.AEX_API_KEY!);
29
+ ```
30
+
31
+ ```bash
32
+ npx aex whoami --api-key "$AEX_API_KEY"
33
+
34
+ # or persist it once, then omit --api-key on later commands:
35
+ npx aex login --api-key "$AEX_API_KEY"
36
+ npx aex whoami
37
+ ```
38
+
39
+ (`new Aex(apiKey)` is the canonical constructor; the equivalent options form is
40
+ documented once in [Credentials](credentials.md).)
41
+
42
+ The token travels as a standard `Authorization: Bearer` header. Treat it like
43
+ any other secret: keep it in environment variables or a secret manager, never
44
+ in run config, prompts, or committed files.
45
+
46
+ ## Plane routing and the `baseUrl` guard
47
+
48
+ An aex API key is **self-describing**: it embeds the plane (`dev` / `prd`) and
49
+ region it was minted for. The constructor parses the key and routes accordingly,
50
+ with **zero network**:
51
+
52
+ - **Omit `baseUrl`** and the key routes to its canonical hosted API plane:
53
+ `prd` keys route to `https://api.aex.dev`, and `dev` keys route to
54
+ `https://dev-api.aex.dev`.
55
+ - **Supply a `baseUrl` whose plane disagrees with the key** (e.g. a `dev` key
56
+ pointed at `https://api.aex.dev`) and the constructor throws
57
+ `CredentialValidationError` **before any request** — you no longer discover the
58
+ mismatch as a late `401 token_invalid` after a full round-trip.
59
+
60
+ ```ts
61
+ // prd key → routes to https://api.aex.dev automatically:
62
+ const prd = new Aex(process.env.AEX_PRD_KEY!);
63
+
64
+ // dev key → routes to https://dev-api.aex.dev automatically:
65
+ const dev = new Aex(process.env.AEX_DEV_KEY!);
66
+ ```
67
+
68
+ ## Scopes
69
+
70
+ A token carries a set of **scopes**; every API route requires one, and a token
71
+ that lacks the route's scope fails with `403 insufficient_scope` naming the
72
+ missing scope. The customer-grantable scopes:
73
+
74
+ | Scope | Grants |
75
+ | --- | --- |
76
+ | `runs:read` | Read sessions/runs, their events and event archives, and webhook delivery ledgers. |
77
+ | `runs:write` | Open sessions, send turns, submit runs, suspend/resume, redeliver webhooks, reveal the webhook signing secret. |
78
+ | `runs:cancel` | Cancel a session/run. |
79
+ | `runs:delete` | Delete a session/run record. |
80
+ | `outputs:read` | List, read, download, and mint links for captured outputs. |
81
+ | `files:write` | Upload asset bytes (files, skills, AGENTS.md) staged for a run. |
82
+ | `files:delete` | Delete workspace asset-store entries. |
83
+ | `secrets:read` | List workspace secrets and read their metadata (never values). |
84
+ | `secrets:write` | Create, rotate, and delete workspace secrets. |
85
+ | `mcp:read` | List and read workspace MCP server configurations. |
86
+ | `mcp:write` | Create workspace MCP server configurations. |
87
+ | `mcp:delete` | Delete workspace MCP server configurations. |
88
+ | `billing:read` | Read billing state and create hosted billing sessions. |
89
+ | `workspaces:delete` | Owner self-service workspace hard-erase. |
90
+
91
+ Tokens may additionally carry the reserved scopes `skills:read` /
92
+ `skills:write` / `skills:delete`, `agentsmd:read` / `agentsmd:write` /
93
+ `agentsmd:delete`, and `files:read`. No API route requires them today — skill
94
+ and AGENTS.md asset uploads are covered by `files:write` — so treat them as
95
+ inert placeholders for future per-asset-type routes.
96
+
97
+ A typical automation token carries `runs:read`, `runs:write`, and
98
+ `outputs:read`. Grant the rest only where the workload needs them — a read-only
99
+ reporting token, for example, needs no `runs:write`.
100
+
101
+ ## Introspection: `whoami`
102
+
103
+ `aex.whoami()` (CLI: `aex whoami`) validates the token and returns the
104
+ workspace id, the token's scopes, and — on current platform deployments — a
105
+ `limits` object with the workspace's effective admission caps
106
+ (`maxConcurrentRuns`, `submitRatePerMinute`, `spendCapUsd`, `monthSpendUsd`,
107
+ `balanceUsd`, `balanceGraceFloorUsd`, `paymentMethodStatus`), resolved by the
108
+ same code the submit gates enforce. Use it as a cheap credential check and to
109
+ anticipate `429`/`402` rejections before submitting — see
110
+ [Limits & quotas](limits-and-quotas.md) and [Errors](errors.md).
111
+
112
+ ## Rotation and revocation
113
+
114
+ - **Rotate** by creating a new token in the dashboard, switching your
115
+ deployment to it, then deleting the old one. Tokens are independent — both
116
+ stay valid during the switch, so rotation needs no downtime.
117
+ - **Revoke** by deleting the token in the dashboard; deletion takes effect
118
+ immediately (allow up to a minute for in-flight caches to expire).
119
+ - Token create/delete are rate-limited per workspace (see
120
+ [Limits & quotas](limits-and-quotas.md)).
121
+ - If you cannot reach the dashboard (or suspect workspace-level compromise),
122
+ contact <support@aex.dev>.
123
+
124
+ Provider keys (`apiKeys`) and runtime secrets are a separate, per-call surface —
125
+ see [Credentials](credentials.md) and [Secrets](secrets.md).
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
+ ```