@aexhq/sdk 0.75.3 → 0.77.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 +23 -4
- package/dist/generated.d.ts +158 -1
- package/dist/index.d.ts +24 -3
- package/dist/index.js +45 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Aex SDK
|
|
2
2
|
|
|
3
|
+
`aex.billing` reads credits and ledger entries, accepts a pricebook and spend limit, creates
|
|
4
|
+
idempotent Stripe topups/refunds, and synchronizes provider status and receipt links. Mutations
|
|
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.
|
|
8
|
+
|
|
9
|
+
`session.submit()` returns the saved turn's event sequence immediately. Hosted Tools keep running
|
|
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.
|
|
13
|
+
|
|
3
14
|
Install `@aexhq/sdk`. Create an API key at https://aex.dev/dashboard.
|
|
4
15
|
|
|
5
16
|
```ts
|
|
@@ -10,8 +21,8 @@ console.log(await aex.account.get());
|
|
|
10
21
|
```
|
|
11
22
|
|
|
12
23
|
`Aex` extends the pinned Brain client. Its sessions, registration, Events, Components and
|
|
13
|
-
extension builders are Brain's implementations. SDK 0.
|
|
14
|
-
6.
|
|
24
|
+
extension builders are Brain's implementations. SDK 0.77 uses Brain SDK 0.27 and Pi/Codex
|
|
25
|
+
6.2. Images and PDFs use HTTPS URLs; Aex owns attachment publication and expiry. Deploy the matching
|
|
15
26
|
runtime and extensions together. Retained sessions require a compatibility check before upgrading.
|
|
16
27
|
See https://aex.dev/docs
|
|
17
28
|
for a complete session example.
|
|
@@ -42,8 +53,10 @@ standalone Brain and require operator deployment. See [official extensions](http
|
|
|
42
53
|
|
|
43
54
|
Place uploaded Wasm Agentloops and Tools in `brainEnv` for hosted execution. `hostEnv`
|
|
44
55
|
executes application functions in your process. Native hosted Components receive no server
|
|
45
|
-
secrets, filesystem or network grants.
|
|
46
|
-
|
|
56
|
+
secrets, filesystem or network grants. `await aex.environments.list()` lists your account's
|
|
57
|
+
published configurations. Import `modal` from `@aexhq/env-modal` and pass the catalog URL and
|
|
58
|
+
granted profile name; [managed execution](../../docs/environments.md) reserves credits at creation.
|
|
59
|
+
Customer-selected HTTP endpoints are denied. Hosted `brainEnv` configuration must be empty; resource access
|
|
47
60
|
is configured by each Environment, not declared through extension `needs`. Prepare dependencies
|
|
48
61
|
for `hostEnv` Tools in your application before registering them. Supply your model key per session.
|
|
49
62
|
|
|
@@ -53,6 +66,12 @@ not grant authority to create more credentials. New key secrets are returned onc
|
|
|
53
66
|
|
|
54
67
|
## Structured output
|
|
55
68
|
|
|
69
|
+
For asynchronous hosted work, configure the official loop with
|
|
70
|
+
`output: {schema: z.toJSONSchema(answerType), maxCorrections: 2}` and use `session.submit()`.
|
|
71
|
+
Validation and bounded corrections run inside that turn. Corrections cannot dispatch Tools;
|
|
72
|
+
only a schema-valid final answer emits an assistant message. Business refinements belong in
|
|
73
|
+
your Tools or application, and are not encoded by JSON Schema.
|
|
74
|
+
|
|
56
75
|
Pass `output: { type: z.object({ name: z.string() }), maxRetries: 2 }` in the second
|
|
57
76
|
argument to `session.send`. The SDK prompts for JSON, validates with Zod locally,
|
|
58
77
|
and returns the inferred parsed value. Two additional correction turns are allowed
|
package/dist/generated.d.ts
CHANGED
|
@@ -3,7 +3,30 @@ import type { Media } from "@aexhq/brain";
|
|
|
3
3
|
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
4
4
|
* via the `definition` "Billing".
|
|
5
5
|
*/
|
|
6
|
-
export type Billing = "preview_customer_model_keys";
|
|
6
|
+
export type Billing = "preview_customer_model_keys" | "prepaid_customer_model_keys";
|
|
7
|
+
/**
|
|
8
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
9
|
+
* via the `definition` "BillingMode".
|
|
10
|
+
*/
|
|
11
|
+
export type BillingMode = "preview" | "prepaid";
|
|
12
|
+
/**
|
|
13
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
14
|
+
* via the `definition` "Mode".
|
|
15
|
+
*/
|
|
16
|
+
export type Mode = "test" | "live";
|
|
17
|
+
/**
|
|
18
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
19
|
+
* via the `definition` "SyncPayment".
|
|
20
|
+
*/
|
|
21
|
+
export type SyncPayment = {
|
|
22
|
+
checkout_id?: string | null;
|
|
23
|
+
id: string;
|
|
24
|
+
kind: "topup";
|
|
25
|
+
} | {
|
|
26
|
+
id: string;
|
|
27
|
+
kind: "refund";
|
|
28
|
+
refund_id?: string | null;
|
|
29
|
+
};
|
|
7
30
|
export interface AexContracts {
|
|
8
31
|
}
|
|
9
32
|
/**
|
|
@@ -123,3 +146,137 @@ export interface AccountSession {
|
|
|
123
146
|
expires: number;
|
|
124
147
|
token: string;
|
|
125
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
151
|
+
* via the `definition` "Pricebook".
|
|
152
|
+
*/
|
|
153
|
+
export interface Pricebook {
|
|
154
|
+
id: string;
|
|
155
|
+
rates: {
|
|
156
|
+
attachment_byte_secs?: Rate;
|
|
157
|
+
egress_bytes?: Rate;
|
|
158
|
+
sandbox_ms?: Rate;
|
|
159
|
+
turn_ms?: Rate;
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* A rational price in micro-USD. Rating rounds once over cumulative resource usage.
|
|
164
|
+
*
|
|
165
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
166
|
+
* via the `definition` "Rate".
|
|
167
|
+
*/
|
|
168
|
+
export interface Rate {
|
|
169
|
+
micro_usd: number;
|
|
170
|
+
units: number;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
174
|
+
* via the `definition` "Wallet".
|
|
175
|
+
*/
|
|
176
|
+
export interface Wallet {
|
|
177
|
+
accepted_pricebook?: string | null;
|
|
178
|
+
available_micro_usd: number;
|
|
179
|
+
balance_micro_usd: number;
|
|
180
|
+
currency: string;
|
|
181
|
+
mode: BillingMode;
|
|
182
|
+
offered_pricebook?: Pricebook | null;
|
|
183
|
+
payment_mode?: Mode | null;
|
|
184
|
+
reserved_micro_usd: number;
|
|
185
|
+
spend_limit_micro_usd?: number | null;
|
|
186
|
+
spent_this_month_micro_usd: number;
|
|
187
|
+
suspended: boolean;
|
|
188
|
+
topup_amounts_cents: number[];
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
192
|
+
* via the `definition` "BillingSettings".
|
|
193
|
+
*/
|
|
194
|
+
export interface BillingSettings {
|
|
195
|
+
pricebook: string;
|
|
196
|
+
spend_limit_micro_usd: number;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
200
|
+
* via the `definition` "LedgerEntry".
|
|
201
|
+
*/
|
|
202
|
+
export interface LedgerEntry {
|
|
203
|
+
created: number;
|
|
204
|
+
delta_micro_usd: number;
|
|
205
|
+
description: string;
|
|
206
|
+
id: number;
|
|
207
|
+
kind: string;
|
|
208
|
+
reference: string;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
212
|
+
* via the `definition` "LedgerPage".
|
|
213
|
+
*/
|
|
214
|
+
export interface LedgerPage {
|
|
215
|
+
entries: LedgerEntry[];
|
|
216
|
+
next_before?: number | null;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
220
|
+
* via the `definition` "TopupInput".
|
|
221
|
+
*/
|
|
222
|
+
export interface TopupInput {
|
|
223
|
+
amount_cents: number;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
227
|
+
* via the `definition` "Topup".
|
|
228
|
+
*/
|
|
229
|
+
export interface Topup {
|
|
230
|
+
amount_cents: number;
|
|
231
|
+
checkout_url?: string | null;
|
|
232
|
+
created: number;
|
|
233
|
+
id: string;
|
|
234
|
+
receipt_url?: string | null;
|
|
235
|
+
refunded_cents: number;
|
|
236
|
+
state: string;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
240
|
+
* via the `definition` "RefundInput".
|
|
241
|
+
*/
|
|
242
|
+
export interface RefundInput {
|
|
243
|
+
amount_cents: number;
|
|
244
|
+
topup: string;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
248
|
+
* via the `definition` "Refund".
|
|
249
|
+
*/
|
|
250
|
+
export interface Refund {
|
|
251
|
+
amount_cents: number;
|
|
252
|
+
created: number;
|
|
253
|
+
id: string;
|
|
254
|
+
state: string;
|
|
255
|
+
topup: string;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
259
|
+
* via the `definition` "EnvironmentProfile".
|
|
260
|
+
*/
|
|
261
|
+
export interface EnvironmentProfile {
|
|
262
|
+
maxLifetimeMs: number;
|
|
263
|
+
[k: string]: unknown;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
267
|
+
* via the `definition` "EnvironmentCatalog".
|
|
268
|
+
*/
|
|
269
|
+
export interface EnvironmentCatalog {
|
|
270
|
+
driver_url: string;
|
|
271
|
+
profiles: {
|
|
272
|
+
[k: string]: EnvironmentProfile;
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
277
|
+
* via the `definition` "EnvironmentSelection".
|
|
278
|
+
*/
|
|
279
|
+
export interface EnvironmentSelection {
|
|
280
|
+
lifetimeMs: number;
|
|
281
|
+
profile: string;
|
|
282
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
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 {
|
|
4
|
+
import type { EnvironmentCatalog } from "./generated.js";
|
|
5
|
+
import type { Attachment, Account, Usage, ApiKey, IssuedKey, KeyInput, LoginGrantInput, LoginGrant, LoginExchange, AccountSession, Wallet, BillingSettings, LedgerPage, Topup, TopupInput, Refund, RefundInput, SyncPayment } from "./generated.js";
|
|
5
6
|
export type AexConnection = Omit<BrainOptions, "token" | "baseUrl"> & {
|
|
6
7
|
baseUrl?: string;
|
|
7
8
|
};
|
|
8
|
-
export type AexOptions = AexConnection &
|
|
9
|
+
export type AexOptions = AexConnection & {
|
|
10
|
+
maxCostMicroUsd?: number;
|
|
11
|
+
} & ({
|
|
9
12
|
apiKey: string;
|
|
10
13
|
accountToken?: never;
|
|
11
14
|
} | {
|
|
@@ -13,13 +16,18 @@ export type AexOptions = AexConnection & ({
|
|
|
13
16
|
apiKey?: never;
|
|
14
17
|
});
|
|
15
18
|
export declare class Aex extends Brain {
|
|
16
|
-
|
|
19
|
+
private readonly maxCostMicroUsd?;
|
|
20
|
+
constructor({ apiKey, accountToken, maxCostMicroUsd, ...options }: AexOptions);
|
|
21
|
+
/** The ceiling applies separately to each admitted operation. Model BYOK charges remain with the provider. */
|
|
22
|
+
request<T>(method: string, path: string, body?: unknown, idempotencyKey?: string, contentType?: string, signal?: AbortSignal, extraHeaders?: HeadersInit): Promise<T>;
|
|
17
23
|
static exchangeLogin(input: LoginExchange, options?: AexConnection): Promise<AccountSession>;
|
|
18
24
|
readonly attachments: {
|
|
19
25
|
upload: (sessionId: string, bytes: Uint8Array, options: {
|
|
20
26
|
contentType: string;
|
|
21
27
|
expiresAt?: number;
|
|
22
28
|
idempotencyKey: string;
|
|
29
|
+
downloadBudgetBytes?: number;
|
|
30
|
+
maxCostMicroUsd?: number;
|
|
23
31
|
signal?: AbortSignal;
|
|
24
32
|
}) => Promise<Attachment>;
|
|
25
33
|
delete: (sessionId: string, id: string) => Promise<void>;
|
|
@@ -30,6 +38,19 @@ export declare class Aex extends Brain {
|
|
|
30
38
|
logout: () => Promise<void>;
|
|
31
39
|
authorizeLogin: (input: LoginGrantInput) => Promise<LoginGrant>;
|
|
32
40
|
};
|
|
41
|
+
readonly billing: {
|
|
42
|
+
get: () => Promise<Wallet>;
|
|
43
|
+
update: (input: BillingSettings) => Promise<Wallet>;
|
|
44
|
+
ledger: (before?: number) => Promise<LedgerPage>;
|
|
45
|
+
topups: () => Promise<Topup[]>;
|
|
46
|
+
topup: (input: TopupInput, idempotencyKey: string) => Promise<Topup>;
|
|
47
|
+
refunds: () => Promise<Refund[]>;
|
|
48
|
+
refund: (input: RefundInput, idempotencyKey: string) => Promise<Refund>;
|
|
49
|
+
sync: (input: SyncPayment) => Promise<Wallet>;
|
|
50
|
+
};
|
|
51
|
+
readonly environments: {
|
|
52
|
+
list: () => Promise<EnvironmentCatalog>;
|
|
53
|
+
};
|
|
33
54
|
/** Key management requires an account session; workload API keys cannot create credentials. */
|
|
34
55
|
readonly keys: {
|
|
35
56
|
list: () => Promise<ApiKey[]>;
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
export * from "@aexhq/brain";
|
|
2
2
|
import { Brain } from "@aexhq/brain";
|
|
3
|
+
function nonnegativeInteger(value, name) {
|
|
4
|
+
if (!Number.isSafeInteger(value) || value < 0)
|
|
5
|
+
throw new TypeError(`${name} must be a nonnegative safe integer`);
|
|
6
|
+
}
|
|
3
7
|
export class Aex extends Brain {
|
|
4
|
-
|
|
8
|
+
maxCostMicroUsd;
|
|
9
|
+
constructor({ apiKey, accountToken, maxCostMicroUsd, ...options }) {
|
|
5
10
|
if (!(apiKey || accountToken) || (apiKey && accountToken))
|
|
6
11
|
throw new TypeError("one apiKey or accountToken is required");
|
|
7
12
|
super({ baseUrl: "https://api.aex.dev", ...options, token: apiKey ?? accountToken });
|
|
13
|
+
if (maxCostMicroUsd !== undefined)
|
|
14
|
+
nonnegativeInteger(maxCostMicroUsd, "maxCostMicroUsd");
|
|
15
|
+
this.maxCostMicroUsd = maxCostMicroUsd;
|
|
16
|
+
}
|
|
17
|
+
/** The ceiling applies separately to each admitted operation. Model BYOK charges remain with the provider. */
|
|
18
|
+
request(method, path, body, idempotencyKey, contentType = "application/json", signal, extraHeaders) {
|
|
19
|
+
const headers = new Headers(extraHeaders);
|
|
20
|
+
if (this.maxCostMicroUsd !== undefined && !headers.has("x-aex-max-cost-micro-usd"))
|
|
21
|
+
headers.set("x-aex-max-cost-micro-usd", String(this.maxCostMicroUsd));
|
|
22
|
+
return super.request(method, path, body, idempotencyKey, contentType, signal, headers);
|
|
8
23
|
}
|
|
9
24
|
static exchangeLogin(input, options = {}) {
|
|
10
25
|
return new Brain({ baseUrl: "https://api.aex.dev", ...options }).request("POST", "/v1/auth/exchange", input);
|
|
@@ -13,7 +28,18 @@ export class Aex extends Brain {
|
|
|
13
28
|
upload: (sessionId, bytes, options) => {
|
|
14
29
|
if (options.expiresAt !== undefined && (!Number.isSafeInteger(options.expiresAt) || options.expiresAt <= 0))
|
|
15
30
|
throw new TypeError("expiresAt must be positive Unix seconds");
|
|
16
|
-
|
|
31
|
+
const headers = {};
|
|
32
|
+
if (options.expiresAt !== undefined)
|
|
33
|
+
headers["x-aex-expires-at"] = String(options.expiresAt);
|
|
34
|
+
if (options.maxCostMicroUsd !== undefined) {
|
|
35
|
+
nonnegativeInteger(options.maxCostMicroUsd, "maxCostMicroUsd");
|
|
36
|
+
headers["x-aex-max-cost-micro-usd"] = String(options.maxCostMicroUsd);
|
|
37
|
+
}
|
|
38
|
+
if (options.downloadBudgetBytes !== undefined) {
|
|
39
|
+
nonnegativeInteger(options.downloadBudgetBytes, "downloadBudgetBytes");
|
|
40
|
+
headers["x-aex-download-budget-bytes"] = String(options.downloadBudgetBytes);
|
|
41
|
+
}
|
|
42
|
+
return this.request("POST", `/v1/sessions/${encodeURIComponent(sessionId)}/attachments`, bytes, options.idempotencyKey, options.contentType, options.signal, headers);
|
|
17
43
|
},
|
|
18
44
|
delete: (sessionId, id) => this.request("DELETE", `/v1/sessions/${encodeURIComponent(sessionId)}/attachments/${encodeURIComponent(id)}`),
|
|
19
45
|
};
|
|
@@ -23,6 +49,23 @@ export class Aex extends Brain {
|
|
|
23
49
|
logout: () => this.request("DELETE", "/v1/account/session"),
|
|
24
50
|
authorizeLogin: (input) => this.request("POST", "/v1/auth/grants", input),
|
|
25
51
|
};
|
|
52
|
+
billing = {
|
|
53
|
+
get: () => this.request("GET", "/v1/billing"),
|
|
54
|
+
update: (input) => this.request("PUT", "/v1/billing", input),
|
|
55
|
+
ledger: (before) => {
|
|
56
|
+
if (before !== undefined)
|
|
57
|
+
nonnegativeInteger(before, "before");
|
|
58
|
+
return this.request("GET", `/v1/billing/ledger${before === undefined ? "" : `?before=${before}`}`);
|
|
59
|
+
},
|
|
60
|
+
topups: () => this.request("GET", "/v1/billing/topups"),
|
|
61
|
+
topup: (input, idempotencyKey) => this.request("POST", "/v1/billing/topups", input, idempotencyKey),
|
|
62
|
+
refunds: () => this.request("GET", "/v1/billing/refunds"),
|
|
63
|
+
refund: (input, idempotencyKey) => this.request("POST", "/v1/billing/refunds", input, idempotencyKey),
|
|
64
|
+
sync: (input) => this.request("POST", "/v1/billing/sync", input),
|
|
65
|
+
};
|
|
66
|
+
environments = {
|
|
67
|
+
list: () => this.request("GET", "/v1/environments"),
|
|
68
|
+
};
|
|
26
69
|
/** Key management requires an account session; workload API keys cannot create credentials. */
|
|
27
70
|
keys = {
|
|
28
71
|
list: () => this.request("GET", "/v1/keys"),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aexhq/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.77.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.27.0"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
34
|
"gen": "node ../../tools/sdk-contracts.mjs",
|