@aexhq/sdk 0.35.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +16 -15
  2. package/dist/_contracts/index.d.ts +3 -4
  3. package/dist/_contracts/index.js +1 -4
  4. package/dist/_contracts/operations.d.ts +2 -1
  5. package/dist/_contracts/operations.js +10 -0
  6. package/dist/_contracts/run-config.d.ts +1 -3
  7. package/dist/_contracts/run-config.js +2 -7
  8. package/dist/_contracts/run-trace.d.ts +0 -86
  9. package/dist/_contracts/run-trace.js +1 -184
  10. package/dist/_contracts/run-unit.d.ts +2 -25
  11. package/dist/_contracts/run-unit.js +1 -2
  12. package/dist/_contracts/runtime-manifest.d.ts +1 -1
  13. package/dist/_contracts/runtime-security-profile.d.ts +0 -2
  14. package/dist/_contracts/runtime-security-profile.js +0 -9
  15. package/dist/_contracts/runtime-types.d.ts +25 -4
  16. package/dist/_contracts/stable.d.ts +1 -1
  17. package/dist/_contracts/stable.js +1 -1
  18. package/dist/_contracts/submission.d.ts +4 -72
  19. package/dist/_contracts/submission.js +5 -472
  20. package/dist/cli.mjs +20 -442
  21. package/dist/cli.mjs.sha256 +1 -1
  22. package/dist/client.d.ts +30 -25
  23. package/dist/client.js +251 -66
  24. package/dist/client.js.map +1 -1
  25. package/dist/index.d.ts +7 -15
  26. package/dist/index.js +5 -17
  27. package/dist/index.js.map +1 -1
  28. package/dist/secret.d.ts +2 -2
  29. package/dist/secret.js +1 -1
  30. package/dist/version.d.ts +1 -1
  31. package/dist/version.js +1 -1
  32. package/docs/concepts/composition.md +8 -14
  33. package/docs/credentials.md +59 -101
  34. package/docs/defaults.md +0 -8
  35. package/docs/events.md +8 -9
  36. package/docs/limits-and-quotas.md +1 -4
  37. package/docs/limits.md +2 -6
  38. package/docs/mcp.md +4 -5
  39. package/docs/networking.md +6 -16
  40. package/docs/outputs.md +0 -4
  41. package/docs/public-surface.json +3 -3
  42. package/docs/quickstart.md +3 -7
  43. package/docs/run-config.md +6 -3
  44. package/docs/secrets.md +1 -1
  45. package/docs/skills.md +3 -3
  46. package/docs/vision-skills.md +52 -101
  47. package/examples/feature-tour.ts +4 -21
  48. package/package.json +1 -1
  49. package/dist/_contracts/proxy-protocol.d.ts +0 -305
  50. package/dist/_contracts/proxy-protocol.js +0 -297
  51. package/dist/_contracts/proxy-validation.d.ts +0 -19
  52. package/dist/_contracts/proxy-validation.js +0 -51
  53. package/dist/data-tools.d.ts +0 -82
  54. package/dist/data-tools.js +0 -251
  55. package/dist/data-tools.js.map +0 -1
  56. package/dist/proxy-endpoint.d.ts +0 -131
  57. package/dist/proxy-endpoint.js +0 -144
  58. package/dist/proxy-endpoint.js.map +0 -1
  59. package/examples/chat-corpus.ts +0 -84
@@ -4,142 +4,100 @@ title: Credentials
4
4
 
5
5
  # Credentials
6
6
 
7
- aex treats provider keys, MCP credentials, and proxy endpoint auth as per-run
8
- credentials. Reusable env secrets are documented separately in
9
- [Secrets](secrets.md).
7
+ aex uses explicit, per-session credentials:
10
8
 
11
- The caller passes a workspace-scoped SDK token and the provider key inline on every `openSession` / `run` call. aex holds the bundle in run-scoped custody for the session lifecycle and attempts terminal cleanup/revocation for the aex-controlled references. MCP credentials and proxy endpoint auth values travel the same way.
9
+ - `AEX_API_TOKEN` authenticates the SDK or CLI to aex.
10
+ - `apiKeys` carries BYOK provider keys for the model provider.
11
+ - `McpServer.remote(..., { headers })` carries MCP auth when a remote MCP server needs it.
12
+ - `environment.secrets` carries runtime secrets for your own code.
12
13
 
13
- A session selects one upstream `provider` (default `anthropic`) and must carry a BYOK
14
- key for it. Keys are supplied per-provider so a session can also hold keys for the
15
- **other** providers its subagents may use:
14
+ Secrets never belong in reusable run config, files, prompts, or examples.
16
15
 
17
- | Field | Required secret |
18
- | --- | --- |
19
- | Provider API keys | `apiKeys` (top-level, keyed by provider) |
16
+ ## Provider keys
17
+
18
+ A session selects one upstream provider and must carry a BYOK key for it. Include
19
+ additional provider keys only when subagents may use those providers.
20
20
 
21
21
  ```ts
22
- // The session's own provider key, plus extra keys its subagents can use.
23
- apiKeys: {
24
- anthropic: process.env.ANTHROPIC_API_KEY!, // the session's provider
25
- deepseek: process.env.DEEPSEEK_API_KEY! // for a cross-provider subagent
26
- }
22
+ const result = await aex.run({
23
+ model: Models.CLAUDE_HAIKU_4_5,
24
+ message: "Write a short report and save it as a file.",
25
+ apiKeys: {
26
+ anthropic: process.env.ANTHROPIC_API_KEY!
27
+ }
28
+ });
27
29
  ```
28
30
 
29
- A `subagent` spawned with a different-family model **inherits the parent's keys
30
- server-side** from the session's vaulted bundle — the keys never transit the
31
- container. If the parent holds no key for the child's provider, the child is
32
- rejected with `parent_missing_provider_key`.
33
-
34
- MCP credential types:
35
-
36
- - `static_bearer`;
37
- - `oauth_access_token`.
31
+ Provider keys are used by the managed runtime for model calls. They are not saved
32
+ as client defaults.
38
33
 
39
- Unsupported:
34
+ ## Runtime secrets
40
35
 
41
- - arbitrary headers;
42
- - OAuth refresh;
43
- - persisted aex vault.
44
-
45
- For managed-runtime runs, aex injects the matching BYOK provider key at the hosted provider-proxy. Provider-side sessions and data remain subject to the selected provider account's retention and deletion policies.
46
-
47
- ## Proxy endpoints (per-run custom HTTP credentials)
48
-
49
- Some skills need to call non-MCP HTTP services (e.g. Stripe, internal APIs). Embedding the credential in the skill content puts the raw secret on disk in the agent container and in the model's context — both prompt-injection-readable.
50
-
51
- The platform's managed HTTP proxy is the agent-first alternative. Declare each endpoint with a `ProxyEndpoint.*` constructor: the instance carries the non-secret **policy** (hashed for idempotency) and its **auth token** together at the call site. The SDK splits the token into the vaulted secrets channel server-side (not hashed, so key rotation does not collapse onto a stale run), and the raw credential value never enters the container.
36
+ Use `environment.secrets` for credentials your code needs at runtime. The value
37
+ can be ephemeral with `Secret.value(...)` or a workspace secret reference with
38
+ `Secret.ref(...)`.
52
39
 
53
40
  ```ts
54
- import { Aex, Models, ProxyEndpoint } from "@aexhq/sdk";
41
+ import { Aex, Models, Secret } from "@aexhq/sdk";
55
42
 
56
- const aex = new Aex({
57
- apiToken: "ant_..."
58
- });
59
-
60
- const stripe = ProxyEndpoint.bearer({
61
- name: "stripe",
62
- baseUrl: "https://api.stripe.com",
63
- token: process.env.STRIPE_API_KEY!,
64
- allowMethods: ["GET", "POST"],
65
- allowPathPrefixes: ["/v1/charges", "/v1/refunds"],
66
- maxRequestBytes: 65_536,
67
- maxResponseBytes: 65_536,
68
- timeoutMs: 10_000,
69
- responseMode: "headers_only",
70
- retry: {
71
- maxAttempts: 3,
72
- initialDelayMs: 250,
73
- maxDelayMs: 5000,
74
- jitter: "full",
75
- retryOnStatuses: [408, 425, 429, 500, 502, 503, 504],
76
- retryOnMethods: ["GET", "HEAD"],
77
- respectRetryAfter: true
78
- }
79
- });
43
+ const aex = new Aex({ apiToken: process.env.AEX_API_TOKEN! });
80
44
 
81
45
  await aex.run({
82
46
  model: Models.CLAUDE_HAIKU_4_5,
83
- message: "",
84
- proxyEndpoints: [stripe],
47
+ message: "Call https://api.example.com/v1/status with INTERNAL_API_TOKEN and summarize it.",
48
+ environment: {
49
+ secrets: {
50
+ INTERNAL_API_TOKEN: Secret.value(process.env.INTERNAL_API_TOKEN!)
51
+ },
52
+ networking: {
53
+ mode: "limited",
54
+ allowedHosts: ["api.example.com"]
55
+ }
56
+ },
85
57
  apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
86
58
  });
87
59
  ```
88
60
 
89
- The five constructors — `ProxyEndpoint.none` / `bearer` / `header` / `basic` / `query` — put the auth secret on the same call as the policy, so any drift (wrong `responseMode`, misnamed auth field) is a TypeScript error at the call site instead of an HTTP 400 a round-trip later.
90
-
91
- Inside the run container, every session has the platform CLI mounted at `/mnt/session/uploads/aex/aex` (a Bun-compatible ESM bundle) and a manifest at `/mnt/session/uploads/aex/index.json` describing the declared endpoints. The skill invokes the CLI through `bun` (the mount has no execute permission so direct invocation fails with `bad interpreter: Permission denied`):
61
+ Inside the run, use normal HTTP code for the service:
92
62
 
93
63
  ```bash
94
- bun /mnt/session/uploads/aex/aex proxy stripe \
95
- --method GET \
96
- --path /v1/charges/ch_123 \
97
- --response-mode headers_only
64
+ curl -sS \
65
+ -H "Authorization: Bearer $INTERNAL_API_TOKEN" \
66
+ https://api.example.com/v1/status
98
67
  ```
99
68
 
100
- The CLI reads the per-run bearer from `/mnt/session/uploads/aex/run-token`, attaches the `X-Aex-Proxy-Protocol` header, and the hosted proxy injects the bearer/header/query/basic credential before dispatching the outbound call. Only the response (subject to `responseMode` and `maxResponseBytes`) reaches the container. `--response-mode` can only narrow below the policy ceiling.
69
+ ## Workspace secrets
101
70
 
102
- Retries are declaration-based. Add `retry` to the endpoint policy when safe for that upstream; runs without `retry` keep single-attempt behavior. `maxAttempts` counts the initial request, and defaults apply only when `retry` is present: `maxAttempts: 3`, `initialDelayMs: 250`, `maxDelayMs: 5000`, `jitter: "full"`, `retryOnStatuses: [408, 425, 429, 500, 502, 503, 504]`, `retryOnMethods: ["GET", "HEAD"]`, and `respectRetryAfter: true`. There are no per-call `aex proxy` retry flags.
103
-
104
- #### Keyless upstreams (`authShape: { type: "none" }`)
105
-
106
- For public APIs that take no credential (Wikimedia Commons, Internet Archive, Library of Congress, NASA Images, NARA, GDELT, etc.), declare the endpoint with `ProxyEndpoint.none(...)` — it produces only a declaration, no auth token:
71
+ Store reusable values once, then reference them by name:
107
72
 
108
73
  ```ts
109
- import { ProxyEndpoint } from "@aexhq/sdk";
110
-
111
- const wikimedia = ProxyEndpoint.none({
112
- name: "wikimedia",
113
- baseUrl: "https://commons.wikimedia.org",
114
- allowMethods: ["GET"],
115
- allowPathPrefixes: ["/wiki/", "/w/api.php"]
74
+ await aex.secrets.set({
75
+ name: "internal-api-token",
76
+ value: process.env.INTERNAL_API_TOKEN!
116
77
  });
117
78
 
118
79
  await aex.run({
119
80
  model: Models.CLAUDE_HAIKU_4_5,
120
- message: "",
121
- proxyEndpoints: [wikimedia],
81
+ message: "Use INTERNAL_API_TOKEN for the status request.",
82
+ environment: {
83
+ secrets: {
84
+ INTERNAL_API_TOKEN: Secret.ref("internal-api-token")
85
+ }
86
+ },
122
87
  apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
123
88
  });
124
89
  ```
125
90
 
126
- The keyless endpoint still routes through the aex managed proxy: every call is allow-listed, audited, and redacted. The hosted proxy injects no `Authorization` header and no query-string credential.
91
+ Secret reads return metadata only; they never return the stored value.
127
92
 
128
- `bun /mnt/session/uploads/aex/aex --help` reads endpoint details from `/mnt/session/uploads/aex/index.json`. Runs that do not declare any `proxyEndpoints` still have the CLI and an empty manifest mounted, so agents never need to introspect whether the surface exists.
93
+ ## Networking
129
94
 
130
- ### Networking
131
-
132
- Networking is open by default. When a run explicitly uses `limited` networking,
133
- the platform host must appear in `allowed_hosts`. aex injects it
134
- automatically; for advance validation use:
135
-
136
- ```ts
137
- const allowedHosts = buildPlatformAllowedHosts({
138
- baseUrl: "https://api.aex.dev",
139
- extraHosts: ["api.stripe.com"]
140
- });
141
- ```
95
+ Networking is open by default. Use `environment.networking.mode: "limited"` with
96
+ `allowedHosts` when you want a run to reach only named public hosts. See
97
+ [Networking](networking.md).
142
98
 
143
- ### Secrets are always explicit at the call site
99
+ ## Explicit call-site rule
144
100
 
145
- There is no `defaultSecrets` and no client-held secret state. Every `openSession` / `run` call carries its own credentials at the call site: the top-level `apiKeys` map (one provider key, plus any subagent keys), MCP auth on each `McpServer` instance, and proxy auth on each `ProxyEndpoint` instance. This is the agent-first invariant: the credentials being used on any given call are visible in the same code that opens the session.
101
+ There is no `defaultSecrets` and no client-held secret state. Each
102
+ `openSession(...)` or `run(...)` call should show the provider keys, MCP auth, and
103
+ runtime secrets needed for that call.
package/docs/defaults.md CHANGED
@@ -39,14 +39,6 @@ For the hard ceilings and who can raise them, see
39
39
  | MCP connect timeout (register + initialize + discover) | 30 seconds | Per-port via `connectTimeoutMs`. | `RUN_DEFAULT_MCP_CONNECT_TIMEOUT_MS` |
40
40
  | MCP `tools/call` timeout | 30 minutes | Per-port via `callTimeoutMs`. | `RUN_DEFAULT_MCP_CALL_TIMEOUT_MS` |
41
41
 
42
- ## Proxy endpoints
43
-
44
- | Option | Default | How to override | Source |
45
- | --- | --- | --- | --- |
46
- | `maxRequestBytes` | 10 MiB | Per-endpoint via the endpoint's `maxRequestBytes`. | `REQUEST_PROXY_DEFAULT_MAX_REQUEST_BYTES` |
47
- | `maxResponseBytes` | `0` (unlimited — the response is streamed unbuffered) | Per-endpoint via the endpoint's `maxResponseBytes`. | `REQUEST_PROXY_DEFAULT_MAX_RESPONSE_BYTES` |
48
- | `timeoutMs` (upstream) | 5 minutes | Per-endpoint via the endpoint's `timeoutMs`. | `REQUEST_PROXY_DEFAULT_TIMEOUT_MS` |
49
-
50
42
  ## Links (signed URLs and tickets)
51
43
 
52
44
  | Option | Default | How to override | Source |
package/docs/events.md CHANGED
@@ -53,9 +53,9 @@ for the string:
53
53
  const lastText = (await session.messages().last())?.text;
54
54
  ```
55
55
 
56
- `decodeAssistantText`, `textOf`, and `summarizeRunTrace` remain exported as the
57
- power-user escape hatch over a raw `RunEvent` list, but "get the last message"
58
- is now `await session.messages().last()`.
56
+ Prefer `session.messages().list()` or the collected `result.messages` /
57
+ `result.text` fields for assistant text. Low-level event helpers remain exported
58
+ for callers that build custom collectors.
59
59
 
60
60
  The CLI mirrors the same surface:
61
61
 
@@ -162,7 +162,7 @@ const jsonl = await response.text();
162
162
 
163
163
  ## Event shape
164
164
 
165
- Events are typed as the discriminated `RunEvent` union for compatibility and as the versioned coordinator envelope for live consumers. aex records raw runtime/provider payloads **after** secret redaction and structural sanitization, so the bytes you see never contain the provider key, MCP credentials, or proxy bearer that were supplied when the session was opened.
165
+ Events are typed as the discriminated `RunEvent` union for compatibility and as the versioned coordinator envelope for live consumers. aex records raw runtime/provider payloads **after** secret redaction and structural sanitization, so the bytes you see never contain provider keys, MCP credentials, or runtime secrets supplied when the session was opened.
166
166
 
167
167
  ## Typed helpers
168
168
 
@@ -180,8 +180,7 @@ import {
180
180
  isToolCallResult,
181
181
  isCustom,
182
182
  isLog,
183
- isEventChannel,
184
- textOf
183
+ isEventChannel
185
184
  } from "@aexhq/sdk";
186
185
  ```
187
186
 
@@ -191,6 +190,6 @@ All guards test the `type` discriminant at runtime. `isTextMessage`,
191
190
  `event.data` to the fields that event type carries — e.g. inside
192
191
  `if (isTextMessage(e))`, `e.data.text` is typed `string`. The lifecycle/channel
193
192
  guards (`isRunStarted`, `isRunError`, `isCustom`, `isLog`, …) operate on the
194
- coordinator envelope and narrow only the discriminant. `textOf(events)` returns
195
- the run's final assistant text concatenated from the `TEXT_MESSAGE_CONTENT`
196
- blocks.
193
+ coordinator envelope and narrow only the discriminant. Use `result.text` or
194
+ `session.messages.all()` when you need assistant text without inspecting the
195
+ event stream directly.
@@ -96,12 +96,9 @@ Default values; each is overridable per-plane via the matching
96
96
  | API token create | 10 | Workspace default | `WORKSPACE_RATE_LIMIT_DEFAULTS` |
97
97
  | API token delete | 30 | Workspace default | `WORKSPACE_RATE_LIMIT_DEFAULTS` |
98
98
 
99
- ## Request scope (proxy and egress)
99
+ ## Request Scope
100
100
 
101
101
  | Limit | Value | Source | Raisable? | Constant |
102
102
  | --- | --- | --- | --- | --- |
103
- | Proxy request body | 10 MiB | aex policy | Per-endpoint via `maxRequestBytes` | `REQUEST_PROXY_DEFAULT_MAX_REQUEST_BYTES` |
104
- | Proxy response body | `0` = unlimited (streamed unbuffered) | aex policy | Per-endpoint via `maxResponseBytes` | `REQUEST_PROXY_DEFAULT_MAX_RESPONSE_BYTES` |
105
- | Proxy upstream timeout | 5 minutes | aex policy | Per-endpoint via `timeoutMs` | `REQUEST_PROXY_DEFAULT_TIMEOUT_MS` |
106
103
  | Signed output URL TTL | 300 seconds | aex policy | Per-call via `expiresSeconds` | `REQUEST_PRESIGN_URL_DEFAULT_TTL_SECONDS` |
107
104
  | Event-stream connection ticket TTL | 60 seconds | aex policy | Per-mint via `ttlMs` | `REQUEST_TICKET_DEFAULT_TTL_MS` |
package/docs/limits.md CHANGED
@@ -17,9 +17,6 @@ For the current provider/model set, see the generated
17
17
  | Area | Default |
18
18
  | --- | --- |
19
19
  | Workspace storage | 50 GiB per workspace for captured outputs and workspace artifacts. aex-maintainer admin workspaces may be unlimited for internal dogfooding; this is not a customer entitlement. |
20
- | Proxy request body | 10 MiB per proxy endpoint unless the endpoint declares a different `maxRequestBytes`. |
21
- | Proxy timeout | 5 minutes per proxy endpoint unless the endpoint declares a different `timeoutMs`. |
22
- | Proxy telemetry | Proxy calls emit report-only usage telemetry for call count, failed calls, request bytes, response bytes when known, and duration. Public proxy pricing is not shipped unless documented later. |
23
20
 
24
21
  ## Product Boundaries
25
22
 
@@ -27,14 +24,13 @@ For the current provider/model set, see the generated
27
24
  | --- | --- |
28
25
  | Runtime | New submissions run on the managed runtime. There is no public runtime selector. |
29
26
  | Provider policy | Provider retention, training exclusion, HIPAA/BAA, data residency, abuse policy, and pricing belong to the selected provider account, endpoint, and contract. |
30
- | Secrets | Provider keys, MCP credentials, proxy auth, and env secrets are caller-owned. aex excludes secret values from idempotency and uses the explicit secret surfaces described in [Secrets](secrets.md). |
27
+ | Secrets | Provider keys, MCP credentials, and env secrets are caller-owned. aex excludes secret values from idempotency and uses the explicit secret surfaces described in [Secrets](secrets.md). |
31
28
  | MCP servers | Remote MCP servers are customer-trusted systems. aex validates declarations and routes credentials; it does not make an untrusted MCP server safe. |
32
- | Proxy endpoints | The proxy enforces declared host/path/method/auth policy for calls routed through it. Upstream side effects and data handling remain with the upstream service and customer. |
33
29
  | Outputs | Captured outputs, events, and metadata are stored under the run record and downloaded through auth-gated routes. Output content is customer content. |
34
30
  | Human review | Runs execute after submission. Cancellation is available, but aex does not pause a run for platform-mediated approval or interactive clarification. |
35
31
  | Sessions | The durable product primitive is the session/run record. Sessions can be resumed by id and auto-suspend after the configured idle window; persistent named agent profiles and saved agent definitions are out of scope. |
36
32
  | Deployment | The supported product is the hosted aex service plus the SDK and CLI. Alternate `baseUrl` values are for local, staging, or hosted aex API planes, not a self-host product promise. |
37
- | Cost | BYOK provider-token charges accrue to the customer's provider account. aex records report-only telemetry for runtime, storage, and proxy usage; free trials, billing-grade invoices, and public pricing documents are not shipped unless documented later. |
33
+ | Cost | BYOK provider-token charges accrue to the customer's provider account. aex records report-only telemetry for runtime and storage usage; free trials, billing-grade invoices, and public pricing documents are not shipped unless documented later. |
38
34
 
39
35
  ## Provider Policy Links
40
36
 
package/docs/mcp.md CHANGED
@@ -25,14 +25,13 @@ server, so we cannot elide MCP responses or write them to the session
25
25
  filesystem on the user's behalf. Anything an MCP tool returns lands
26
26
  directly in the model's context.
27
27
 
28
- For ingestion-style tools that return large JSON blobs (search results,
29
- catalogue dumps, bulk reads), use the **CLI-as-skill + managed proxy**
30
- pattern instead of MCP:
28
+ For ingestion-style MCP servers that return large JSON blobs (search results,
29
+ catalogue dumps, bulk reads), prefer a skill that writes files instead of
30
+ putting the whole response in model context:
31
31
 
32
32
  1. Package the upstream as a skill-tool (`Tools.fromSkillDir` /
33
33
  `Tools.fromSkillUrl`) — a CLI binary the agent invokes with its bash tool.
34
- 2. Route every upstream HTTPS call through a per-run `ProxyEndpoint`
35
- (audit, byte caps, budget enforcement).
34
+ 2. Keep any upstream HTTPS credentials in `environment.secrets`.
36
35
  3. Have the CLI write the full payload to the session filesystem. By default,
37
36
  files it creates or modifies are captured automatically; pass
38
37
  `outputs.allowedDirs` only when you want to narrow capture to specific roots.
@@ -26,7 +26,6 @@ These reach the network over managed paths and are **not** subject to
26
26
  - The model / provider call for the run (and its subagents).
27
27
  - The built-in `web_search` and `web_fetch` tools (still SSRF-guarded).
28
28
  - Any remote MCP servers you declare in `mcpServers` — see [MCP](mcp.md).
29
- - Any `proxyEndpoints` you declare — see [Credentials](credentials.md).
30
29
  - The package registries for any `environment.packages` you declare (pip → PyPI,
31
30
  apt → the distribution mirrors). Declaring a package implicitly allows the
32
31
  registry it installs from.
@@ -70,17 +69,8 @@ non-default port when you need one (`api.example.com:8443`); a bare host name
70
69
  covers HTTPS on 443. Matching is exact per host — it is not a wildcard or suffix
71
70
  match, so list each host you need.
72
71
 
73
- To validate your allowlist before submitting, `buildPlatformAllowedHosts` returns
74
- the host set the platform will enforce given a base URL plus your extra hosts:
75
-
76
- ```ts
77
- import { buildPlatformAllowedHosts } from "@aexhq/sdk";
78
-
79
- const allowedHosts = buildPlatformAllowedHosts({
80
- baseUrl: "https://api.aex.dev",
81
- extraHosts: ["api.example.com"]
82
- });
83
- ```
72
+ Keep the allowlist in your session options so the submitted network policy is
73
+ visible at the same call site as the code that needs it.
84
74
 
85
75
  ## Open mode
86
76
 
@@ -135,7 +125,7 @@ your client succeeds without extra setup.
135
125
  - **`allowedHosts` only applies in `limited` mode.** It is ignored in `open`
136
126
  mode, where the SSRF deny-list is the only gate.
137
127
 
138
- For routing credentialed HTTP calls through the managed proxy without putting the
139
- secret in the container, use proxy endpoints see
140
- [Credentials](credentials.md). For remote tool servers, see [MCP](mcp.md). For
141
- the full set of run-config fields, see [Run configuration](run-config.md).
128
+ For credentialed HTTP calls, pass the credential as an `environment.secrets`
129
+ entry and let your code use its normal HTTP client. For remote tool servers, see
130
+ [MCP](mcp.md). For the full set of run-config fields, see
131
+ [Run configuration](run-config.md).
package/docs/outputs.md CHANGED
@@ -100,10 +100,6 @@ if (truncated) {
100
100
 
101
101
  Check `truncated` before treating `text` as complete. Pass `options.grep` (a substring or `RegExp`) to keep only matching lines of the capped text. The returned `output` is the matched `Output` record, and `totalBytes` is the file's full size when the server reports it.
102
102
 
103
- ### Chatting over a workspace's outputs
104
-
105
- `createDataTools(client)` packages the read surface (`sessions.list` + `sessions.outputs(id).list` + `sessions.outputs(id).read`) as a vendor-neutral LLM tool set (`{ tools, instructions, execute }`) so you can build a search-then-fetch chat over your sessions and their outputs in a few lines on top of the public SDK. The `tools` are plain JSON-Schema definitions (the shape every major LLM tool API accepts); `execute(name, input)` dispatches a tool call against the workspace-scoped client. See the runnable `examples/data-chat/` example.
106
-
107
103
  ## Finding outputs
108
104
 
109
105
  `session.outputs().list(query?)` can filter the captured output list client-side. Use `session.outputs().find(query)` when you want discovery to be explicit, or `session.outputs().findOne(query)` when exactly one file is expected:
@@ -2,7 +2,7 @@
2
2
  "brand": "aex",
3
3
  "productName": "Agent Executor",
4
4
  "oneLine": "aex is an agent execution platform for launching autonomous agents from a simple TypeScript SDK and CLI.",
5
- "description": "Open durable agent sessions, send turns, stream events, capture outputs, and compose agents with skills, files, MCP, proxy endpoints, and subagents across the managed runtime.",
5
+ "description": "Open durable agent sessions, send turns, stream events, capture outputs, and compose agents with skills, files, MCP, secrets, networking controls, and subagents across the managed runtime.",
6
6
  "alpha": {
7
7
  "label": "Alpha testing",
8
8
  "description": "Access is limited to invited testers while we harden the hosted runtime, dashboard, and SDK workflows."
@@ -61,7 +61,7 @@
61
61
  "slug": "agent-composition",
62
62
  "href": "/docs/features/#agent-composition",
63
63
  "title": "Agent composition",
64
- "description": "Skills, files, AGENTS.md, remote MCP servers, proxy endpoints, environment variables, packages, and networking controls."
64
+ "description": "Skills, files, AGENTS.md, remote MCP servers, environment variables, packages, secrets, and networking controls."
65
65
  },
66
66
  {
67
67
  "slug": "subagents",
@@ -79,7 +79,7 @@
79
79
  "slug": "typed-control-surface",
80
80
  "href": "/docs/features/#typed-control-surface",
81
81
  "title": "Typed control surface",
82
- "description": "Strongly typed SDK inputs, CLI parity, BYOK secrets, scoped proxy auth, redaction, and output modes."
82
+ "description": "Strongly typed SDK inputs, CLI parity, BYOK provider keys, workspace secrets, redaction, and output modes."
83
83
  }
84
84
  ]
85
85
  }
@@ -83,11 +83,8 @@ for await (const event of turn) {
83
83
  }
84
84
  await turn.done();
85
85
 
86
- // Reads/streams/downloads are grouped into accessor sub-resources:
87
- // session.messages() / events() / outputs() / webhooks(). Grab the last
88
- // assistant message (an AssistantTextEntry; use ?.text for the string).
89
- const lastText = (await session.messages().last())?.text;
90
- console.log(lastText);
86
+ const messages = await session.messages().list();
87
+ console.log(messages.at(-1)?.text);
91
88
 
92
89
  // Poll the record until the session parks (idle / suspended / error).
93
90
  const record = await session.wait();
@@ -110,8 +107,7 @@ aex run \
110
107
 
111
108
  ## Add capabilities
112
109
 
113
- - Add files, skills, AGENTS.md, MCP servers, proxy endpoints, packages, and networking controls with [Composition](concepts/composition.md).
114
- - Inspect runtime tools with [Agent tools](concepts/agent-tools.md).
110
+ - Add files, skills, AGENTS.md, MCP servers, packages, and networking controls with [Composition](concepts/composition.md).
115
111
  - Use parent/child run delegation from the [Features](https://aex.dev/docs/features/#subagents) page.
116
112
  - Narrow output capture or download individual files with [Outputs](outputs.md).
117
113
  - Check supported providers and models in the [provider/runtime capability matrix](provider-runtime-capabilities.md).
@@ -13,13 +13,16 @@ Allowed fields:
13
13
  - `mcpServers` - array of `McpServerRef`; headers are split into the vaulted secrets channel server-side.
14
14
  - `environment` - `{ networking?, packages?, variables? }`. Networking is open by default; set `networking.mode` to `limited` only when you want an allowlist. `variables` are merged into the in-container `RUNTIME.env` / `RUNTIME.json` mounts. (Run secrets go in `environment.secrets`, which carries live `Secret` instances and is not part of a shareable config.)
15
15
  - `runtime` - optional managed-runtime preset. Prefer `Sizes` in TypeScript.
16
- - `proxyEndpoints` - array of `ProxyEndpoint` instances; endpoint-level `retry` is allowed here and remains declaration-based.
17
16
  - `metadata` - non-secret structured metadata.
18
17
  - `overrides` - `{ idleTtl?, timeout?, maxSpendUsd? }`. `timeout` is an optional session deadline (e.g. `"30m"`, `"2h"`); `maxSpendUsd` stops the session once its spend would exceed the cap (see [Limits & quotas](limits-and-quotas.md)).
19
18
 
20
19
  `message` (the one-shot `run` input), `agentsMd`, `files`, `outputs`, `tools`, `includeBuiltinTools`, and `outputMode` are `openSession` / `run` options, not reusable run-config fields. They carry the turn input, bytes, capture behavior, or agent tool/output controls that belong on a concrete call. Skill bundles are `tools` entries built with `Tools.fromSkillDir(...)` / `Tools.fromSkillUrl(...)`, so they too are SDK-code options rather than config fields. Subagents run in-process; there is no `limits` / `parentRunId` option.
21
20
 
22
- Secrets never live in run config. Pass provider keys through the top-level `apiKeys` map (and run secrets through `environment.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.
21
+ Secrets never live in run config. Pass provider keys through the top-level
22
+ `apiKeys` map and runtime secrets through `environment.secrets` in the SDK, or
23
+ the equivalent host-mode flags (`--anthropic-api-key`, `--mcp-auth`) in the CLI.
24
+ See [Secrets](secrets.md) for secret lifecycles and [Credentials](credentials.md)
25
+ for credential handling.
23
26
 
24
27
  ## Reuse in code
25
28
 
@@ -52,4 +55,4 @@ aex run --config ./run.json \
52
55
  --anthropic-api-key "$ANTHROPIC_API_KEY"
53
56
  ```
54
57
 
55
- ...or as explicit flags (`--model`, `--system`, `--prompt`, `--mcp`, `--mcp-auth`, `--runtime-size`, `--run-timeout`, `--proxy-endpoint`, `--proxy-auth`, `--metadata`). The two modes are mutually exclusive.
58
+ ...or as explicit flags (`--model`, `--system`, `--prompt`, `--mcp`, `--mcp-auth`, `--runtime-size`, `--run-timeout`, `--metadata`). The two modes are mutually exclusive.
package/docs/secrets.md CHANGED
@@ -111,5 +111,5 @@ await aex.run({
111
111
  await aex.secrets.delete("serper-api-key");
112
112
  ```
113
113
 
114
- The CLI supports per-run provider, MCP, and proxy credentials. Workspace secret
114
+ The CLI supports per-run provider and MCP credentials. Workspace secret
115
115
  administration is exposed through the SDK.
package/docs/skills.md CHANGED
@@ -72,9 +72,9 @@ files into the workspace under `/workspace/skills/<name>/`. So the `SKILL.md` bo
72
72
  and every supporting file are on disk from the first turn; the load-tool call is
73
73
  how that body enters the model's context, not how the files get written.
74
74
 
75
- The platform also mounts the `aex` CLI and a per-run manifest into every run.
76
- Skills call managed HTTP proxy endpoints through the mounted CLI
77
- (`aex proxy ...`); see [Credentials](credentials.md) for the policy and auth model.
75
+ Skills that call external HTTP APIs should read credentials from
76
+ `environment.secrets` and use the normal client for that service. See
77
+ [Credentials](credentials.md) for the secret model.
78
78
 
79
79
  Run-scoped asset copies are part of the run record and are removed by run deletion
80
80
  or retention cleanup.