@aexhq/sdk 0.62.1 → 0.63.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,24 @@
1
1
  # @aexhq/sdk
2
2
 
3
- TypeScript SDK for Aex sessions and tool extensions.
3
+ The hosted Aex client wraps the neutral `@aexhq/brain` HTTP SDK with an Aex API key and the
4
+ `https://api.aex.dev` base URL.
4
5
 
5
6
  ```ts
6
7
  import { Aex } from "@aexhq/sdk";
7
- import { awsMicrovm } from "@aexhq/env-aws-microvm";
8
- import { pi } from "@aexhq/loop-pi";
9
- import { openai } from "@aexhq/model-openai";
10
- import { bash, read, task, write } from "@aexhq/tools";
11
8
 
12
9
  const aex = new Aex({ apiKey: process.env.AEX_API_KEY! });
13
- const workspace = awsMicrovm();
14
-
15
10
  const session = await aex.sessions.create({
16
- model: {
17
- component: openai(),
18
- provider: "openai",
19
- name: "gpt-5.4",
20
- apiKey: process.env.OPENAI_API_KEY!,
21
- },
22
- agentloop: pi({ instructions: "Work carefully and verify changes." }),
23
- environments: { workspace },
24
- tools: [bash(), read(), write(), task()],
11
+ agentloop_digest,
12
+ model: { binding_id: "vercel-ai-gateway", model: "openai/gpt-5.4" },
13
+ presentation,
14
+ environments,
15
+ tool_bindings,
25
16
  });
26
17
 
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
- });
18
+ await session.send("Inspect the workspace.");
19
+ for await (const event of session.events()) console.log(event);
60
20
  ```
61
21
 
62
- Source callback Tools are routed automatically to the single `app()` Environment. Durable objects
63
- remain available through `session.storage`, independently of Environment lifetime.
22
+ Admit Agentloop packages through `aex.brain.admitAgentloop(...)`. Tool implementations remain in
23
+ their bound remote Environment; the SDK sends definitions and binding requests, not implementation
24
+ code.
package/dist/index.d.ts CHANGED
@@ -1,25 +1,18 @@
1
+ import { BrainClient, BrainError, type BrainOptions } from "@aexhq/brain";
1
2
  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";
3
+ export { BrainError as AexError } from "@aexhq/brain";
4
+ export { Session, Sessions } from "./session.js";
5
+ export type { RequestOptions } from "./session.js";
6
+ export type { AgentloopAdmission, CreateSessionRequest, EnvironmentRequirement, EventPage, SessionEvent, SessionList, ToolBinding, ToolDefinition, } from "@aexhq/brain";
14
7
  export interface AexOptions {
15
8
  apiKey: string;
16
9
  baseUrl?: string;
17
- fetch?: Fetch;
18
- webSocketFactory?: WebSocketFactory;
10
+ fetch?: BrainOptions["fetch"];
11
+ timeoutMs?: number;
19
12
  }
20
13
  export declare class Aex {
14
+ readonly brain: BrainClient;
21
15
  readonly sessions: Sessions;
22
16
  constructor(options: AexOptions);
23
- /** Stop customer-app execution permanently; this Aex instance cannot create another session. */
24
- close(): void;
25
17
  }
18
+ export { BrainError };
package/dist/index.js CHANGED
@@ -1,28 +1,21 @@
1
+ import { BrainClient, BrainError } from "@aexhq/brain";
1
2
  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";
3
+ export { BrainError as AexError } from "@aexhq/brain";
4
+ export { Session, Sessions } from "./session.js";
7
5
  const DEFAULT_API_URL = "https://api.aex.dev";
8
6
  export class Aex {
7
+ brain;
9
8
  sessions;
10
9
  constructor(options) {
11
10
  if (options.apiKey.trim() === "")
12
11
  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();
12
+ this.brain = new BrainClient({
13
+ baseUrl: options.baseUrl ?? DEFAULT_API_URL,
14
+ apiKey: options.apiKey,
15
+ ...(options.fetch === undefined ? {} : { fetch: options.fetch }),
16
+ ...(options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs }),
17
+ });
18
+ this.sessions = new Sessions(this.brain);
27
19
  }
28
20
  }
21
+ export { BrainError };
package/dist/session.d.ts CHANGED
@@ -1,137 +1,22 @@
1
- import type { Event, Session as BrainSessionData, SessionState } from "@aexhq/brain/session";
2
- import { type ComponentExtension, type SessionTool as ComponentSessionTool } from "@aexhq/brain";
3
- import type { NetworkPolicy, WebSocketFactory } from "@aexhq/brain";
4
- import * as z from "zod";
5
- import type { EventOptions } from "./transport.js";
6
- import { Transport } from "./transport.js";
7
- import { type Tool } from "./tools.js";
8
- import { SessionChildren, SessionSandbox, SessionStorage } from "./resources.js";
9
- type SessionData = BrainSessionData & {
10
- retain_until: string;
11
- };
12
- export type SessionInput = string;
13
- export interface ModelOptions {
14
- /** Imported Model component. */
15
- component: ComponentExtension<"model">;
16
- provider: string;
17
- name: string;
18
- apiKey: string;
19
- baseUrl?: string;
20
- maxOutputTokens?: number;
21
- }
22
- export interface CreateSessionOptions {
23
- model: ModelOptions;
24
- /** The imported agent loop that drives this session and every child unless spawn overrides it. */
25
- agentloop: ComponentExtension<"agentloop">;
26
- /** Omitted or empty grants no tools. A non-empty list is the exact grant. */
27
- environments?: Readonly<Record<string, ComponentExtension<"environment">>>;
28
- tools?: readonly (Tool | ComponentSessionTool)[];
29
- /** Write-only values for components that explicitly consume session secrets. */
30
- secrets?: Record<string, string>;
31
- /** Maximum direct outbound network authority sealed for managed sandboxes. Omission is deny-all. */
32
- network?: NetworkPolicy;
33
- /** Replacement attempts after an unrecoverable provider outcome. Defaults to one. */
34
- providerRecoveryRetries?: 0 | 1;
35
- /** Optional ceilings for durable child sessions. Omitted fields use the hosted defaults. */
36
- children?: {
37
- maxDepth?: number;
38
- maxDirectChildren?: number;
39
- maxDescendants?: number;
40
- };
41
- metadata?: Record<string, string>;
42
- /** Finite durable-history deadline. Omit to use the Brain deployment default. */
43
- retainUntil?: Date | string;
44
- }
1
+ import { BrainClient, SessionHandle, type CreateSessionRequest, type Session as SessionState, type SessionEvent } from "@aexhq/brain";
45
2
  export interface RequestOptions {
46
- signal?: AbortSignal;
47
3
  idempotencyKey?: string;
48
- metadata?: Record<string, string>;
49
- }
50
- export interface OutputOptions<Schema extends z.ZodType = z.ZodType> extends RequestOptions {
51
- output: Schema;
52
- /** Extra attempts after the first invalid candidate. Defaults to 1; maximum 2. */
53
- outputRetries?: 0 | 1 | 2;
54
- }
55
- export interface ListSessionsOptions {
56
- limit?: number;
57
- cursor?: string;
58
- state?: SessionState;
59
- signal?: AbortSignal;
60
- }
61
- export interface SessionList {
62
- data: Session[];
63
- hasMore: boolean;
64
- nextCursor?: string;
65
- }
66
- export interface ModelSummary {
67
- provider: string;
68
- name: string;
69
- baseUrl?: string;
70
- contextWindowTokens: number;
71
- }
72
- export interface SessionSummary {
73
- id: string;
74
- parentId: string | undefined;
75
- rootId: string;
76
- depth: number;
77
- state: SessionState;
78
- turnState: SessionData["turn_state"];
79
- model: ModelSummary;
80
- createdAt: string;
81
- updatedAt: string;
82
- retainUntil: string;
83
- metadata: Readonly<Record<string, string | undefined>>;
84
4
  }
85
5
  export declare class Sessions {
86
- #private;
87
- constructor(transport: Transport, webSocketFactory?: WebSocketFactory);
88
- /** @internal Called by `Aex.close()`. */
89
- close(): void;
90
- create(options: CreateSessionOptions, request?: RequestOptions): Promise<Session>;
91
- get(id: string, options?: Pick<RequestOptions, "signal">): Promise<Session>;
92
- list(options?: ListSessionsOptions): Promise<SessionList>;
93
- }
94
- export declare class Session implements SessionSummary {
95
- #private;
96
- readonly storage: SessionStorage;
97
- readonly children: SessionChildren;
98
- constructor(transport: Transport, data: SessionData);
99
- /** The Environment names this session sealed. Only these can be addressed. */
100
- get environments(): readonly string[];
101
- /** One sealed Environment addressed by the name the session declared it under. */
102
- environment(name: string): SessionSandbox;
103
- /** The session's default sandbox: the one Environment it declared. */
104
- get sandbox(): SessionSandbox;
105
- get id(): string;
6
+ private readonly brain;
7
+ constructor(brain: BrainClient);
8
+ create(request: CreateSessionRequest, options?: RequestOptions): Promise<Session>;
9
+ list(): Promise<Session[]>;
10
+ get(sessionId: string): Promise<Session>;
11
+ }
12
+ export declare class Session {
13
+ private readonly handle;
14
+ constructor(handle: SessionHandle);
106
15
  get state(): SessionState;
107
- get turnState(): SessionData["turn_state"];
108
- get parentId(): string | undefined;
109
- get rootId(): string;
110
- get depth(): number;
111
- get model(): ModelSummary;
112
- get createdAt(): string;
113
- get updatedAt(): string;
114
- get retainUntil(): string;
115
- get metadata(): Readonly<Record<string, string | undefined>>;
116
- refresh(options?: Pick<RequestOptions, "signal">): Promise<this>;
117
- send(input: SessionInput, options?: RequestOptions): Promise<string>;
118
- send<Schema extends z.ZodType>(input: SessionInput, options: OutputOptions<Schema>): Promise<z.output<Schema>>;
119
- /**
120
- * Raw, attempt-aware event stream. Provisional frames have no durable cursor and may later be
121
- * superseded; consumers rendering them must key by `attempt_id` and process
122
- * `model.attempt_superseded`. Use `send()` when only the durable winning answer is needed.
123
- */
124
- events(options?: EventOptions): AsyncGenerator<Event>;
125
- cancel(options?: Pick<RequestOptions, "signal">): Promise<this>;
126
- suspend(options?: Pick<RequestOptions, "signal">): Promise<this>;
127
- resume(options?: Pick<RequestOptions, "signal">): Promise<this>;
128
- setRetention(value: Date | string, options?: Pick<RequestOptions, "signal"> & {
129
- allowShorten?: boolean;
130
- }): Promise<this>;
131
- end(options?: Pick<RequestOptions, "signal">): Promise<this>;
132
- delete(options?: Pick<RequestOptions, "signal"> & {
133
- queue?: boolean;
134
- }): Promise<void>;
135
- private markIdle;
16
+ get id(): string;
17
+ send(content: unknown, options?: RequestOptions): Promise<SessionState>;
18
+ events(after?: number): AsyncIterable<SessionEvent>;
19
+ cancel(options?: RequestOptions): Promise<void>;
20
+ end(options?: RequestOptions): Promise<SessionState>;
21
+ delete(options?: RequestOptions): Promise<void>;
136
22
  }
137
- export {};