@aexhq/sdk 0.29.0 → 0.30.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.
- package/README.md +79 -6
- package/dist/_contracts/event-guards.d.ts +67 -0
- package/dist/_contracts/event-guards.js +36 -0
- package/dist/_contracts/index.d.ts +2 -0
- package/dist/_contracts/index.js +6 -0
- package/dist/_contracts/run-trace.d.ts +7 -0
- package/dist/_contracts/run-trace.js +9 -0
- package/dist/_contracts/runtime-types.d.ts +31 -0
- package/dist/_contracts/submission.d.ts +16 -2
- package/dist/_contracts/submission.js +23 -5
- package/dist/agents-md.d.ts +4 -1
- package/dist/agents-md.js +10 -9
- package/dist/agents-md.js.map +1 -1
- package/dist/cli.mjs +17785 -3914
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +91 -12
- package/dist/client.js +236 -77
- package/dist/client.js.map +1 -1
- package/dist/data-tools.d.ts +23 -0
- package/dist/data-tools.js +102 -13
- package/dist/data-tools.js.map +1 -1
- package/dist/file.d.ts +4 -1
- package/dist/file.js +10 -9
- package/dist/file.js.map +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/skill.d.ts +8 -6
- package/dist/skill.js +14 -14
- package/dist/skill.js.map +1 -1
- package/dist/tool.d.ts +4 -1
- package/dist/tool.js +10 -8
- package/dist/tool.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/concepts/agent-tools.md +7 -3
- package/docs/events.md +32 -9
- package/docs/networking.md +141 -0
- package/docs/quickstart.md +19 -10
- package/examples/chat-corpus.ts +85 -0
- package/package.json +2 -2
package/dist/skill.js
CHANGED
|
@@ -25,7 +25,8 @@ import { readDirectoryAsFiles } from "./node-fs.js";
|
|
|
25
25
|
export class Skill {
|
|
26
26
|
#ref;
|
|
27
27
|
#inlineBytes;
|
|
28
|
-
|
|
28
|
+
/** Asset id cached after the first submit, so reuse skips a re-upload. */
|
|
29
|
+
#assetId;
|
|
29
30
|
/**
|
|
30
31
|
* Internal constructor. Use `Skill.fromFiles` or `Skill.fromPath` to create
|
|
31
32
|
* instances.
|
|
@@ -45,10 +46,15 @@ export class Skill {
|
|
|
45
46
|
}
|
|
46
47
|
/** True for local-bytes Skills that haven't been uploaded yet. */
|
|
47
48
|
get isDraft() {
|
|
48
|
-
return this.#ref.kind === "draft"
|
|
49
|
+
return this.#ref.kind === "draft";
|
|
49
50
|
}
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
/** Internal: the asset id resolved on a prior submit, or undefined. */
|
|
52
|
+
get _cachedAssetId() {
|
|
53
|
+
return this.#assetId;
|
|
54
|
+
}
|
|
55
|
+
/** Internal: remember the asset id resolved for this draft's bytes. */
|
|
56
|
+
_rememberAsset(assetId) {
|
|
57
|
+
this.#assetId = assetId;
|
|
52
58
|
}
|
|
53
59
|
/**
|
|
54
60
|
* Build a draft Skill from an inline files map. The SDK validates
|
|
@@ -141,23 +147,17 @@ export class Skill {
|
|
|
141
147
|
return new Skill(ref);
|
|
142
148
|
}
|
|
143
149
|
/**
|
|
144
|
-
* Internal: yield the draft's bytes + metadata so `client.submit`
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
* supported retry pattern).
|
|
150
|
+
* Internal: yield the draft's bytes + metadata so `client.submit` can upload
|
|
151
|
+
* the asset. Idempotent (non-consuming): a Skill is reusable across submits —
|
|
152
|
+
* the first submit caches the resolved asset id (see `_rememberAsset`) so
|
|
153
|
+
* later submits reuse it instead of re-uploading.
|
|
149
154
|
*
|
|
150
155
|
* Returns undefined for already-materialized Skills.
|
|
151
156
|
*/
|
|
152
157
|
_takeDraftBundle() {
|
|
153
|
-
if (this.#consumed) {
|
|
154
|
-
throw new Error("Skill: cannot reuse a consumed Skill in submit. Build a fresh Skill via " +
|
|
155
|
-
"Skill.fromPath(...) / Skill.fromFiles(...) per submit call.");
|
|
156
|
-
}
|
|
157
158
|
if (this.#ref.kind !== "draft" || !this.#inlineBytes) {
|
|
158
159
|
return undefined;
|
|
159
160
|
}
|
|
160
|
-
this.#consumed = true;
|
|
161
161
|
return {
|
|
162
162
|
name: this.#ref.name,
|
|
163
163
|
contentHash: this.#ref.contentHash,
|
package/dist/skill.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAInB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAmB,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,KAAK;IACP,IAAI,CAA2B;IAC/B,YAAY,CAAyB;IAC9C,
|
|
1
|
+
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"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"}
|
package/dist/tool.d.ts
CHANGED
|
@@ -12,7 +12,10 @@ export declare class Tool {
|
|
|
12
12
|
private constructor();
|
|
13
13
|
get ref(): ToolRef | DraftToolRef;
|
|
14
14
|
get isDraft(): boolean;
|
|
15
|
-
|
|
15
|
+
/** Internal: the asset id resolved on a prior submit, or undefined. */
|
|
16
|
+
get _cachedAssetId(): string | undefined;
|
|
17
|
+
/** Internal: remember the asset id resolved for this draft's bytes. */
|
|
18
|
+
_rememberAsset(assetId: string): void;
|
|
16
19
|
static fromFiles(args: ToolManifestInput & {
|
|
17
20
|
readonly files: SkillFiles;
|
|
18
21
|
}): Promise<Tool>;
|
package/dist/tool.js
CHANGED
|
@@ -4,7 +4,8 @@ import { readDirectoryAsFiles } from "./node-fs.js";
|
|
|
4
4
|
export class Tool {
|
|
5
5
|
#ref;
|
|
6
6
|
#inlineBytes;
|
|
7
|
-
|
|
7
|
+
/** Asset id cached after the first submit, so reuse skips a re-upload. */
|
|
8
|
+
#assetId;
|
|
8
9
|
constructor(ref, inlineBytes) {
|
|
9
10
|
this.#ref = ref;
|
|
10
11
|
this.#inlineBytes = inlineBytes;
|
|
@@ -13,10 +14,15 @@ export class Tool {
|
|
|
13
14
|
return this.#ref;
|
|
14
15
|
}
|
|
15
16
|
get isDraft() {
|
|
16
|
-
return this.#ref.kind === "draft"
|
|
17
|
+
return this.#ref.kind === "draft";
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
/** Internal: the asset id resolved on a prior submit, or undefined. */
|
|
20
|
+
get _cachedAssetId() {
|
|
21
|
+
return this.#assetId;
|
|
22
|
+
}
|
|
23
|
+
/** Internal: remember the asset id resolved for this draft's bytes. */
|
|
24
|
+
_rememberAsset(assetId) {
|
|
25
|
+
this.#assetId = assetId;
|
|
20
26
|
}
|
|
21
27
|
static async fromFiles(args) {
|
|
22
28
|
if (!args || typeof args !== "object") {
|
|
@@ -60,13 +66,9 @@ export class Tool {
|
|
|
60
66
|
return new Tool(normalizeToolRef("Tool.fromAsset", ref));
|
|
61
67
|
}
|
|
62
68
|
_takeDraftBundle() {
|
|
63
|
-
if (this.#consumed) {
|
|
64
|
-
throw new Error("Tool: cannot reuse a consumed Tool in submit. Build a fresh Tool via Tool.fromPath(...) / Tool.fromFiles(...) per submit call.");
|
|
65
|
-
}
|
|
66
69
|
if (this.#ref.kind !== "draft" || !this.#inlineBytes) {
|
|
67
70
|
return undefined;
|
|
68
71
|
}
|
|
69
|
-
this.#consumed = true;
|
|
70
72
|
const { kind: _kind, contentHash, ...ref } = this.#ref;
|
|
71
73
|
return {
|
|
72
74
|
ref: { kind: "asset", ...ref },
|
package/dist/tool.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EAIzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,eAAe,EACf,eAAe,EAGhB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAUpD,MAAM,OAAO,IAAI;IACN,IAAI,CAAyB;IAC7B,YAAY,CAAyB;IAC9C,
|
|
1
|
+
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -51,9 +51,13 @@ await aex.submit({
|
|
|
51
51
|
});
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
Networking is open by default
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
Networking is open by default: the agent may reach any public host, subject to a
|
|
55
|
+
fixed SSRF deny-list. `web_fetch` and `web_search` reach the network over a
|
|
56
|
+
managed, SSRF-guarded path that is **not** governed by `environment.networking`,
|
|
57
|
+
so their hosts never need to be listed in a `limited` allowlist. Setting
|
|
58
|
+
`environment.networking.mode` to `limited` restricts only the agent's own
|
|
59
|
+
arbitrary egress (e.g. a `curl` in `bash`); the built-in web tools keep working.
|
|
60
|
+
See [Networking](../networking.md).
|
|
57
61
|
|
|
58
62
|
## Disable builtins
|
|
59
63
|
|
package/docs/events.md
CHANGED
|
@@ -36,11 +36,23 @@ for await (const event of aex.streamEnvelopes(runId, { from: 0 })) {
|
|
|
36
36
|
The CLI mirrors the same surface:
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
aex events
|
|
40
|
-
aex events
|
|
41
|
-
aex
|
|
39
|
+
aex events <run-id> --api-token … [--aex-url …] # snapshot (polling)
|
|
40
|
+
aex events <run-id> --follow [--timeout 8m] --api-token … [--aex-url …] # stream until terminal (polling)
|
|
41
|
+
aex tail <run-id> [--json] [--filter <type|source>] [--logs] [--settle] [--timeout 8m] --api-token … # live, human-readable, over the WS envelope stream
|
|
42
|
+
aex inspect <run-id> [--json] [--filter <type|source>] [--logs] [--timeout 8m] --api-token … # one-shot full timeline + jump-to-failure + cost/usage
|
|
43
|
+
aex wait <run-id> [--timeout 8m] [--interval 2s] --api-token … # block, print final run
|
|
42
44
|
```
|
|
43
45
|
|
|
46
|
+
`aex tail` and `aex inspect` consume the same coordinator WebSocket envelope
|
|
47
|
+
stream as `streamEnvelopes()` (replay-from-cursor + tail + exactly-once resume),
|
|
48
|
+
so they are the low-latency equivalents of `events --follow`'s polling. `--json`
|
|
49
|
+
is the raw-NDJSON escape hatch; `--filter` keeps only the named AG-UI types
|
|
50
|
+
(`TEXT_MESSAGE_CONTENT`, `TOOL_CALL_START`, …) or sources (`agent`/`runtime`/…);
|
|
51
|
+
a `RUN_ERROR` is surfaced as a jump-to-failure line. `aex inspect` adds a header,
|
|
52
|
+
a settle-consistent full timeline, and a cost/usage footer. Both exit `0`
|
|
53
|
+
succeeded / `1` other terminal / `3` timeout. They need a global `WebSocket`
|
|
54
|
+
(Bun or Node ≥ 22).
|
|
55
|
+
|
|
44
56
|
`aex wait` is the host mirror of `aex.wait(runId)` / `aex.waitForRun(runId)`:
|
|
45
57
|
it polls until the run reaches a terminal status and prints the final `Run`
|
|
46
58
|
record. Exit `0` when the run `succeeded`, `1` for any other terminal status,
|
|
@@ -69,9 +81,11 @@ Two facts make this easy to work with:
|
|
|
69
81
|
consistently, don't key off the terminal event — use one of:
|
|
70
82
|
|
|
71
83
|
```ts
|
|
72
|
-
// Blocking:
|
|
73
|
-
|
|
74
|
-
|
|
84
|
+
// Blocking: submit + wait + collect. Resolves once the RECORD is terminal
|
|
85
|
+
// (polls getRun, not the event) and returns a settle-consistent RunResult
|
|
86
|
+
// (status, ok, text, events, trace, outputs, costUsd).
|
|
87
|
+
const result = await aex.run(runConfig);
|
|
88
|
+
const sameRun = await aex.waitForRun(runId); // or wait on an already-submitted run for the bare Run record
|
|
75
89
|
```
|
|
76
90
|
|
|
77
91
|
```ts
|
|
@@ -112,7 +126,7 @@ terminal event is `RUN_ERROR` with `data.reason: "failed"` and
|
|
|
112
126
|
|
|
113
127
|
## Typed helpers
|
|
114
128
|
|
|
115
|
-
The package exports conservative type guards
|
|
129
|
+
The package exports conservative type guards over run events:
|
|
116
130
|
|
|
117
131
|
```ts
|
|
118
132
|
import {
|
|
@@ -126,8 +140,17 @@ import {
|
|
|
126
140
|
isToolCallResult,
|
|
127
141
|
isCustom,
|
|
128
142
|
isLog,
|
|
129
|
-
isEventChannel
|
|
143
|
+
isEventChannel,
|
|
144
|
+
textOf
|
|
130
145
|
} from "@aexhq/sdk";
|
|
131
146
|
```
|
|
132
147
|
|
|
133
|
-
|
|
148
|
+
All guards test the `type` discriminant at runtime. `isTextMessage`,
|
|
149
|
+
`isToolCallStart`, `isToolCallResult`, and `isRunFinished` operate on the loose
|
|
150
|
+
`RunEvent` snapshot (`listEvents` / `RunResult.events`) and additionally NARROW
|
|
151
|
+
`event.data` to the fields that event type carries — e.g. inside
|
|
152
|
+
`if (isTextMessage(e))`, `e.data.text` is typed `string`. The lifecycle/channel
|
|
153
|
+
guards (`isRunStarted`, `isRunError`, `isCustom`, `isLog`, …) operate on the
|
|
154
|
+
coordinator envelope and narrow only the discriminant. `textOf(events)` returns
|
|
155
|
+
the run's final assistant text concatenated from the `TEXT_MESSAGE_CONTENT`
|
|
156
|
+
blocks.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Networking
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Networking
|
|
6
|
+
|
|
7
|
+
A run executes your agent's code in a sandbox that has **no unmediated route to
|
|
8
|
+
the internet**. Every outbound connection — whether it comes from the model, a
|
|
9
|
+
built-in tool, or a `curl` your code runs in the shell — passes through the
|
|
10
|
+
platform's egress boundary, which enforces the run's networking policy and a
|
|
11
|
+
fixed SSRF deny-list (loopback, link-local, cloud-metadata, and other private
|
|
12
|
+
ranges are always blocked, including hostnames that resolve to those ranges).
|
|
13
|
+
|
|
14
|
+
**Networking is open by default.** A run that does not set
|
|
15
|
+
`environment.networking` may reach any public host — still subject to the SSRF
|
|
16
|
+
deny-list above — with no allowlist required. You use the `environment.networking`
|
|
17
|
+
field to *narrow* that surface when you want a tighter, auditable egress posture.
|
|
18
|
+
Code cannot widen the policy from inside the container: the boundary is the
|
|
19
|
+
platform's, not the agent's.
|
|
20
|
+
|
|
21
|
+
## Paths that always work
|
|
22
|
+
|
|
23
|
+
These reach the network over managed paths and are **not** subject to
|
|
24
|
+
`environment.networking`, so you never list their hosts:
|
|
25
|
+
|
|
26
|
+
- The model / provider call for the run (and its subagents).
|
|
27
|
+
- The built-in `web_search` and `web_fetch` tools (still SSRF-guarded).
|
|
28
|
+
- Any remote MCP servers you declare in `mcpServers` — see [MCP](mcp.md).
|
|
29
|
+
- Any `proxyEndpoints` you declare — see [Credentials](credentials.md).
|
|
30
|
+
- The package registries for any `environment.packages` you declare (pip → PyPI,
|
|
31
|
+
apt → the distribution mirrors). Declaring a package implicitly allows the
|
|
32
|
+
registry it installs from.
|
|
33
|
+
|
|
34
|
+
`environment.networking` governs the **other** case: arbitrary outbound that
|
|
35
|
+
your own code makes to a host the platform doesn't already manage — a `curl` in
|
|
36
|
+
the `bash` tool, a `requests`/`urllib` call in Python, a `fetch` in
|
|
37
|
+
`code_execution`, or a third-party SDK.
|
|
38
|
+
|
|
39
|
+
## Restrict a run to an allowlist
|
|
40
|
+
|
|
41
|
+
Set `mode: "limited"` and list exactly the hosts your code is allowed to reach.
|
|
42
|
+
Anything not on the list (and not one of the always-allowed paths above) is
|
|
43
|
+
blocked, and the call fails. The platform automatically appends the
|
|
44
|
+
infrastructure hosts aex itself needs, so the model and tool paths keep working
|
|
45
|
+
without you listing them.
|
|
46
|
+
|
|
47
|
+
### TypeScript
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { AgentExecutor, Models, Providers } from "@aexhq/sdk";
|
|
51
|
+
|
|
52
|
+
const aex = new AgentExecutor({ apiToken: process.env.AEX_API_TOKEN! });
|
|
53
|
+
|
|
54
|
+
await aex.submit({
|
|
55
|
+
provider: Providers.ANTHROPIC,
|
|
56
|
+
model: Models.CLAUDE_HAIKU_4_5,
|
|
57
|
+
prompt: "Fetch the public status page and summarize it.",
|
|
58
|
+
environment: {
|
|
59
|
+
networking: {
|
|
60
|
+
mode: "limited",
|
|
61
|
+
allowedHosts: ["api.example.com", "status.example.com"]
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
secrets: { apiKey: process.env.ANTHROPIC_API_KEY! }
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`allowedHosts` entries are host names (lowercased), e.g. `api.example.com`. Add a
|
|
69
|
+
non-default port when you need one (`api.example.com:8443`); a bare host name
|
|
70
|
+
covers HTTPS on 443. Matching is exact per host — it is not a wildcard or suffix
|
|
71
|
+
match, so list each host you need.
|
|
72
|
+
|
|
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
|
+
```
|
|
84
|
+
|
|
85
|
+
## Open mode
|
|
86
|
+
|
|
87
|
+
`open` is the default: a run that omits `environment.networking` already runs in
|
|
88
|
+
open mode. Set `mode: "open"` explicitly when you want to be unambiguous, or when
|
|
89
|
+
a run needs to reach hosts you can't enumerate ahead of time. The run may then
|
|
90
|
+
reach any public host, still subject to the SSRF deny-list. Prefer `limited`
|
|
91
|
+
whenever you can name the hosts — it gives the run a stable, auditable, least-
|
|
92
|
+
privilege egress surface (it is the tighter posture, not the default).
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
await aex.submit({
|
|
96
|
+
model: Models.CLAUDE_HAIKU_4_5,
|
|
97
|
+
prompt: "Research the topic across the open web.",
|
|
98
|
+
environment: { networking: { mode: "open" } },
|
|
99
|
+
secrets: { apiKey: process.env.ANTHROPIC_API_KEY! }
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Transparent for normal HTTP clients
|
|
104
|
+
|
|
105
|
+
You write ordinary code — there is no per-request proxy configuration and no
|
|
106
|
+
client changes. The runtime sets the standard proxy environment
|
|
107
|
+
(`HTTP_PROXY` / `HTTPS_PROXY`, with `NO_PROXY` for internal hosts), so any client
|
|
108
|
+
that honors it — `curl`, Python `requests` / `urllib`, `pip`, `npm`, Node
|
|
109
|
+
`fetch`, and most language SDKs — reaches allowed hosts transparently:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# In the agent's shell, against a limited run that allows api.example.com:
|
|
113
|
+
curl -sS https://api.example.com/v1/status # works
|
|
114
|
+
curl -sS https://other-host.example # blocked (not in allowlist)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
You also do **not** need to install any certificate. The platform manages the
|
|
118
|
+
trust store for the managed egress path automatically, so TLS verification in
|
|
119
|
+
your client succeeds without extra setup.
|
|
120
|
+
|
|
121
|
+
## Limitations and gotchas
|
|
122
|
+
|
|
123
|
+
- **Enforcement is at the platform boundary, not in your code.** A tool can't
|
|
124
|
+
bypass the policy by ignoring proxy settings or opening a raw socket — the
|
|
125
|
+
sandbox has no other route out, so a disallowed host simply fails. This is the
|
|
126
|
+
intended fail-closed behavior.
|
|
127
|
+
- **A client that hard-bypasses the standard environment may fail to connect.**
|
|
128
|
+
This is rare — almost all HTTP tooling honors `HTTP_PROXY` / `HTTPS_PROXY` and
|
|
129
|
+
the system trust store. But a client that is explicitly told to ignore the
|
|
130
|
+
proxy environment, pins or replaces its certificate trust store, or speaks a
|
|
131
|
+
non-HTTP protocol over a raw socket can hit a wall even for an allowed host.
|
|
132
|
+
The fix is to let the client use the standard proxy and certificate
|
|
133
|
+
environment the runtime provides (most libraries do by default), rather than
|
|
134
|
+
overriding it.
|
|
135
|
+
- **`allowedHosts` only applies in `limited` mode.** It is ignored in `open`
|
|
136
|
+
mode, where the SSRF deny-list is the only gate.
|
|
137
|
+
|
|
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).
|
package/docs/quickstart.md
CHANGED
|
@@ -10,26 +10,35 @@ title: Quickstart
|
|
|
10
10
|
bun add @aexhq/sdk
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
## 2.
|
|
13
|
+
## 2. Run a prompt
|
|
14
14
|
|
|
15
15
|
```ts
|
|
16
|
-
import { AgentExecutor, Models
|
|
16
|
+
import { AgentExecutor, Models } from "@aexhq/sdk";
|
|
17
17
|
|
|
18
|
-
const aex = new AgentExecutor({
|
|
19
|
-
apiToken: process.env.AEX_API_TOKEN!
|
|
20
|
-
});
|
|
18
|
+
const aex = new AgentExecutor({ apiToken: process.env.AEX_API_TOKEN! });
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
// run() submits, waits for the run to settle, and returns the result.
|
|
21
|
+
// `provider` is derived from the model; `apiKey` is your BYOK provider key.
|
|
22
|
+
const { text, ok } = await aex.run({
|
|
24
23
|
model: Models.CLAUDE_HAIKU_4_5,
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
apiKey: process.env.ANTHROPIC_API_KEY!,
|
|
25
|
+
prompt: "Write a short report and save it as a file."
|
|
27
26
|
});
|
|
27
|
+
|
|
28
|
+
console.log(ok, text);
|
|
28
29
|
```
|
|
29
30
|
|
|
30
|
-
## 3.
|
|
31
|
+
## 3. Submit, stream, wait, and download
|
|
32
|
+
|
|
33
|
+
When you need the run id, live events, or downloads, drive the lifecycle yourself:
|
|
31
34
|
|
|
32
35
|
```ts
|
|
36
|
+
const runId = await aex.submit({
|
|
37
|
+
model: Models.CLAUDE_HAIKU_4_5,
|
|
38
|
+
apiKey: process.env.ANTHROPIC_API_KEY!,
|
|
39
|
+
prompt: "Write a short report and save it as a file."
|
|
40
|
+
});
|
|
41
|
+
|
|
33
42
|
for await (const event of aex.stream(runId)) {
|
|
34
43
|
console.log(event.type);
|
|
35
44
|
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference: a read-only, multi-run chat over a CORPUS of aex runs.
|
|
3
|
+
*
|
|
4
|
+
* Combines the public `@aexhq/sdk` corpus read-tools (`createCorpusTools`) with a
|
|
5
|
+
* direct Claude chat loop (`@anthropic-ai/sdk`). The importable `@aexhq/sdk` stays
|
|
6
|
+
* LLM-vendor-free; the vendor dependency lives only here in the example (and in
|
|
7
|
+
* the bundled `aex chat` CLI command).
|
|
8
|
+
*
|
|
9
|
+
* Run (Bun): ANTHROPIC_API_KEY=… AEX_TOKEN=… bun examples/chat-corpus.ts <runId> [runId…]
|
|
10
|
+
*
|
|
11
|
+
* The model answers ONLY from the named runs' outputs (read via the corpus
|
|
12
|
+
* tools); a run outside the corpus is refused by the tool layer.
|
|
13
|
+
*/
|
|
14
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
15
|
+
import { AgentExecutor, createCorpusTools, DataToolError } from "@aexhq/sdk";
|
|
16
|
+
|
|
17
|
+
const runIds = process.argv.slice(2);
|
|
18
|
+
if (runIds.length === 0) {
|
|
19
|
+
console.error("usage: bun examples/chat-corpus.ts <runId> [runId…]");
|
|
20
|
+
process.exit(2);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const aex = new AgentExecutor({
|
|
24
|
+
apiToken: process.env.AEX_TOKEN!,
|
|
25
|
+
...(process.env.AEX_URL ? { baseUrl: process.env.AEX_URL } : {})
|
|
26
|
+
});
|
|
27
|
+
const tools = createCorpusTools(aex, { runIds });
|
|
28
|
+
const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY! });
|
|
29
|
+
|
|
30
|
+
const SYSTEM =
|
|
31
|
+
"You answer questions about a fixed set of aex agent runs using the provided tools. " +
|
|
32
|
+
tools.instructions;
|
|
33
|
+
|
|
34
|
+
// Anthropic wire-shape tool defs: { name, description, input_schema }. The corpus
|
|
35
|
+
// tool defs are already in that exact shape. Put one cache_control breakpoint on
|
|
36
|
+
// the LAST tool so the (deterministic) tool list + system prefix cache together.
|
|
37
|
+
const wireTools = tools.tools.map((t, i) => ({
|
|
38
|
+
name: t.name,
|
|
39
|
+
description: t.description,
|
|
40
|
+
input_schema: t.input_schema,
|
|
41
|
+
...(i === tools.tools.length - 1 ? { cache_control: { type: "ephemeral" as const } } : {})
|
|
42
|
+
}));
|
|
43
|
+
|
|
44
|
+
const messages: Anthropic.MessageParam[] = [
|
|
45
|
+
{
|
|
46
|
+
role: "user",
|
|
47
|
+
content: "Across these runs, what did they produce and what are the headline findings?"
|
|
48
|
+
}
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
for (let turn = 0; turn < 12; turn++) {
|
|
52
|
+
const stream = anthropic.messages.stream({
|
|
53
|
+
model: process.env.AEX_CHAT_MODEL ?? "claude-opus-4-8",
|
|
54
|
+
max_tokens: 8192,
|
|
55
|
+
thinking: { type: "adaptive" },
|
|
56
|
+
system: [{ type: "text", text: SYSTEM }],
|
|
57
|
+
tools: wireTools,
|
|
58
|
+
messages
|
|
59
|
+
});
|
|
60
|
+
stream.on("text", (delta) => process.stdout.write(delta));
|
|
61
|
+
const response = await stream.finalMessage();
|
|
62
|
+
messages.push({ role: "assistant", content: response.content });
|
|
63
|
+
|
|
64
|
+
if (response.stop_reason === "refusal") {
|
|
65
|
+
console.error("\n[refused]", response.stop_details?.category ?? "");
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
if (response.stop_reason === "end_turn" || response.stop_reason === "max_tokens") break;
|
|
69
|
+
if (response.stop_reason === "pause_turn") continue;
|
|
70
|
+
if (response.stop_reason !== "tool_use") break;
|
|
71
|
+
|
|
72
|
+
const toolResults: Anthropic.ToolResultBlockParam[] = [];
|
|
73
|
+
for (const block of response.content) {
|
|
74
|
+
if (block.type !== "tool_use") continue;
|
|
75
|
+
try {
|
|
76
|
+
const result = await tools.execute(block.name, block.input as Record<string, unknown>);
|
|
77
|
+
toolResults.push({ type: "tool_result", tool_use_id: block.id, content: JSON.stringify(result) });
|
|
78
|
+
} catch (err) {
|
|
79
|
+
const message = err instanceof DataToolError ? err.message : String(err);
|
|
80
|
+
toolResults.push({ type: "tool_result", tool_use_id: block.id, content: message, is_error: true });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
messages.push({ role: "user", content: toolResults });
|
|
84
|
+
}
|
|
85
|
+
console.log();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aexhq/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"description": "TypeScript SDK for running autonomous agent sessions across providers (Anthropic, OpenAI, DeepSeek, Gemini, Mistral) behind one interface.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"pack:dry-run": "bun ../../scripts/with-generated-dist-lock.mjs bun pm pack --dry-run --ignore-scripts"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@aexhq/contracts": "0.
|
|
44
|
+
"@aexhq/contracts": "0.30.0"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|
|
47
47
|
"bun": ">=1.3.14"
|