@aexhq/sdk 0.78.0 → 0.80.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 +76 -108
- package/dist/generated.d.ts +16 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,119 +1,87 @@
|
|
|
1
1
|
# Aex SDK
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
require an account credential. Configure `maxCostMicroUsd` on a prepaid workload client for its
|
|
6
|
-
per-operation ceiling. Attachment uploads also accept `downloadBudgetBytes` and an optional
|
|
7
|
-
operation-specific `maxCostMicroUsd`. See [billing](../../docs/billing.md) for units and recovery.
|
|
3
|
+
Run AI agents on [Aex](https://aex.dev) from JavaScript or TypeScript. Connect your model and
|
|
4
|
+
tools, send messages, and read saved conversations without operating a Brain server.
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
after client close; host Tools require their process online. Follow Events from that sequence and read
|
|
11
|
-
the transcript when the turn terminates. Put structured correction policy in the hosted Agentloop
|
|
12
|
-
when submitting from a short-lived Server Action.
|
|
6
|
+
## Get started
|
|
13
7
|
|
|
14
|
-
|
|
8
|
+
Create a key in the [dashboard](https://aex.dev/dashboard). With Node.js 22 or newer, install:
|
|
15
9
|
|
|
16
|
-
```
|
|
17
|
-
|
|
10
|
+
```sh
|
|
11
|
+
npm install @aexhq/sdk@0.80.0 @aexhq/agentloop-pi@7.1.0 zod@4
|
|
12
|
+
```
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
Set `AEX_API_KEY` and `OPENAI_API_KEY` in your server environment. Save as `order.mjs` and
|
|
15
|
+
run `node order.mjs`:
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import { Aex, brainEnv, tool } from "@aexhq/sdk";
|
|
19
|
+
import { pi } from "@aexhq/agentloop-pi";
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
|
|
22
|
+
const lookupOrder = tool({
|
|
23
|
+
name: "lookup_order",
|
|
24
|
+
description: "Look up an order by id.",
|
|
25
|
+
input: z.object({ id: z.string() }),
|
|
26
|
+
run: ({ id }, ctx) => ctx.finish({ id, status: "shipped" }),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const aex = new Aex({ apiKey: process.env.AEX_API_KEY });
|
|
30
|
+
try {
|
|
31
|
+
const session = await aex.sessions.create({
|
|
32
|
+
model: { provider: "openai", name: "gpt-4.1-mini", apiKey: process.env.OPENAI_API_KEY },
|
|
33
|
+
agentloop: pi({ env: brainEnv({ name: "brain" }) }),
|
|
34
|
+
tools: [lookupOrder()],
|
|
35
|
+
});
|
|
36
|
+
try {
|
|
37
|
+
await session.send("Look up order A-1001. Has it shipped?");
|
|
38
|
+
console.log(JSON.stringify(await session.transcript(), null, 2));
|
|
39
|
+
console.log("Session:", session.id);
|
|
40
|
+
} finally {
|
|
41
|
+
await session.end();
|
|
42
|
+
}
|
|
43
|
+
} finally {
|
|
44
|
+
await aex.close();
|
|
45
|
+
}
|
|
21
46
|
```
|
|
22
47
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
A forgotten finish stays open until the original deadline, cancellation or Environment loss;
|
|
49
|
-
without a deadline it can remain open indefinitely.
|
|
50
|
-
|
|
51
|
-
Host Tools accept ordinary successful output or a Brain `Outcome` directly. Structured errors retain
|
|
52
|
-
code, message, retryable and details. The top-level statuses `ok`, `error`, `timeout`, `cancelled`
|
|
53
|
-
and `unknown` declare outcomes; malformed envelopes fail validation, and only successful values
|
|
54
|
-
pass through the output schema. Tool deadlines produce `timeout`, explicit cancellation produces
|
|
55
|
-
`cancelled`, and missing reliable results after dispatch produce `unknown`. All are failed Tool
|
|
56
|
-
results. Timeout and cancellation do not promise rollback. See
|
|
57
|
-
[the full return contract](https://aex.dev/brain/docs/guides/write-a-tool#return-values-and-outcomes).
|
|
58
|
-
|
|
59
|
-
`@aexhq/tools-mcp` runs selected MCP Tools in your application host, preserving structured failures
|
|
60
|
-
and original JSON Schema constraints. The official Docker and browser HTTP Environments target
|
|
61
|
-
standalone Brain and require operator deployment. See [official extensions](https://github.com/aexhq/extensions).
|
|
62
|
-
|
|
63
|
-
Place uploaded Wasm Agentloops and Tools in `brainEnv` for hosted execution. `hostEnv`
|
|
64
|
-
executes application functions in your process. Native hosted Components receive no server
|
|
65
|
-
secrets, filesystem or network grants. `await aex.environments.list()` lists your account's
|
|
66
|
-
published configurations. Import `modal` from `@aexhq/env-modal` and pass the catalog URL and
|
|
67
|
-
granted profile name; [managed execution](../../docs/environments.md) reserves credits at creation.
|
|
68
|
-
Customer-selected HTTP endpoints are denied. Hosted `brainEnv` configuration must be empty; resource access
|
|
69
|
-
is configured by each Environment, not declared through extension `needs`. Prepare dependencies
|
|
70
|
-
for `hostEnv` Tools in your application before registering them. Supply your model key per session.
|
|
71
|
-
|
|
72
|
-
`account.get()` and `account.usage()` accept a workload API key. `keys` management requires
|
|
73
|
-
an authenticated account session and is normally performed in the dashboard. API keys do
|
|
74
|
-
not grant authority to create more credentials. New key secrets are returned once.
|
|
75
|
-
|
|
76
|
-
## Structured output
|
|
77
|
-
|
|
78
|
-
For asynchronous hosted work, configure the official loop with
|
|
79
|
-
`output: {schema: z.toJSONSchema(answerType), maxCorrections: 2}` and use `session.submit()`.
|
|
80
|
-
Validation and bounded corrections run inside that turn. Corrections cannot dispatch Tools;
|
|
81
|
-
only a schema-valid final answer emits an assistant message. Business refinements belong in
|
|
82
|
-
your Tools or application, and are not encoded by JSON Schema.
|
|
83
|
-
|
|
84
|
-
Pass `output: { type: z.object({ name: z.string() }), maxRetries: 2 }` in the second
|
|
85
|
-
argument to `session.send`. The SDK prompts for JSON, validates with Zod locally,
|
|
86
|
-
and returns the inferred parsed value. Two additional correction turns are allowed
|
|
87
|
-
by default; set zero to disable retries. Ordinary sends keep returning session state;
|
|
88
|
-
`idle` alone does not mean the turn succeeded. No terminal Tool is needed for structured output.
|
|
89
|
-
|
|
90
|
-
See the [executable example](https://github.com/aexhq/aex/blob/main/examples/structured-output.mjs)
|
|
91
|
-
and [full contract](https://aex.dev/brain/docs/guides/structured-output).
|
|
92
|
-
Exhaustion throws `StructuredOutputError` with `attempts`, `lastOutput`, and `issues`.
|
|
93
|
-
Retries run in your client and are ordinary turns with the session's existing tools.
|
|
94
|
-
Use exclusive ownership of sends during the operation. An optional top-level
|
|
95
|
-
`signal` cancels the active turn and stops corrections. Raw attempts remain visible
|
|
96
|
-
in history and streams; validation does not change the Agentloop or provider format.
|
|
97
|
-
|
|
98
|
-
## Account management
|
|
99
|
-
|
|
100
|
-
Use an account session obtained through browser login for account management. Workload
|
|
101
|
-
API keys remain scoped to runtime operations and read-only account/usage access.
|
|
102
|
-
|
|
103
|
-
```ts
|
|
104
|
-
const account = new Aex({ accountToken: process.env.AEX_ACCOUNT_TOKEN! });
|
|
105
|
-
await account.keys.list();
|
|
106
|
-
const issued = await account.keys.create({ name: "My app" });
|
|
107
|
-
await account.keys.update(issued.key.id, { name: "Renamed app" });
|
|
108
|
-
await account.keys.delete(issued.key.id);
|
|
109
|
-
await account.account.get(); // includes billing status and limits
|
|
110
|
-
await account.account.usage();
|
|
111
|
-
await account.account.logout();
|
|
48
|
+
The transcript includes an order lookup and the agent's answer. The lookup function runs in your
|
|
49
|
+
process; keep it connected while the agent needs that tool. The [quickstart](https://aex.dev/docs)
|
|
50
|
+
explains setup and where other tools run.
|
|
51
|
+
|
|
52
|
+
## Sessions and tools
|
|
53
|
+
|
|
54
|
+
The SDK uses Brain's session API and extension helpers. You can import `tool`, `agentloop`,
|
|
55
|
+
`brainEnv`, `hostEnv`, `component` and `environment` from `@aexhq/sdk`.
|
|
56
|
+
|
|
57
|
+
- [Sessions](https://aex.dev/brain/docs/concepts/sessions): send, submit, stream, reconnect and stop.
|
|
58
|
+
- [Tools](https://aex.dev/brain/docs/guides/write-a-tool): application functions and packaged tools.
|
|
59
|
+
- [Structured output](https://aex.dev/brain/docs/guides/structured-output): validated JSON answers.
|
|
60
|
+
- [Managed environments](https://github.com/aexhq/aex/blob/main/docs/environments.md): hosted tools and workspaces.
|
|
61
|
+
- [Attachments](https://github.com/aexhq/aex/blob/main/docs/attachments.md): upload images and PDFs.
|
|
62
|
+
|
|
63
|
+
Use `ctx.finish(value)` to complete a tool. Use `aex.close()` in `finally` to close client
|
|
64
|
+
connections. Closing the client keeps stored sessions; tools in your process still require it.
|
|
65
|
+
|
|
66
|
+
## Account and usage
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
console.log(await aex.account.get());
|
|
70
|
+
console.log(await aex.account.usage());
|
|
71
|
+
console.log(await aex.account.modelUsage(sessionId));
|
|
72
|
+
console.log(await aex.environments.list());
|
|
112
73
|
```
|
|
113
74
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
75
|
+
Run these before closing the client. Workload keys can read account and usage information.
|
|
76
|
+
Creating keys, accepting prices, topups and refunds require an account login; use the
|
|
77
|
+
[dashboard](https://aex.dev/dashboard) or [CLI](https://www.npmjs.com/package/@aexhq/cli).
|
|
78
|
+
|
|
79
|
+
See the [billing guide](https://github.com/aexhq/aex/blob/main/docs/billing.md) for account API
|
|
80
|
+
methods and `maxCostMicroUsd`, the ceiling for a resource operation. Aex spending controls do
|
|
81
|
+
not cap your separate model-provider bill.
|
|
118
82
|
|
|
119
|
-
|
|
83
|
+
Inline Tools default to the process registering them. Published libraries use Brain's generated
|
|
84
|
+
bindings and the selected Environment's prepared runtime. `ctx.finish(value, { content: summary })`
|
|
85
|
+
retains the structured result while offering concise model text. `ctx.model({ messages })` runs an
|
|
86
|
+
independent request within the invocation's lifetime and the session's model authority; hosted
|
|
87
|
+
usage and spending controls include those requests. The Agentloop owns the shared conversation.
|
package/dist/generated.d.ts
CHANGED
|
@@ -63,6 +63,18 @@ export interface Limits {
|
|
|
63
63
|
upstream_timeout_secs: number;
|
|
64
64
|
usage_max_age_secs: number;
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
68
|
+
* via the `definition` "TokenUsage".
|
|
69
|
+
*/
|
|
70
|
+
export interface TokenUsage {
|
|
71
|
+
charged_micro_usd: number;
|
|
72
|
+
pending_estimate_micro_usd: number;
|
|
73
|
+
rated_micro_usd: number;
|
|
74
|
+
reported_input_tokens: number;
|
|
75
|
+
reported_output_tokens: number;
|
|
76
|
+
unmeasured_calls: number;
|
|
77
|
+
}
|
|
66
78
|
/**
|
|
67
79
|
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
68
80
|
* via the `definition` "Usage".
|
|
@@ -72,6 +84,7 @@ export interface Usage {
|
|
|
72
84
|
attachment_bytes: number;
|
|
73
85
|
attachments: number;
|
|
74
86
|
measured_at?: number | null;
|
|
87
|
+
model: TokenUsage;
|
|
75
88
|
retained_bytes: number;
|
|
76
89
|
sessions: number;
|
|
77
90
|
}
|
|
@@ -155,6 +168,7 @@ export interface Pricebook {
|
|
|
155
168
|
rates: {
|
|
156
169
|
attachment_byte_secs?: Rate;
|
|
157
170
|
egress_bytes?: Rate;
|
|
171
|
+
model_tokens?: Rate;
|
|
158
172
|
sandbox_ms?: Rate;
|
|
159
173
|
turn_ms?: Rate;
|
|
160
174
|
};
|
|
@@ -175,12 +189,14 @@ export interface Rate {
|
|
|
175
189
|
*/
|
|
176
190
|
export interface Wallet {
|
|
177
191
|
accepted_pricebook?: string | null;
|
|
192
|
+
accepted_rates?: Pricebook | null;
|
|
178
193
|
available_micro_usd: number;
|
|
179
194
|
balance_micro_usd: number;
|
|
180
195
|
currency: string;
|
|
181
196
|
mode: BillingMode;
|
|
182
197
|
offered_pricebook?: Pricebook | null;
|
|
183
198
|
payment_mode?: Mode | null;
|
|
199
|
+
pending_estimate_micro_usd: number;
|
|
184
200
|
reserved_micro_usd: number;
|
|
185
201
|
spend_limit_micro_usd?: number | null;
|
|
186
202
|
spent_this_month_micro_usd: number;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * from "@aexhq/brain";
|
|
2
2
|
export type * from "./generated.js";
|
|
3
3
|
import { Brain, type BrainOptions } from "@aexhq/brain";
|
|
4
|
-
import type { EnvironmentCatalog } from "./generated.js";
|
|
4
|
+
import type { EnvironmentCatalog, TokenUsage } from "./generated.js";
|
|
5
5
|
import type { Attachment, Account, Usage, ApiKey, IssuedKey, KeyInput, LoginGrantInput, LoginGrant, LoginExchange, AccountSession, Wallet, BillingSettings, LedgerPage, Topup, TopupInput, Refund, RefundInput, SyncPayment } from "./generated.js";
|
|
6
6
|
export type AexConnection = Omit<BrainOptions, "token" | "baseUrl"> & {
|
|
7
7
|
baseUrl?: string;
|
|
@@ -18,7 +18,7 @@ export type AexOptions = AexConnection & {
|
|
|
18
18
|
export declare class Aex extends Brain {
|
|
19
19
|
private readonly maxCostMicroUsd?;
|
|
20
20
|
constructor({ apiKey, accountToken, maxCostMicroUsd, ...options }: AexOptions);
|
|
21
|
-
/**
|
|
21
|
+
/** Resource and legacy turn reservations use this ceiling; token hosting follows the account limit. */
|
|
22
22
|
request<T>(method: string, path: string, body?: unknown, idempotencyKey?: string, contentType?: string, signal?: AbortSignal, extraHeaders?: HeadersInit): Promise<T>;
|
|
23
23
|
static exchangeLogin(input: LoginExchange, options?: AexConnection): Promise<AccountSession>;
|
|
24
24
|
readonly attachments: {
|
|
@@ -35,6 +35,7 @@ export declare class Aex extends Brain {
|
|
|
35
35
|
readonly account: {
|
|
36
36
|
get: () => Promise<Account>;
|
|
37
37
|
usage: () => Promise<Usage>;
|
|
38
|
+
modelUsage: (sessionId: string) => Promise<TokenUsage>;
|
|
38
39
|
logout: () => Promise<void>;
|
|
39
40
|
authorizeLogin: (input: LoginGrantInput) => Promise<LoginGrant>;
|
|
40
41
|
};
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ export class Aex extends Brain {
|
|
|
14
14
|
nonnegativeInteger(maxCostMicroUsd, "maxCostMicroUsd");
|
|
15
15
|
this.maxCostMicroUsd = maxCostMicroUsd;
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
17
|
+
/** Resource and legacy turn reservations use this ceiling; token hosting follows the account limit. */
|
|
18
18
|
request(method, path, body, idempotencyKey, contentType = "application/json", signal, extraHeaders) {
|
|
19
19
|
const headers = new Headers(extraHeaders);
|
|
20
20
|
if (this.maxCostMicroUsd !== undefined && !headers.has("x-aex-max-cost-micro-usd"))
|
|
@@ -46,6 +46,7 @@ export class Aex extends Brain {
|
|
|
46
46
|
account = {
|
|
47
47
|
get: () => this.request("GET", "/v1/account"),
|
|
48
48
|
usage: () => this.request("GET", "/v1/usage"),
|
|
49
|
+
modelUsage: (sessionId) => this.request("GET", `/v1/usage/${encodeURIComponent(sessionId)}`),
|
|
49
50
|
logout: () => this.request("DELETE", "/v1/account/session"),
|
|
50
51
|
authorizeLogin: (input) => this.request("POST", "/v1/auth/grants", input),
|
|
51
52
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aexhq/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.80.0",
|
|
4
4
|
"description": "Aex accounts and hosted sessions using the Brain SDK",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"tag": "next"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@aexhq/brain": "0.
|
|
31
|
+
"@aexhq/brain": "0.30.0"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
34
|
"gen": "node ../../tools/sdk-contracts.mjs",
|