@aexhq/sdk 0.84.0 → 0.85.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 +5 -3
- package/dist/application.d.ts +2 -0
- package/dist/application.js +12 -0
- package/dist/generated.d.ts +32 -0
- package/dist/index.d.ts +27 -4
- package/dist/index.js +31 -5
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ tools, send messages, and read saved conversations without operating a Brain ser
|
|
|
8
8
|
Create a key in the [dashboard](https://aex.dev/dashboard). With Node.js 22 or newer, install:
|
|
9
9
|
|
|
10
10
|
```sh
|
|
11
|
-
npm install @aexhq/sdk@0.
|
|
11
|
+
npm install @aexhq/sdk@0.85.0 @aexhq/agentloop-pi@7.2.4 zod@4.4.3
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
Set `AEX_API_KEY` and `OPENAI_API_KEY` in your server environment. Save as `order.mjs` and
|
|
@@ -119,7 +119,7 @@ correction. It supports JSON Schema, not arbitrary local Zod refinements or tran
|
|
|
119
119
|
Brain SDK 0.34 removes typed sends and the corresponding types and errors. Aex SDK 0.84
|
|
120
120
|
owns them. Existing Aex `send(..., { output })` calls keep the same syntax and behavior.
|
|
121
121
|
Import `StructuredSendOptions` and `StructuredOutputError` from `@aexhq/sdk`.
|
|
122
|
-
Use Pi/Codex 7.2.
|
|
122
|
+
Use Pi/Codex 7.2.4 and extension packages pinned to Brain 0.35.1 with this SDK.
|
|
123
123
|
Mixing exact Brain dependency versions creates different TypeScript extension brands.
|
|
124
124
|
|
|
125
125
|
An existing standalone Brain handle can use Aex's policy without changing servers:
|
|
@@ -159,7 +159,9 @@ independent request within the invocation's lifetime and the session's model aut
|
|
|
159
159
|
usage and spending controls include those requests. The Agentloop owns the shared conversation.
|
|
160
160
|
|
|
161
161
|
Connect short application functions through an authenticated HTTP route with
|
|
162
|
-
[HTTP tools](https://
|
|
162
|
+
[HTTP tools](https://aex.dev/docs/application). Submit a turn, close the
|
|
163
163
|
request and read its committed outcome later. Desktop apps can use
|
|
164
164
|
[upload-only grants](https://github.com/aexhq/aex/blob/main/docs/attachments.md#upload-from-a-desktop-without-an-account-key)
|
|
165
165
|
without receiving an account credential.
|
|
166
|
+
|
|
167
|
+
Choose [clientBrowser](https://aex.dev/docs/client-browser) for the user's connected tab, or [Application](https://aex.dev/docs/application) for a deployed backend. Both use `aex.sessions.create()` and ordinary Tool declarations.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { inspectEnvironment, inspectTool } from "@aexhq/brain";
|
|
2
|
+
import { applicationTool } from "@aexhq/env-http";
|
|
3
|
+
export function composeApplication(options, baseUrl) {
|
|
4
|
+
const url = new URL("/environments/application", baseUrl).href;
|
|
5
|
+
return { ...options, tools: options.tools?.map(placed => {
|
|
6
|
+
const tool = inspectTool(placed);
|
|
7
|
+
const environment = inspectEnvironment(tool.environment);
|
|
8
|
+
if (environment.driver.driver !== "http" || environment.driver.url !== url)
|
|
9
|
+
return placed;
|
|
10
|
+
return applicationTool(placed, { env: tool.environment });
|
|
11
|
+
}) };
|
|
12
|
+
}
|
package/dist/generated.d.ts
CHANGED
|
@@ -29,6 +29,38 @@ export type SyncPayment = {
|
|
|
29
29
|
};
|
|
30
30
|
export interface AexContracts {
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
34
|
+
* via the `definition` "ClientHost".
|
|
35
|
+
*/
|
|
36
|
+
export interface ClientHost {
|
|
37
|
+
hostId: string;
|
|
38
|
+
token: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
42
|
+
* via the `definition` "ClientAccess".
|
|
43
|
+
*/
|
|
44
|
+
export interface ClientAccess {
|
|
45
|
+
credentials: ClientHost;
|
|
46
|
+
expires_at: number;
|
|
47
|
+
id: string;
|
|
48
|
+
token: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
52
|
+
* via the `definition` "ClientGrantInput".
|
|
53
|
+
*/
|
|
54
|
+
export interface ClientGrantInput {
|
|
55
|
+
expires_at: number;
|
|
56
|
+
origin: string;
|
|
57
|
+
/**
|
|
58
|
+
* The prepared Brain request. Credentials remain on the server.
|
|
59
|
+
*/
|
|
60
|
+
session: {
|
|
61
|
+
[k: string]: unknown;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
32
64
|
/**
|
|
33
65
|
* This interface was referenced by `AexContracts`'s JSON-Schema
|
|
34
66
|
* via the `definition` "HttpCatalog".
|
package/dist/index.d.ts
CHANGED
|
@@ -3,9 +3,10 @@ export type * from "./generated.js";
|
|
|
3
3
|
export { AexSessionHandle } from "./session.js";
|
|
4
4
|
export { StructuredOutputError } from "./structured-output.js";
|
|
5
5
|
export type { StructuredSendOptions } from "./structured-output.js";
|
|
6
|
-
import {
|
|
6
|
+
import { application } from "@aexhq/env-http";
|
|
7
|
+
import { Brain, type BrainOptions, type CreateSessionOptions, type OperationOptions, type ModelSelection } from "@aexhq/brain";
|
|
7
8
|
import { AexSessionHandle } from "./session.js";
|
|
8
|
-
import type { EnvironmentCatalog, TokenUsage } from "./generated.js";
|
|
9
|
+
import type { ClientAccess, EnvironmentCatalog, TokenUsage } from "./generated.js";
|
|
9
10
|
import type { Attachment, Account, Usage, ApiKey, IssuedKey, KeyInput, LoginGrantInput, LoginGrant, LoginExchange, AccountSession, Wallet, BillingSettings, LedgerPage, Topup, TopupInput, Refund, RefundInput, SyncPayment } from "./generated.js";
|
|
10
11
|
export type AexConnection = Omit<BrainOptions, "token" | "baseUrl"> & {
|
|
11
12
|
baseUrl?: string;
|
|
@@ -15,16 +16,27 @@ export type AexOptions = AexConnection & {
|
|
|
15
16
|
} & ({
|
|
16
17
|
apiKey: string;
|
|
17
18
|
accountToken?: never;
|
|
19
|
+
clientAccess?: never;
|
|
18
20
|
} | {
|
|
19
21
|
accountToken: string;
|
|
20
22
|
apiKey?: never;
|
|
23
|
+
clientAccess?: never;
|
|
24
|
+
} | {
|
|
25
|
+
clientAccess: ClientAccess;
|
|
26
|
+
apiKey?: never;
|
|
27
|
+
accountToken?: never;
|
|
21
28
|
});
|
|
29
|
+
export type AexSessionOptions = Omit<CreateSessionOptions, "model"> & {
|
|
30
|
+
model: ModelSelection | Omit<ModelSelection, "apiKey">;
|
|
31
|
+
};
|
|
22
32
|
export declare class Aex {
|
|
23
33
|
private readonly client;
|
|
24
|
-
|
|
34
|
+
private readonly clientAccess?;
|
|
35
|
+
constructor({ apiKey, accountToken, clientAccess, maxCostMicroUsd, ...options }: AexOptions);
|
|
36
|
+
private composition;
|
|
25
37
|
get baseUrl(): string;
|
|
26
38
|
readonly sessions: Readonly<{
|
|
27
|
-
create: (options:
|
|
39
|
+
create: (options: AexSessionOptions, operation?: OperationOptions) => Promise<AexSessionHandle>;
|
|
28
40
|
get: (sessionId: string, options?: {
|
|
29
41
|
tools?: readonly import("@aexhq/brain").PlacedTool[];
|
|
30
42
|
} | undefined) => Promise<AexSessionHandle>;
|
|
@@ -77,7 +89,18 @@ export declare class Aex {
|
|
|
77
89
|
refund: (input: RefundInput, idempotencyKey: string) => Promise<Refund>;
|
|
78
90
|
sync: (input: SyncPayment) => Promise<Wallet>;
|
|
79
91
|
};
|
|
92
|
+
readonly clients: {
|
|
93
|
+
grant: ({ session, origin, expiresAt }: {
|
|
94
|
+
session: CreateSessionOptions;
|
|
95
|
+
origin: string;
|
|
96
|
+
expiresAt?: number;
|
|
97
|
+
}) => Promise<ClientAccess>;
|
|
98
|
+
revoke: (id: string) => Promise<void>;
|
|
99
|
+
};
|
|
80
100
|
readonly environments: {
|
|
101
|
+
application: (options: Omit<Parameters<typeof application>[0], "url" | "credential"> & {
|
|
102
|
+
credential?: string;
|
|
103
|
+
}) => import("@aexhq/brain").Environment;
|
|
81
104
|
http: () => Promise<import("./generated.js").HttpCatalog>;
|
|
82
105
|
list: () => Promise<EnvironmentCatalog>;
|
|
83
106
|
};
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export * from "@aexhq/brain";
|
|
2
2
|
export { AexSessionHandle } from "./session.js";
|
|
3
3
|
export { StructuredOutputError } from "./structured-output.js";
|
|
4
|
+
import { application } from "@aexhq/env-http";
|
|
5
|
+
import { composeApplication } from "./application.js";
|
|
4
6
|
import { Brain } from "@aexhq/brain";
|
|
5
7
|
import { AexSessionHandle } from "./session.js";
|
|
6
8
|
function nonnegativeInteger(value, name) {
|
|
@@ -25,14 +27,25 @@ class HostedBrain extends Brain {
|
|
|
25
27
|
}
|
|
26
28
|
export class Aex {
|
|
27
29
|
client;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
clientAccess;
|
|
31
|
+
constructor({ apiKey, accountToken, clientAccess, maxCostMicroUsd, ...options }) {
|
|
32
|
+
if ([apiKey, accountToken, clientAccess].filter(Boolean).length !== 1)
|
|
33
|
+
throw new TypeError("one apiKey, accountToken or clientAccess is required");
|
|
34
|
+
this.clientAccess = clientAccess;
|
|
35
|
+
this.client = new HostedBrain({ baseUrl: "https://api.aex.dev", ...options, token: apiKey ?? accountToken ?? clientAccess?.token,
|
|
36
|
+
...(clientAccess && { credentials: clientAccess.credentials }), maxCostMicroUsd });
|
|
37
|
+
}
|
|
38
|
+
composition(options) {
|
|
39
|
+
if (this.clientAccess && "apiKey" in options.model)
|
|
40
|
+
throw new TypeError("client access uses server-side model credentials; omit apiKey");
|
|
41
|
+
const model = this.clientAccess ? { ...options.model, apiKey: this.clientAccess.token } : options.model;
|
|
42
|
+
if (!("apiKey" in model) || typeof model.apiKey !== "string")
|
|
43
|
+
throw new TypeError("server-side sessions require a model apiKey");
|
|
44
|
+
return composeApplication({ ...options, model: { ...model, apiKey: model.apiKey } }, this.baseUrl);
|
|
32
45
|
}
|
|
33
46
|
get baseUrl() { return this.client.baseUrl; }
|
|
34
47
|
sessions = Object.freeze({
|
|
35
|
-
create: async (
|
|
48
|
+
create: async (options, operation) => new AexSessionHandle(await this.client.sessions.create(this.composition(options), operation)),
|
|
36
49
|
get: async (...args) => new AexSessionHandle(await this.client.sessions.get(...args)),
|
|
37
50
|
list: () => this.client.sessions.list(),
|
|
38
51
|
});
|
|
@@ -104,7 +117,20 @@ export class Aex {
|
|
|
104
117
|
refund: (input, idempotencyKey) => this.request("POST", "/v1/billing/refunds", input, idempotencyKey),
|
|
105
118
|
sync: (input) => this.request("POST", "/v1/billing/sync", input),
|
|
106
119
|
};
|
|
120
|
+
clients = {
|
|
121
|
+
grant: async ({ session, origin, expiresAt = Math.floor(Date.now() / 1000) + 3600 }) => {
|
|
122
|
+
if (this.clientAccess)
|
|
123
|
+
throw new TypeError("client grants require a backend API key");
|
|
124
|
+
const prepared = await this.client.sessions.prepare(this.composition(session), "authorized-client");
|
|
125
|
+
return this.request("POST", "/v1/clients", { origin, expires_at: expiresAt, session: prepared });
|
|
126
|
+
},
|
|
127
|
+
revoke: (id) => this.request("DELETE", `/v1/clients/${encodeURIComponent(id)}`),
|
|
128
|
+
};
|
|
107
129
|
environments = {
|
|
130
|
+
application: (options) => application({
|
|
131
|
+
...options, credential: options.credential ?? this.clientAccess?.token ?? "",
|
|
132
|
+
url: new URL("/environments/application", this.baseUrl).href,
|
|
133
|
+
}),
|
|
108
134
|
http: () => this.request("GET", "/v1/environments/http"),
|
|
109
135
|
list: () => this.request("GET", "/v1/environments"),
|
|
110
136
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aexhq/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.85.0",
|
|
4
4
|
"description": "Aex accounts and hosted sessions using the Brain SDK",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -28,8 +28,9 @@
|
|
|
28
28
|
"tag": "next"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@aexhq/brain": "0.
|
|
32
|
-
"zod": "4.4.3"
|
|
31
|
+
"@aexhq/brain": "0.35.1",
|
|
32
|
+
"zod": "4.4.3",
|
|
33
|
+
"@aexhq/env-http": "0.3.0"
|
|
33
34
|
},
|
|
34
35
|
"scripts": {
|
|
35
36
|
"gen": "node ../../tools/sdk-contracts.mjs",
|