@aexhq/sdk 0.62.1 → 0.64.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 CHANGED
@@ -1,63 +1,29 @@
1
1
  # @aexhq/sdk
2
2
 
3
- TypeScript SDK for Aex sessions and tool extensions.
3
+ The hosted Aex client uses the neutral Brain composition API with the `https://api.aex.dev` base
4
+ URL and an Aex API key.
4
5
 
5
6
  ```ts
6
7
  import { Aex } from "@aexhq/sdk";
7
- import { awsMicrovm } from "@aexhq/env-aws-microvm";
8
+ import { awsMicroVm } from "@aexhq/env-aws-microvm";
8
9
  import { pi } from "@aexhq/loop-pi";
9
- import { openai } from "@aexhq/model-openai";
10
- import { bash, read, task, write } from "@aexhq/tools";
10
+ import { bash, read } from "@aexhq/tools";
11
11
 
12
12
  const aex = new Aex({ apiKey: process.env.AEX_API_KEY! });
13
- const workspace = awsMicrovm();
14
-
15
- const session = await aex.sessions.create({
13
+ const workspace = awsMicroVm({ region: "eu-west-2" });
14
+ const session = await aex.createSession({
16
15
  model: {
17
- component: openai(),
18
- provider: "openai",
19
- name: "gpt-5.4",
20
- apiKey: process.env.OPENAI_API_KEY!,
16
+ provider: "vercel-ai-gateway",
17
+ name: "openai/gpt-5-mini",
18
+ apiKey: process.env.VERCEL_AI_GATEWAY_API_KEY!,
21
19
  },
22
- agentloop: pi({ instructions: "Work carefully and verify changes." }),
23
- environments: { workspace },
24
- tools: [bash(), read(), write(), task()],
20
+ agentLoop: pi(),
21
+ tools: [read().runIn(workspace), bash().runIn(workspace)],
25
22
  });
26
23
 
27
- console.log(await session.send("Inspect the workspace."));
28
- ```
29
-
30
- There is no default Agentloop, Model, Tool, or Environment. A Tool component that requests the
31
- Environment capability requires the session's one declared Environment in the MVP.
32
-
33
- ## Application Tools
34
-
35
- Application callbacks use the same Tool and Environment component ABI while the handler remains in
36
- your process. Declare one `app()` Environment; Aex registers each selected callback over one
37
- authenticated, reconnecting connection. Handler source and captured application state are never
38
- uploaded to Brain.
39
-
40
- ```ts
41
- import { Aex, tool } from "@aexhq/sdk";
42
- import { app } from "@aexhq/env-app";
43
- import { z } from "zod";
44
-
45
- const lookupOrder = tool(
46
- z.object({ orderId: z.string() }),
47
- async function lookupOrder({ orderId }) {
48
- return database.lookup(orderId);
49
- },
50
- )
51
- .describe("Look up an order")
52
- .returns(z.object({ status: z.string() }));
53
-
54
- await new Aex({ apiKey: process.env.AEX_API_KEY! }).sessions.create({
55
- model,
56
- agentloop,
57
- environments: { application: app({ id: "orders-ui" }) },
58
- tools: [lookupOrder],
59
- });
24
+ await session.send("Inspect the workspace.");
25
+ for await (const event of session.events()) console.log(event);
60
26
  ```
61
27
 
62
- Source callback Tools are routed automatically to the single `app()` Environment. Durable objects
63
- remain available through `session.storage`, independently of Environment lifetime.
28
+ Aex supplies hosted authentication and policy. Agentloop admission, Tool placement, Environment
29
+ requirements, operation keys, and event cursors are handled by the shared Brain SDK.
package/dist/index.d.ts CHANGED
@@ -1,25 +1,12 @@
1
- import { Sessions } from "./session.js";
2
- import type { Fetch } from "./transport.js";
3
- import type { WebSocketFactory } from "@aexhq/brain";
4
- export { AbortError, AexError, OutputRefusalError, OutputSchemaError, OutputValidationError, SessionError, } from "./errors.js";
5
- export type { AexErrorOptions, OutputValidationIssue } from "./errors.js";
6
- export { Session, Sessions, } from "./session.js";
7
- export type { CreateSessionOptions, ListSessionsOptions, ModelSummary, ModelOptions, OutputOptions, RequestOptions, SessionInput, SessionList, SessionSummary, } from "./session.js";
8
- export { SessionChild, SessionChildren, SessionStorage, } from "./resources.js";
9
- export type { BinarySource, ChildSummary, IdempotentOperationOptions, OperationOptions, PageOptions, StorageObject, StoragePage, StreamingUploadSource, UploadSource, } from "./resources.js";
10
- export type { EventOptions } from "./transport.js";
11
- export { tool } from "./tools.js";
12
- export type { Tool, ToolContract, ToolContext, ToolHandler, } from "./tools.js";
13
- export type { NetworkPolicy, WebSocketFactory } from "@aexhq/brain";
1
+ import { Brain, type BrainOptions } from "@aexhq/brain";
2
+ export { BrainError as AexError } from "@aexhq/brain";
3
+ export type { AgentLoop, BoundTool, CreateSessionOptions, Environment, EnvironmentLifecycle, OperationOptions, SessionEvent, SessionState, Tool, ToolBindingOptions, ToolDefinition, VercelAiGatewayModel, } from "@aexhq/brain";
14
4
  export interface AexOptions {
15
5
  apiKey: string;
16
6
  baseUrl?: string;
17
- fetch?: Fetch;
18
- webSocketFactory?: WebSocketFactory;
7
+ fetch?: BrainOptions["fetch"];
8
+ timeoutMs?: number;
19
9
  }
20
- export declare class Aex {
21
- readonly sessions: Sessions;
10
+ export declare class Aex extends Brain {
22
11
  constructor(options: AexOptions);
23
- /** Stop customer-app execution permanently; this Aex instance cannot create another session. */
24
- close(): void;
25
12
  }
package/dist/index.js CHANGED
@@ -1,28 +1,15 @@
1
- import { Sessions } from "./session.js";
2
- import { Transport } from "./transport.js";
3
- export { AbortError, AexError, OutputRefusalError, OutputSchemaError, OutputValidationError, SessionError, } from "./errors.js";
4
- export { Session, Sessions, } from "./session.js";
5
- export { SessionChild, SessionChildren, SessionStorage, } from "./resources.js";
6
- export { tool } from "./tools.js";
1
+ import { Brain } from "@aexhq/brain";
2
+ export { BrainError as AexError } from "@aexhq/brain";
7
3
  const DEFAULT_API_URL = "https://api.aex.dev";
8
- export class Aex {
9
- sessions;
4
+ export class Aex extends Brain {
10
5
  constructor(options) {
11
6
  if (options.apiKey.trim() === "")
12
7
  throw new TypeError("Aex apiKey cannot be empty");
13
- const fetchImplementation = options.fetch ?? globalThis.fetch?.bind(globalThis);
14
- if (fetchImplementation === undefined) {
15
- throw new TypeError("This runtime does not provide fetch; pass a fetch implementation to Aex");
16
- }
17
- const transport = new Transport(options.apiKey, options.baseUrl ?? DEFAULT_API_URL, fetchImplementation);
18
- const webSocketFactory = options.webSocketFactory ??
19
- (globalThis.WebSocket === undefined
20
- ? undefined
21
- : (request) => new globalThis.WebSocket(request.url, request.protocol));
22
- this.sessions = new Sessions(transport, webSocketFactory);
23
- }
24
- /** Stop customer-app execution permanently; this Aex instance cannot create another session. */
25
- close() {
26
- this.sessions.close();
8
+ super({
9
+ baseUrl: options.baseUrl ?? DEFAULT_API_URL,
10
+ token: options.apiKey,
11
+ ...(options.fetch === undefined ? {} : { fetch: options.fetch }),
12
+ ...(options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs }),
13
+ });
27
14
  }
28
15
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aexhq/sdk",
3
- "version": "0.62.1",
3
+ "version": "0.64.0",
4
4
  "description": "TypeScript SDK for Aex sessions",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://aex.dev",
@@ -34,14 +34,9 @@
34
34
  "test": "tsc -p tsconfig.json && node --test"
35
35
  },
36
36
  "dependencies": {
37
- "@aexhq/brain": "0.5.0",
38
- "@aexhq/env-app": "0.3.2"
39
- },
40
- "peerDependencies": {
41
- "zod": "4.4.3"
37
+ "@aexhq/brain": "0.7.0"
42
38
  },
43
39
  "devDependencies": {
44
- "typescript": "^5.9.2",
45
- "zod": "4.4.3"
40
+ "typescript": "^5.9.2"
46
41
  }
47
42
  }
package/dist/errors.d.ts DELETED
@@ -1,39 +0,0 @@
1
- import type { ApiError, ApiErrorCode } from "@aexhq/brain/session";
2
- /** One Aex trusted-output validation failure, expressed as a JSON Pointer. */
3
- export interface OutputValidationIssue {
4
- path: string;
5
- message: string;
6
- keyword?: string;
7
- }
8
- export interface AexErrorOptions {
9
- code?: ApiErrorCode | undefined;
10
- status?: number | undefined;
11
- param?: string | undefined;
12
- requestId?: string | undefined;
13
- cause?: unknown;
14
- }
15
- export declare class AexError extends Error {
16
- readonly code: ApiErrorCode | undefined;
17
- readonly status: number | undefined;
18
- readonly param: string | undefined;
19
- readonly requestId: string | undefined;
20
- constructor(message: string, options?: AexErrorOptions);
21
- }
22
- export declare class OutputSchemaError extends AexError {
23
- constructor(message: string, options?: AexErrorOptions);
24
- }
25
- export declare class OutputRefusalError extends AexError {
26
- constructor(message: string, options?: AexErrorOptions);
27
- }
28
- export declare class OutputValidationError extends AexError {
29
- readonly issues: readonly OutputValidationIssue[];
30
- constructor(message: string, issues?: readonly OutputValidationIssue[], options?: AexErrorOptions);
31
- }
32
- export declare class SessionError extends AexError {
33
- constructor(message: string, options?: AexErrorOptions);
34
- }
35
- export declare class AbortError extends AexError {
36
- constructor(message?: string, options?: AexErrorOptions);
37
- }
38
- export declare function errorFromApi(error: ApiError, status?: number, issues?: readonly OutputValidationIssue[]): AexError;
39
- export declare function abortError(cause?: unknown): AbortError;
package/dist/errors.js DELETED
@@ -1,69 +0,0 @@
1
- export class AexError extends Error {
2
- code;
3
- status;
4
- param;
5
- requestId;
6
- constructor(message, options = {}) {
7
- super(message, options.cause === undefined ? undefined : { cause: options.cause });
8
- this.name = "AexError";
9
- this.code = options.code;
10
- this.status = options.status;
11
- this.param = options.param;
12
- this.requestId = options.requestId;
13
- }
14
- }
15
- export class OutputSchemaError extends AexError {
16
- constructor(message, options = {}) {
17
- super(message, { ...options, code: "output_schema_error" });
18
- this.name = "OutputSchemaError";
19
- }
20
- }
21
- export class OutputRefusalError extends AexError {
22
- constructor(message, options = {}) {
23
- super(message, { ...options, code: "output_refused" });
24
- this.name = "OutputRefusalError";
25
- }
26
- }
27
- export class OutputValidationError extends AexError {
28
- issues;
29
- constructor(message, issues = [], options = {}) {
30
- super(message, { ...options, code: "output_validation_error" });
31
- this.name = "OutputValidationError";
32
- this.issues = issues;
33
- }
34
- }
35
- export class SessionError extends AexError {
36
- constructor(message, options = {}) {
37
- super(message, options);
38
- this.name = "SessionError";
39
- }
40
- }
41
- export class AbortError extends AexError {
42
- constructor(message = "The operation was cancelled", options = {}) {
43
- super(message, { ...options, code: "cancelled" });
44
- this.name = "AbortError";
45
- }
46
- }
47
- export function errorFromApi(error, status, issues = []) {
48
- const options = {
49
- code: error.code,
50
- status,
51
- param: error.param,
52
- requestId: error.request_id,
53
- };
54
- switch (error.code) {
55
- case "output_schema_error":
56
- return new OutputSchemaError(error.message, options);
57
- case "output_refused":
58
- return new OutputRefusalError(error.message, options);
59
- case "output_validation_error":
60
- return new OutputValidationError(error.message, issues, options);
61
- case "cancelled":
62
- return new AbortError(error.message, options);
63
- default:
64
- return new SessionError(error.message, options);
65
- }
66
- }
67
- export function abortError(cause) {
68
- return new AbortError("The operation was cancelled", { cause });
69
- }
package/dist/json.d.ts DELETED
@@ -1,4 +0,0 @@
1
- /** RFC 8785 canonical JSON. Object keys sort by UTF-16 code units, as required by JCS. */
2
- export declare function canonicalize(value: unknown): string;
3
- export declare function jcsSha256(value: unknown): Promise<string>;
4
- export declare function randomIdempotencyKey(): string;
package/dist/json.js DELETED
@@ -1,46 +0,0 @@
1
- import { OutputSchemaError, SessionError } from "./errors.js";
2
- /** RFC 8785 canonical JSON. Object keys sort by UTF-16 code units, as required by JCS. */
3
- export function canonicalize(value) {
4
- const visit = (current) => {
5
- if (Array.isArray(current))
6
- return current.map(visit);
7
- if (current !== null && typeof current === "object") {
8
- const object = current;
9
- return Object.fromEntries(Object.keys(object)
10
- .filter((key) => object[key] !== undefined)
11
- .sort()
12
- .map((key) => [key, visit(object[key])]));
13
- }
14
- if (typeof current === "number" && !Number.isFinite(current)) {
15
- throw new OutputSchemaError("The output schema contains a non-finite number");
16
- }
17
- return current;
18
- };
19
- const encoded = JSON.stringify(visit(value));
20
- if (encoded === undefined) {
21
- throw new OutputSchemaError("The output schema is not JSON-serialisable");
22
- }
23
- return encoded;
24
- }
25
- export async function jcsSha256(value) {
26
- const subtle = globalThis.crypto?.subtle;
27
- if (subtle === undefined) {
28
- throw new OutputSchemaError("This runtime does not provide Web Crypto SHA-256 support");
29
- }
30
- const bytes = new TextEncoder().encode(canonicalize(value));
31
- const digest = await subtle.digest("SHA-256", bytes);
32
- return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
33
- }
34
- export function randomIdempotencyKey() {
35
- const crypto = globalThis.crypto;
36
- if (crypto === undefined) {
37
- throw new SessionError("This runtime does not provide secure random values");
38
- }
39
- if (typeof crypto.randomUUID === "function")
40
- return crypto.randomUUID();
41
- const bytes = crypto.getRandomValues(new Uint8Array(16));
42
- bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;
43
- bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;
44
- const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0"));
45
- return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex.slice(6, 8).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
46
- }
@@ -1,162 +0,0 @@
1
- import { SessionChildren as BrainChildren, SessionSandbox as BrainSandbox } from "@aexhq/brain";
2
- import type { SandboxFileEntry as BrainSandboxFileEntry, SandboxStatus as BrainSandboxStatus } from "@aexhq/brain";
3
- import type { Event, Session as BrainSession } from "@aexhq/brain/session";
4
- import type { EventOptions } from "./transport.js";
5
- import { Transport } from "./transport.js";
6
- export type BinarySource = string | ArrayBuffer | ArrayBufferView | Blob;
7
- /** A replayable, length- and digest-declared source for O(1)-heap large uploads. */
8
- export interface StreamingUploadSource {
9
- readonly bytes: number;
10
- readonly sha256: string;
11
- stream(): ReadableStream<Uint8Array>;
12
- }
13
- export type UploadSource = BinarySource | StreamingUploadSource;
14
- export interface OperationOptions {
15
- signal?: AbortSignal;
16
- }
17
- export interface IdempotentOperationOptions extends OperationOptions {
18
- /** Stable retry identity; the SDK generates one when omitted. */
19
- idempotencyKey?: string;
20
- }
21
- export interface PageOptions extends OperationOptions {
22
- cursor?: string;
23
- limit?: number;
24
- }
25
- export interface SandboxStatus {
26
- state: BrainSandboxStatus["state"];
27
- generation?: string;
28
- reason?: string;
29
- changedAt?: string;
30
- expiresAt?: string;
31
- }
32
- export interface SandboxFile {
33
- path: string;
34
- kind: BrainSandboxFileEntry["kind"];
35
- bytes: number;
36
- sha256?: string;
37
- modifiedAt: string;
38
- }
39
- export interface SandboxFilePage {
40
- data: SandboxFile[];
41
- hasMore: boolean;
42
- nextCursor?: string;
43
- generation: string;
44
- }
45
- export interface SandboxFileOptions extends OperationOptions {
46
- generation: string;
47
- }
48
- export interface SandboxFilePageOptions extends SandboxFileOptions, PageOptions {
49
- }
50
- export declare class SandboxFiles {
51
- #private;
52
- constructor(inner: BrainSandbox["files"], transport: Transport);
53
- list(path: string, options: SandboxFilePageOptions): Promise<SandboxFilePage>;
54
- stat(path: string, options: SandboxFileOptions): Promise<SandboxFile>;
55
- download(path: string, options: SandboxFileOptions): Promise<Uint8Array>;
56
- downloadStream(path: string, options: SandboxFileOptions): Promise<ReadableStream<Uint8Array>>;
57
- upload(path: string, source: UploadSource, options: SandboxFileOptions & {
58
- overwrite?: boolean;
59
- }): Promise<SandboxFile>;
60
- find(input: {
61
- path: string;
62
- glob: string;
63
- }, options: SandboxFilePageOptions): Promise<SandboxFilePage>;
64
- grep(input: {
65
- path: string;
66
- query: string;
67
- }, options: SandboxFilePageOptions): Promise<SandboxFilePage>;
68
- }
69
- export declare class SessionSandbox {
70
- #private;
71
- readonly files: SandboxFiles;
72
- constructor(transport: Transport, sessionId: string, environment: string);
73
- /** The declared Environment name this sandbox addresses. */
74
- get environment(): string;
75
- status(options?: OperationOptions): Promise<SandboxStatus>;
76
- create(options?: OperationOptions): Promise<SandboxStatus>;
77
- }
78
- export interface StorageObject {
79
- key: string;
80
- bytes: number;
81
- sha256: string;
82
- contentType?: string;
83
- createdAt: string;
84
- updatedAt: string;
85
- }
86
- export interface StoragePage {
87
- data: StorageObject[];
88
- hasMore: boolean;
89
- nextCursor?: string;
90
- }
91
- export declare class SessionStorage {
92
- #private;
93
- constructor(transport: Transport, sessionId: string);
94
- list(options?: PageOptions & {
95
- prefix?: string;
96
- }): Promise<StoragePage>;
97
- stat(key: string, options?: OperationOptions): Promise<StorageObject>;
98
- download(key: string, options?: OperationOptions): Promise<Uint8Array>;
99
- downloadStream(key: string, options?: OperationOptions): Promise<ReadableStream<Uint8Array>>;
100
- upload(key: string, source: UploadSource, options?: OperationOptions & {
101
- contentType?: string;
102
- overwrite?: boolean;
103
- }): Promise<StorageObject>;
104
- delete(key: string, options?: OperationOptions): Promise<void>;
105
- copyFromSandbox(input: {
106
- environment: string;
107
- key: string;
108
- path: string;
109
- sandboxGeneration: string;
110
- overwrite?: boolean;
111
- }, options?: OperationOptions): Promise<StorageObject>;
112
- copyToSandbox(input: {
113
- environment: string;
114
- key: string;
115
- path: string;
116
- sandboxGeneration: string;
117
- overwrite?: boolean;
118
- }, options?: OperationOptions): Promise<SandboxFile>;
119
- }
120
- export interface ChildSummary {
121
- id: string;
122
- parentId: string;
123
- rootId: string;
124
- name?: string;
125
- depth: number;
126
- state: BrainSession["state"];
127
- turnState: BrainSession["turn_state"];
128
- turnPhase?: string;
129
- shape: BrainSession["shape"];
130
- createdAt: string;
131
- updatedAt: string;
132
- }
133
- export declare class SessionChild {
134
- #private;
135
- constructor(inner: ReturnType<BrainChildren["get"]>);
136
- get id(): string;
137
- info(options?: OperationOptions): Promise<ChildSummary>;
138
- send(message: string, options?: IdempotentOperationOptions): Promise<void>;
139
- followUp(message: string, options?: IdempotentOperationOptions): Promise<ChildSummary>;
140
- wait(options?: OperationOptions & {
141
- timeoutMs?: number;
142
- }): Promise<ChildSummary>;
143
- interrupt(options?: OperationOptions): Promise<ChildSummary>;
144
- end(options?: OperationOptions): Promise<ChildSummary>;
145
- events(options?: EventOptions): AsyncGenerator<Event>;
146
- }
147
- export declare class SessionChildren {
148
- #private;
149
- constructor(transport: Transport, sessionId: string);
150
- create(input: {
151
- prompt: string;
152
- name?: string;
153
- forkTurns?: "all" | "none" | `${number}`;
154
- }, options?: IdempotentOperationOptions): Promise<SessionChild>;
155
- list(options?: PageOptions): Promise<{
156
- data: ChildSummary[];
157
- hasMore: boolean;
158
- nextCursor?: string;
159
- }>;
160
- get(childId: string): SessionChild;
161
- }
162
- export declare function encodeBase64(bytes: Uint8Array): string;