@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.
- package/README.md +159 -159
- package/dist/_contracts/asset-upload-helper.d.ts +38 -0
- package/dist/_contracts/asset-upload-helper.js +111 -0
- package/dist/_contracts/internal.d.ts +5 -9
- package/dist/_contracts/internal.js +5 -79
- package/dist/_contracts/operations.d.ts +9 -2
- package/dist/_contracts/operations.js +141 -16
- package/dist/_contracts/retry-core.d.ts +27 -0
- package/dist/_contracts/retry-core.js +75 -0
- package/dist/_contracts/runtime-types.d.ts +6 -0
- package/dist/_contracts/stable.d.ts +10 -5
- package/dist/_contracts/stable.js +10 -5
- package/dist/asset-upload.d.ts +2 -1
- package/dist/asset-upload.js +28 -61
- package/dist/asset-upload.js.map +1 -1
- package/dist/cli.mjs +297 -80
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +5 -0
- package/dist/client.js +8 -13
- package/dist/client.js.map +1 -1
- package/dist/retry.js +13 -41
- package/dist/retry.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/networking.md
CHANGED
|
@@ -1,163 +1,163 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Networking
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Networking
|
|
6
|
-
|
|
7
|
-
A run executes your agent's code in a sandbox with **no direct route to the
|
|
8
|
-
internet**. Outbound traffic is governed by **two layers**:
|
|
9
|
-
|
|
10
|
-
1. **The per-run policy (`environment.networking`)** — enforced by the agent
|
|
11
|
-
runtime *inside the run*. It applies to the standard proxy path every normal
|
|
12
|
-
HTTP client uses (see below) and can only *narrow* what the run may reach.
|
|
13
|
-
2. **The platform ceiling** — a fixed, platform-managed egress boundary every
|
|
14
|
-
connection ultimately traverses. It allows the hosts aex itself manages
|
|
15
|
-
(model providers, built-in tool endpoints, package registries, and related
|
|
16
|
-
well-known development hosts such as `github.com`) and enforces a fixed SSRF
|
|
17
|
-
deny-list: loopback, link-local, cloud-metadata, and other private ranges are
|
|
18
|
-
blocked on the standard proxy path every normal HTTP client uses, including
|
|
19
|
-
hostnames that resolve to those ranges. Note: on the current managed (Fargate)
|
|
20
|
-
plane a subprocess that deliberately bypasses the proxy with a **raw socket**
|
|
21
|
-
can still reach the on-link task-metadata IP (`169.254.170.2`), which exposes
|
|
22
|
-
non-secret task identity (AWS account id via the task ARN, cluster/image ref)
|
|
23
|
-
— but **never IAM credentials** (the run's task role is unset, so the metadata
|
|
24
|
-
credential endpoint serves nothing) and never another tenant's data.
|
|
25
|
-
|
|
26
|
-
Honest boundary statement: the per-run `allowedHosts` policy is enforced by the
|
|
27
|
-
run's own runtime on the standard proxy path — it is **not** yet enforced at
|
|
28
|
-
the platform proxy layer. A subprocess that deliberately bypasses the standard
|
|
29
|
-
proxy environment (a raw socket / raw CONNECT) is bounded by the **platform
|
|
30
|
-
ceiling** rather than by the per-run list. Per-run enforcement at the platform
|
|
31
|
-
proxy layer is planned; until it ships, treat `allowedHosts` as a strong
|
|
32
|
-
default-path control and an auditable statement of intent, not a hard isolation
|
|
33
|
-
boundary against adversarial code inside the run.
|
|
34
|
-
|
|
35
|
-
**Default posture.** A run that does not set `environment.networking` runs in
|
|
36
|
-
`open` mode: its own code may reach anything within the platform ceiling with
|
|
37
|
-
no allowlist required. Use `environment.networking` to *narrow* that surface
|
|
38
|
-
when you want a tighter, auditable egress posture. Code cannot widen the
|
|
39
|
-
ceiling from inside the container.
|
|
40
|
-
|
|
41
|
-
## Paths that always work
|
|
42
|
-
|
|
43
|
-
These reach the network over managed platform paths and are **not** subject to
|
|
44
|
-
`environment.networking`, so you never list their hosts:
|
|
45
|
-
|
|
46
|
-
- The model / provider call for the run (and its subagents).
|
|
47
|
-
- The built-in `web_search` and `web_fetch` tools. They run over a managed,
|
|
48
|
-
SSRF-guarded server-side path, which is why they can reach arbitrary public
|
|
49
|
-
URLs even though your own code is bounded by the ceiling.
|
|
50
|
-
- Remote MCP servers you declare in `mcpServers` — MCP traffic rides a managed
|
|
51
|
-
path; see [MCP](mcp.md).
|
|
52
|
-
- The package registries for any `environment.packages` you declare (pip → PyPI,
|
|
53
|
-
apt → the distribution mirrors). Declaring a package implicitly allows the
|
|
54
|
-
registry it installs from.
|
|
55
|
-
|
|
56
|
-
`environment.networking` governs the **other** case: outbound that your own
|
|
57
|
-
code makes — a `curl` in the `bash` tool, a `requests`/`urllib` call in Python,
|
|
58
|
-
a `fetch` in `code_execution`, or a third-party SDK.
|
|
59
|
-
|
|
60
|
-
## Restrict a run to an allowlist
|
|
61
|
-
|
|
62
|
-
Set `mode: "limited"` and list exactly the hosts your code is allowed to reach.
|
|
63
|
-
The run's runtime enforces the list on the standard proxy path: a connection to
|
|
64
|
-
a host that is neither on the list nor one of the always-allowed paths above is
|
|
65
|
-
refused before it leaves the run. Package-registry hosts implied by
|
|
66
|
-
`environment.packages` are appended automatically so installs keep working.
|
|
67
|
-
|
|
68
|
-
Note that `allowedHosts` narrows *within* the platform ceiling — listing a host
|
|
69
|
-
does not by itself make it reachable if the platform ceiling does not carry it.
|
|
70
|
-
If your run needs a host the ceiling blocks, contact support.
|
|
71
|
-
|
|
72
|
-
### TypeScript
|
|
73
|
-
|
|
74
|
-
```ts
|
|
75
|
-
import { Aex, Models, Providers } from "@aexhq/sdk";
|
|
76
|
-
|
|
77
|
-
const aex = new Aex({ apiKey: process.env.AEX_API_KEY! });
|
|
78
|
-
|
|
79
|
-
await aex.run({
|
|
80
|
-
provider: Providers.ANTHROPIC,
|
|
81
|
-
model: Models.CLAUDE_HAIKU_4_5,
|
|
82
|
-
message: "Fetch the public status page and summarize it.",
|
|
83
|
-
environment: {
|
|
84
|
-
networking: {
|
|
85
|
-
mode: "limited",
|
|
86
|
-
allowedHosts: ["api.example.com", "status.example.com"]
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
|
|
90
|
-
});
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
`allowedHosts` entries are host names (lowercased), e.g. `api.example.com`. Add a
|
|
94
|
-
non-default port when you need one (`api.example.com:8443`); a bare host name
|
|
95
|
-
covers HTTPS on 443. Matching is exact per host — it is not a wildcard or suffix
|
|
96
|
-
match, so list each host you need.
|
|
97
|
-
|
|
98
|
-
Keep the allowlist in your session options so the submitted network policy is
|
|
99
|
-
visible at the same call site as the code that needs it.
|
|
100
|
-
|
|
101
|
-
## Open mode
|
|
102
|
-
|
|
103
|
-
`open` is the default: a run that omits `environment.networking` already runs in
|
|
104
|
-
open mode. Set `mode: "open"` explicitly when you want to be unambiguous. Open
|
|
105
|
-
mode applies no per-run allowlist — the run's own code may reach anything the
|
|
106
|
-
platform ceiling allows, still subject to the SSRF deny-list. Prefer `limited`
|
|
107
|
-
whenever you can name the hosts — it gives the run a stable, auditable,
|
|
108
|
-
least-privilege egress surface (it is the tighter posture, not the default).
|
|
109
|
-
|
|
110
|
-
```ts
|
|
111
|
-
await aex.run({
|
|
112
|
-
model: Models.CLAUDE_HAIKU_4_5,
|
|
113
|
-
message: "Research the topic across the open web.",
|
|
114
|
-
environment: { networking: { mode: "open" } },
|
|
115
|
-
apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
|
|
116
|
-
});
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
(Web research like the example above flows through the managed `web_search` /
|
|
120
|
-
`web_fetch` path, which is not ceiling-bounded.)
|
|
121
|
-
|
|
122
|
-
## Transparent for normal HTTP clients
|
|
123
|
-
|
|
124
|
-
You write ordinary code — there is no per-request proxy configuration and no
|
|
125
|
-
client changes. The runtime sets the standard proxy environment
|
|
126
|
-
(`HTTP_PROXY` / `HTTPS_PROXY`, with `NO_PROXY` for internal hosts), so any client
|
|
127
|
-
that honors it — `curl`, Python `requests` / `urllib`, `pip`, `npm`, Node
|
|
128
|
-
`fetch`, and most language SDKs — reaches allowed hosts transparently:
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
# In the agent's shell, against a limited run that allows api.example.com:
|
|
132
|
-
curl -sS https://api.example.com/v1/status # works
|
|
133
|
-
curl -sS https://other-host.example # refused (not in allowlist)
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
You also do **not** need to install any certificate. The platform manages the
|
|
137
|
-
trust store for the managed egress path automatically, so TLS verification in
|
|
138
|
-
your client succeeds without extra setup.
|
|
139
|
-
|
|
140
|
-
## Limitations and gotchas
|
|
141
|
-
|
|
142
|
-
- **The per-run policy is enforced by the run's runtime, not at the platform
|
|
143
|
-
proxy.** Clients that honor the standard proxy environment (almost all HTTP
|
|
144
|
-
tooling) are held to the `allowedHosts` list. A subprocess that deliberately
|
|
145
|
-
ignores the proxy environment and opens a raw connection is **not** held to
|
|
146
|
-
the per-run list — it is bounded by the platform ceiling (the aex-managed
|
|
147
|
-
provider/tool/registry host set) and the SSRF deny-list instead. Per-run
|
|
148
|
-
enforcement at the platform proxy layer is planned.
|
|
149
|
-
- **A client that hard-bypasses the standard environment may fail to connect.**
|
|
150
|
-
A client that ignores the proxy environment, pins or replaces its certificate
|
|
151
|
-
trust store, or speaks a non-HTTP protocol over a raw socket can hit a wall
|
|
152
|
-
even for a host you allowed. The fix is to let the client use the standard
|
|
153
|
-
proxy and certificate environment the runtime provides (most libraries do by
|
|
154
|
-
default), rather than overriding it.
|
|
155
|
-
- **`allowedHosts` only applies in `limited` mode.** It is ignored in `open`
|
|
156
|
-
mode, where the platform ceiling and the SSRF deny-list are the gates.
|
|
157
|
-
- **`allowedHosts` cannot exceed the platform ceiling.** It narrows; it never
|
|
158
|
-
widens. A listed host outside the ceiling still fails.
|
|
159
|
-
|
|
160
|
-
For credentialed HTTP calls, pass the credential as an `environment.secrets`
|
|
161
|
-
entry and let your code use its normal HTTP client. For remote tool servers, see
|
|
162
|
-
[MCP](mcp.md). For the full set of run-config fields, see
|
|
163
|
-
[Run configuration](run-config.md).
|
|
1
|
+
---
|
|
2
|
+
title: Networking
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Networking
|
|
6
|
+
|
|
7
|
+
A run executes your agent's code in a sandbox with **no direct route to the
|
|
8
|
+
internet**. Outbound traffic is governed by **two layers**:
|
|
9
|
+
|
|
10
|
+
1. **The per-run policy (`environment.networking`)** — enforced by the agent
|
|
11
|
+
runtime *inside the run*. It applies to the standard proxy path every normal
|
|
12
|
+
HTTP client uses (see below) and can only *narrow* what the run may reach.
|
|
13
|
+
2. **The platform ceiling** — a fixed, platform-managed egress boundary every
|
|
14
|
+
connection ultimately traverses. It allows the hosts aex itself manages
|
|
15
|
+
(model providers, built-in tool endpoints, package registries, and related
|
|
16
|
+
well-known development hosts such as `github.com`) and enforces a fixed SSRF
|
|
17
|
+
deny-list: loopback, link-local, cloud-metadata, and other private ranges are
|
|
18
|
+
blocked on the standard proxy path every normal HTTP client uses, including
|
|
19
|
+
hostnames that resolve to those ranges. Note: on the current managed (Fargate)
|
|
20
|
+
plane a subprocess that deliberately bypasses the proxy with a **raw socket**
|
|
21
|
+
can still reach the on-link task-metadata IP (`169.254.170.2`), which exposes
|
|
22
|
+
non-secret task identity (AWS account id via the task ARN, cluster/image ref)
|
|
23
|
+
— but **never IAM credentials** (the run's task role is unset, so the metadata
|
|
24
|
+
credential endpoint serves nothing) and never another tenant's data.
|
|
25
|
+
|
|
26
|
+
Honest boundary statement: the per-run `allowedHosts` policy is enforced by the
|
|
27
|
+
run's own runtime on the standard proxy path — it is **not** yet enforced at
|
|
28
|
+
the platform proxy layer. A subprocess that deliberately bypasses the standard
|
|
29
|
+
proxy environment (a raw socket / raw CONNECT) is bounded by the **platform
|
|
30
|
+
ceiling** rather than by the per-run list. Per-run enforcement at the platform
|
|
31
|
+
proxy layer is planned; until it ships, treat `allowedHosts` as a strong
|
|
32
|
+
default-path control and an auditable statement of intent, not a hard isolation
|
|
33
|
+
boundary against adversarial code inside the run.
|
|
34
|
+
|
|
35
|
+
**Default posture.** A run that does not set `environment.networking` runs in
|
|
36
|
+
`open` mode: its own code may reach anything within the platform ceiling with
|
|
37
|
+
no allowlist required. Use `environment.networking` to *narrow* that surface
|
|
38
|
+
when you want a tighter, auditable egress posture. Code cannot widen the
|
|
39
|
+
ceiling from inside the container.
|
|
40
|
+
|
|
41
|
+
## Paths that always work
|
|
42
|
+
|
|
43
|
+
These reach the network over managed platform paths and are **not** subject to
|
|
44
|
+
`environment.networking`, so you never list their hosts:
|
|
45
|
+
|
|
46
|
+
- The model / provider call for the run (and its subagents).
|
|
47
|
+
- The built-in `web_search` and `web_fetch` tools. They run over a managed,
|
|
48
|
+
SSRF-guarded server-side path, which is why they can reach arbitrary public
|
|
49
|
+
URLs even though your own code is bounded by the ceiling.
|
|
50
|
+
- Remote MCP servers you declare in `mcpServers` — MCP traffic rides a managed
|
|
51
|
+
path; see [MCP](mcp.md).
|
|
52
|
+
- The package registries for any `environment.packages` you declare (pip → PyPI,
|
|
53
|
+
apt → the distribution mirrors). Declaring a package implicitly allows the
|
|
54
|
+
registry it installs from.
|
|
55
|
+
|
|
56
|
+
`environment.networking` governs the **other** case: outbound that your own
|
|
57
|
+
code makes — a `curl` in the `bash` tool, a `requests`/`urllib` call in Python,
|
|
58
|
+
a `fetch` in `code_execution`, or a third-party SDK.
|
|
59
|
+
|
|
60
|
+
## Restrict a run to an allowlist
|
|
61
|
+
|
|
62
|
+
Set `mode: "limited"` and list exactly the hosts your code is allowed to reach.
|
|
63
|
+
The run's runtime enforces the list on the standard proxy path: a connection to
|
|
64
|
+
a host that is neither on the list nor one of the always-allowed paths above is
|
|
65
|
+
refused before it leaves the run. Package-registry hosts implied by
|
|
66
|
+
`environment.packages` are appended automatically so installs keep working.
|
|
67
|
+
|
|
68
|
+
Note that `allowedHosts` narrows *within* the platform ceiling — listing a host
|
|
69
|
+
does not by itself make it reachable if the platform ceiling does not carry it.
|
|
70
|
+
If your run needs a host the ceiling blocks, contact support.
|
|
71
|
+
|
|
72
|
+
### TypeScript
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import { Aex, Models, Providers } from "@aexhq/sdk";
|
|
76
|
+
|
|
77
|
+
const aex = new Aex({ apiKey: process.env.AEX_API_KEY! });
|
|
78
|
+
|
|
79
|
+
await aex.run({
|
|
80
|
+
provider: Providers.ANTHROPIC,
|
|
81
|
+
model: Models.CLAUDE_HAIKU_4_5,
|
|
82
|
+
message: "Fetch the public status page and summarize it.",
|
|
83
|
+
environment: {
|
|
84
|
+
networking: {
|
|
85
|
+
mode: "limited",
|
|
86
|
+
allowedHosts: ["api.example.com", "status.example.com"]
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`allowedHosts` entries are host names (lowercased), e.g. `api.example.com`. Add a
|
|
94
|
+
non-default port when you need one (`api.example.com:8443`); a bare host name
|
|
95
|
+
covers HTTPS on 443. Matching is exact per host — it is not a wildcard or suffix
|
|
96
|
+
match, so list each host you need.
|
|
97
|
+
|
|
98
|
+
Keep the allowlist in your session options so the submitted network policy is
|
|
99
|
+
visible at the same call site as the code that needs it.
|
|
100
|
+
|
|
101
|
+
## Open mode
|
|
102
|
+
|
|
103
|
+
`open` is the default: a run that omits `environment.networking` already runs in
|
|
104
|
+
open mode. Set `mode: "open"` explicitly when you want to be unambiguous. Open
|
|
105
|
+
mode applies no per-run allowlist — the run's own code may reach anything the
|
|
106
|
+
platform ceiling allows, still subject to the SSRF deny-list. Prefer `limited`
|
|
107
|
+
whenever you can name the hosts — it gives the run a stable, auditable,
|
|
108
|
+
least-privilege egress surface (it is the tighter posture, not the default).
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
await aex.run({
|
|
112
|
+
model: Models.CLAUDE_HAIKU_4_5,
|
|
113
|
+
message: "Research the topic across the open web.",
|
|
114
|
+
environment: { networking: { mode: "open" } },
|
|
115
|
+
apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
(Web research like the example above flows through the managed `web_search` /
|
|
120
|
+
`web_fetch` path, which is not ceiling-bounded.)
|
|
121
|
+
|
|
122
|
+
## Transparent for normal HTTP clients
|
|
123
|
+
|
|
124
|
+
You write ordinary code — there is no per-request proxy configuration and no
|
|
125
|
+
client changes. The runtime sets the standard proxy environment
|
|
126
|
+
(`HTTP_PROXY` / `HTTPS_PROXY`, with `NO_PROXY` for internal hosts), so any client
|
|
127
|
+
that honors it — `curl`, Python `requests` / `urllib`, `pip`, `npm`, Node
|
|
128
|
+
`fetch`, and most language SDKs — reaches allowed hosts transparently:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# In the agent's shell, against a limited run that allows api.example.com:
|
|
132
|
+
curl -sS https://api.example.com/v1/status # works
|
|
133
|
+
curl -sS https://other-host.example # refused (not in allowlist)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
You also do **not** need to install any certificate. The platform manages the
|
|
137
|
+
trust store for the managed egress path automatically, so TLS verification in
|
|
138
|
+
your client succeeds without extra setup.
|
|
139
|
+
|
|
140
|
+
## Limitations and gotchas
|
|
141
|
+
|
|
142
|
+
- **The per-run policy is enforced by the run's runtime, not at the platform
|
|
143
|
+
proxy.** Clients that honor the standard proxy environment (almost all HTTP
|
|
144
|
+
tooling) are held to the `allowedHosts` list. A subprocess that deliberately
|
|
145
|
+
ignores the proxy environment and opens a raw connection is **not** held to
|
|
146
|
+
the per-run list — it is bounded by the platform ceiling (the aex-managed
|
|
147
|
+
provider/tool/registry host set) and the SSRF deny-list instead. Per-run
|
|
148
|
+
enforcement at the platform proxy layer is planned.
|
|
149
|
+
- **A client that hard-bypasses the standard environment may fail to connect.**
|
|
150
|
+
A client that ignores the proxy environment, pins or replaces its certificate
|
|
151
|
+
trust store, or speaks a non-HTTP protocol over a raw socket can hit a wall
|
|
152
|
+
even for a host you allowed. The fix is to let the client use the standard
|
|
153
|
+
proxy and certificate environment the runtime provides (most libraries do by
|
|
154
|
+
default), rather than overriding it.
|
|
155
|
+
- **`allowedHosts` only applies in `limited` mode.** It is ignored in `open`
|
|
156
|
+
mode, where the platform ceiling and the SSRF deny-list are the gates.
|
|
157
|
+
- **`allowedHosts` cannot exceed the platform ceiling.** It narrows; it never
|
|
158
|
+
widens. A listed host outside the ceiling still fails.
|
|
159
|
+
|
|
160
|
+
For credentialed HTTP calls, pass the credential as an `environment.secrets`
|
|
161
|
+
entry and let your code use its normal HTTP client. For remote tool servers, see
|
|
162
|
+
[MCP](mcp.md). For the full set of run-config fields, see
|
|
163
|
+
[Run configuration](run-config.md).
|