agentxjs 2.1.0 → 2.2.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,84 +1,80 @@
1
1
  # agentxjs
2
2
 
3
- Client SDK for building AI agent applications. Supports local (embedded) and remote (WebSocket) modes through a single unified API.
4
-
5
- ## Overview
6
-
7
- `agentxjs` is the main SDK that developers use directly. It auto-detects the mode based on config: provide `apiKey` for local mode (no server needed), or `serverUrl` for remote mode (connects to an AgentX server over WebSocket).
3
+ Client SDK for building AI agent applications. Supports local, remote, and server modes through a unified fluent API.
8
4
 
9
5
  ## Quick Start
10
6
 
11
- ### When to use which mode?
12
-
13
- | | Local Mode | Remote Mode |
14
- | ------------- | ----------------------------------------------- | ------------------------------------------------------------ |
15
- | **Use when** | Prototyping, CLI tools, single-user apps, tests | Multi-tenant apps, shared infrastructure, horizontal scaling |
16
- | **Trade-off** | Simpler setup, no server to manage | Centralized state, multiple clients can share agents |
17
- | **Data** | In-process SQLite (or `:memory:`) | Server-managed persistent storage |
18
- | **Config** | `apiKey` | `serverUrl` |
19
-
20
- **Start with Local mode.** Switch to Remote when you need multiple processes or users sharing the same agents.
21
-
22
7
  ### Local Mode (Embedded)
23
8
 
24
9
  Runs agents directly in your process. No server required.
25
10
 
26
11
  ```typescript
27
12
  import { createAgentX } from "agentxjs";
13
+ import { nodePlatform } from "@agentxjs/node-platform";
14
+ import { createMonoDriver } from "@agentxjs/mono-driver";
28
15
 
29
- const agentx = await createAgentX({
16
+ const createDriver = (config) => createMonoDriver({
17
+ ...config,
30
18
  apiKey: process.env.ANTHROPIC_API_KEY,
31
- provider: "anthropic",
19
+ options: { provider: "anthropic" },
32
20
  });
33
21
 
34
- await agentx.containers.create("my-app");
22
+ const ax = createAgentX(nodePlatform({ createDriver }));
23
+
24
+ await ax.container.create("my-app");
35
25
 
36
- const { record: image } = await agentx.images.create({
26
+ const { record: image } = await ax.image.create({
37
27
  containerId: "my-app",
38
28
  systemPrompt: "You are a helpful assistant.",
39
29
  });
40
30
 
41
- const { agentId } = await agentx.agents.create({ imageId: image.imageId });
31
+ const { agentId } = await ax.agent.create({ imageId: image.imageId });
42
32
 
43
- agentx.on("text_delta", (e) => process.stdout.write(e.data.text));
44
- await agentx.sessions.send(agentId, "Hello!");
33
+ ax.on("text_delta", (e) => process.stdout.write(e.data.text));
34
+ await ax.session.send(agentId, "Hello!");
45
35
  ```
46
36
 
47
- ### Remote Mode (WebSocket)
37
+ ### Remote Mode (WebSocket Client)
48
38
 
49
39
  Connects to a running AgentX server. Same API surface.
50
40
 
51
41
  ```typescript
52
42
  import { createAgentX } from "agentxjs";
53
43
 
54
- const agentx = await createAgentX({
55
- serverUrl: "ws://localhost:5200",
56
- });
44
+ const ax = createAgentX();
45
+ const client = await ax.connect("ws://localhost:5200");
57
46
 
58
- // Identical API as local mode
59
- await agentx.containers.create("my-app");
60
- const { record: image } = await agentx.images.create({
47
+ await client.container.create("my-app");
48
+ const { record: image } = await client.image.create({
61
49
  containerId: "my-app",
62
50
  systemPrompt: "You are a helpful assistant.",
63
51
  });
64
- const { agentId } = await agentx.agents.create({ imageId: image.imageId });
52
+ const { agentId } = await client.agent.create({ imageId: image.imageId });
53
+
54
+ client.on("text_delta", (e) => process.stdout.write(e.data.text));
55
+ await client.session.send(agentId, "Hello!");
56
+ ```
57
+
58
+ ### Server Mode
59
+
60
+ Start an AgentX WebSocket server for remote clients.
61
+
62
+ ```typescript
63
+ import { createAgentX } from "agentxjs";
64
+ import { nodePlatform } from "@agentxjs/node-platform";
65
65
 
66
- agentx.on("text_delta", (e) => process.stdout.write(e.data.text));
67
- await agentx.sessions.send(agentId, "Hello!");
66
+ const ax = createAgentX(nodePlatform({ createDriver }));
67
+ const server = await ax.serve({ port: 5200 });
68
68
  ```
69
69
 
70
70
  ## API Reference
71
71
 
72
- ### `createAgentX(config: AgentXConfig): Promise<AgentX>`
72
+ ### `createAgentX(config?): AgentXBuilder`
73
73
 
74
- Creates an AgentX client. Mode is auto-detected:
74
+ Creates an AgentX builder. Synchronous returns immediately.
75
75
 
76
- | Config field | Mode | Trigger |
77
- | ---------------- | ------ | --------------------------------------- |
78
- | `serverUrl` | Remote | Connects via WebSocket |
79
- | `apiKey` | Local | Starts embedded runtime with MonoDriver |
80
- | `createDriver` | Local | Uses custom driver factory |
81
- | `customPlatform` | Local | Uses custom platform |
76
+ - **With config** (PlatformConfig): Local mode + `connect()` + `serve()`
77
+ - **Without config**: Only `connect()` available
82
78
 
83
79
  ### AgentX Interface
84
80
 
@@ -88,53 +84,118 @@ interface AgentX {
88
84
  readonly events: EventBus;
89
85
 
90
86
  // Namespaced operations
91
- readonly containers: ContainerNamespace;
92
- readonly images: ImageNamespace;
93
- readonly agents: AgentNamespace;
94
- readonly sessions: SessionNamespace;
95
- readonly presentations: PresentationNamespace;
87
+ readonly container: ContainerNamespace;
88
+ readonly image: ImageNamespace;
89
+ readonly agent: AgentNamespace;
90
+ readonly session: SessionNamespace;
91
+ readonly presentation: PresentationNamespace;
92
+
93
+ // Universal RPC
94
+ rpc<T = unknown>(method: string, params?: unknown): Promise<T>;
96
95
 
97
96
  // Event subscription
98
97
  on<T extends string>(type: T, handler: BusEventHandler): Unsubscribe;
99
98
  onAny(handler: BusEventHandler): Unsubscribe;
100
99
  subscribe(sessionId: string): void;
101
100
 
101
+ // Error handling
102
+ onError(handler: (error: AgentXError) => void): Unsubscribe;
103
+
102
104
  // Lifecycle
103
105
  disconnect(): Promise<void>;
104
106
  dispose(): Promise<void>;
105
107
  }
108
+
109
+ interface AgentXBuilder extends AgentX {
110
+ connect(serverUrl: string, options?: ConnectOptions): Promise<AgentX>;
111
+ serve(config?: ServeConfig): Promise<AgentXServer>;
112
+ }
106
113
  ```
107
114
 
108
115
  ### Namespace Operations
109
116
 
110
- **containers**:
117
+ **container**:
111
118
 
112
119
  - `create(containerId: string): Promise<ContainerCreateResponse>`
113
120
  - `get(containerId: string): Promise<ContainerGetResponse>`
114
121
  - `list(): Promise<ContainerListResponse>`
115
122
 
116
- **images**:
123
+ **image**:
117
124
 
118
- - `create(params: { containerId, name?, description?, systemPrompt?, mcpServers? }): Promise<ImageCreateResponse>`
125
+ - `create(params: { containerId, name?, description?, systemPrompt?, mcpServers?, customData? }): Promise<ImageCreateResponse>`
119
126
  - `get(imageId: string): Promise<ImageGetResponse>`
120
127
  - `list(containerId?: string): Promise<ImageListResponse>`
128
+ - `update(imageId: string, updates: { name?, description?, customData? }): Promise<ImageUpdateResponse>`
121
129
  - `delete(imageId: string): Promise<BaseResponse>`
130
+ - `getMessages(imageId: string): Promise<Message[]>`
122
131
 
123
- **agents**:
132
+ **agent**:
124
133
 
125
134
  - `create(params: { imageId, agentId? }): Promise<AgentCreateResponse>`
126
135
  - `get(agentId: string): Promise<AgentGetResponse>`
127
136
  - `list(containerId?: string): Promise<AgentListResponse>`
128
137
  - `destroy(agentId: string): Promise<BaseResponse>`
129
138
 
130
- **sessions**:
139
+ **session**:
131
140
 
132
141
  - `send(agentId: string, content: string | unknown[]): Promise<MessageSendResponse>`
133
142
  - `interrupt(agentId: string): Promise<BaseResponse>`
143
+ - `getMessages(agentId: string): Promise<Message[]>`
144
+
145
+ **presentation**:
146
+
147
+ - `create(agentId: string, options?: PresentationOptions): Promise<Presentation>`
148
+
149
+ ### Universal RPC
150
+
151
+ Transport-agnostic JSON-RPC entry point. Works in all modes — local dispatches to CommandHandler, remote forwards via WebSocket.
152
+
153
+ ```typescript
154
+ // Equivalent to ax.container.create("default")
155
+ await ax.rpc("container.create", { containerId: "default" });
156
+
157
+ // Equivalent to ax.image.list()
158
+ const { records } = await ax.rpc<{ records: ImageRecord[] }>("image.list");
159
+
160
+ // Useful for custom transport (e.g. Cloudflare Workers/DO)
161
+ const response = await ax.rpc(request.method, request.params);
162
+ ```
163
+
164
+ ### Error Handling
165
+
166
+ Top-level error handler — receives structured `AgentXError` from all layers (driver, persistence, connection, runtime). Independent of stream events and Presentation API.
167
+
168
+ ```typescript
169
+ import { AgentXError } from "agentxjs";
170
+
171
+ ax.onError((error) => {
172
+ console.error(`[${error.category}] ${error.code}: ${error.message}`);
134
173
 
135
- **presentations**:
174
+ if (error.code === "CIRCUIT_OPEN") {
175
+ // Too many consecutive LLM failures — stop sending requests
176
+ }
136
177
 
137
- - `create(agentId: string, options?: PresentationOptions): Presentation`
178
+ if (error.code === "PERSISTENCE_FAILED") {
179
+ // Message failed to save — conversation continues but data may be lost
180
+ }
181
+
182
+ if (!error.recoverable) {
183
+ // Fatal error — consider restarting the agent
184
+ }
185
+ });
186
+ ```
187
+
188
+ **AgentXError properties:**
189
+
190
+ | Property | Type | Description |
191
+ | ------------- | -------- | ------------------------------------ |
192
+ | `code` | string | Error code (e.g. `PERSISTENCE_FAILED`) |
193
+ | `category` | string | `"driver"` \| `"persistence"` \| `"connection"` \| `"runtime"` |
194
+ | `recoverable` | boolean | Whether the caller should retry |
195
+ | `context` | object | `{ agentId?, sessionId?, imageId? }` |
196
+ | `cause` | Error? | Original error |
197
+
198
+ **Built-in circuit breaker:** After 5 consecutive driver failures, the circuit opens and rejects new requests. After 30s cooldown, one probe request is allowed through. Success closes the circuit.
138
199
 
139
200
  ### Stream Events
140
201
 
@@ -150,36 +211,24 @@ interface AgentX {
150
211
 
151
212
  ### Presentation API
152
213
 
153
- High-level UI state management. Aggregates raw stream events into a structured conversation state.
214
+ High-level UI state management. Aggregates raw stream events into structured conversation state.
154
215
 
155
216
  ```typescript
156
- const presentation = await agentx.presentations.create(agentId, {
157
- onUpdate: (state: PresentationState) => renderUI(state),
217
+ const presentation = await ax.presentation.create(agentId, {
218
+ onUpdate: (state) => {
219
+ // state.conversations — completed messages (includes history)
220
+ // state.streaming — current streaming response (or null)
221
+ // state.status — "idle" | "thinking" | "responding" | "executing"
222
+ renderUI(state);
223
+ },
158
224
  onError: (error) => console.error(error),
159
225
  });
160
- // For existing sessions, getState() already contains conversation history
161
226
 
162
227
  await presentation.send("What is the weather?");
163
228
  const state = presentation.getState();
164
- // state.conversations -- completed conversations (includes history)
165
- // state.streaming -- current streaming response (or null)
166
- // state.status -- "idle" | "thinking" | "responding" | "executing"
167
-
168
229
  presentation.dispose();
169
230
  ```
170
231
 
171
- **PresentationState**:
172
-
173
- ```typescript
174
- interface PresentationState {
175
- conversations: Conversation[]; // UserConversation | AssistantConversation | ErrorConversation
176
- streaming: AssistantConversation | null;
177
- status: "idle" | "thinking" | "responding" | "executing";
178
- }
179
- ```
180
-
181
- **Block types**: `TextBlock { type: "text", content }`, `ToolBlock { type: "tool", toolName, status, ... }`, `ImageBlock { type: "image", url }`
182
-
183
232
  For custom state management, use the exported reducer:
184
233
 
185
234
  ```typescript
@@ -189,69 +238,3 @@ let state = createInitialState();
189
238
  state = addUserConversation(state, "Hello");
190
239
  state = presentationReducer(state, event); // pure function
191
240
  ```
192
-
193
- ## Configuration
194
-
195
- ### AgentXConfig
196
-
197
- ```typescript
198
- interface AgentXConfig {
199
- // --- Local Mode ---
200
- apiKey?: string; // LLM provider API key
201
- provider?: LLMProvider; // default: "anthropic"
202
- model?: string; // e.g. "claude-sonnet-4-20250514"
203
- baseUrl?: string; // custom API endpoint
204
- dataPath?: string; // default: ":memory:"
205
- createDriver?: CreateDriver; // custom driver factory (advanced)
206
- customPlatform?: AgentXPlatform; // custom platform (advanced)
207
-
208
- // --- Remote Mode ---
209
- serverUrl?: string; // WebSocket URL
210
- headers?: MaybeAsync<Record<string, string>>; // auth headers
211
- context?: MaybeAsync<Record<string, unknown>>; // business context
212
-
213
- // --- Common ---
214
- timeout?: number; // default: 30000 ms
215
- debug?: boolean;
216
- autoReconnect?: boolean; // default: true (remote only)
217
- }
218
- ```
219
-
220
- | Field | Type | Default | Description |
221
- | --------------- | ------------------------------------- | ---------------- | ----------------------------------------------------------------------------------- |
222
- | `apiKey` | `string` | -- | LLM provider API key (triggers local mode) |
223
- | `provider` | `LLMProvider` | `"anthropic"` | `"anthropic"` \| `"openai"` \| `"google"` \| `"xai"` \| `"deepseek"` \| `"mistral"` |
224
- | `model` | `string` | provider default | Model identifier |
225
- | `baseUrl` | `string` | -- | Custom API endpoint |
226
- | `dataPath` | `string` | `":memory:"` | SQLite path or `:memory:` |
227
- | `serverUrl` | `string` | -- | WebSocket URL (triggers remote mode) |
228
- | `headers` | `MaybeAsync<Record<string, string>>` | -- | Static, dynamic, or async auth headers |
229
- | `context` | `MaybeAsync<Record<string, unknown>>` | -- | Business context (userId, tenantId, etc.) |
230
- | `timeout` | `number` | `30000` | Request timeout in ms |
231
- | `debug` | `boolean` | `false` | Enable debug logging |
232
- | `autoReconnect` | `boolean` | `true` | Auto reconnect on connection loss (remote only) |
233
-
234
- ### MaybeAsync
235
-
236
- `headers` and `context` accept static values, functions, or async functions:
237
-
238
- ```typescript
239
- type MaybeAsync<T> = T | (() => T) | (() => Promise<T>);
240
-
241
- // Static
242
- headers: {
243
- Authorization: "Bearer sk-xxx";
244
- }
245
-
246
- // Dynamic
247
- headers: () => ({ Authorization: `Bearer ${getToken()}` });
248
-
249
- // Async
250
- headers: async () => ({ Authorization: `Bearer ${await refreshToken()}` });
251
- ```
252
-
253
- ### Environment Variables
254
-
255
- | Variable | Description |
256
- | ------------------- | -------------------------------------- |
257
- | `ANTHROPIC_API_KEY` | Default API key for Anthropic provider |
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { CreateDriver } from '@agentxjs/core/driver';
2
2
  import { AgentXRuntime, AgentXPlatform } from '@agentxjs/core/runtime';
3
3
  import { Message } from '@agentxjs/core/agent';
4
+ import { AgentXError } from '@agentxjs/core/error';
5
+ export { AgentXError, AgentXErrorCategory, AgentXErrorCode, AgentXErrorContext } from '@agentxjs/core/error';
4
6
  import { Unsubscribe, BusEvent, EventBus, BusEventHandler } from '@agentxjs/core/event';
5
7
  import * as _agentxjs_core_network from '@agentxjs/core/network';
6
8
  import { RpcMethod } from '@agentxjs/core/network';
@@ -467,6 +469,22 @@ interface AgentX {
467
469
  }>): Unsubscribe;
468
470
  onAny(handler: BusEventHandler): Unsubscribe;
469
471
  subscribe(sessionId: string): void;
472
+ /**
473
+ * Top-level error handler — receives all AgentXError instances from any layer.
474
+ *
475
+ * Independent of `on("error", ...)` (stream events) and `presentation.onError` (UI errors).
476
+ *
477
+ * @example
478
+ * ```typescript
479
+ * ax.onError((error) => {
480
+ * console.error(`[${error.category}] ${error.code}: ${error.message}`);
481
+ * if (!error.recoverable) {
482
+ * // Circuit is open, stop sending requests
483
+ * }
484
+ * });
485
+ * ```
486
+ */
487
+ onError(handler: (error: AgentXError) => void): Unsubscribe;
470
488
  /**
471
489
  * Universal JSON-RPC entry point — works in all modes:
472
490
  * - Local: dispatches to CommandHandler directly
@@ -646,9 +664,9 @@ declare function createServer(config: ServerConfig): Promise<AgentXServer>;
646
664
  * @example Local mode
647
665
  * ```typescript
648
666
  * import { createAgentX } from "agentxjs";
649
- * import { node } from "@agentxjs/node-platform";
667
+ * import { nodePlatform } from "@agentxjs/node-platform";
650
668
  *
651
- * const ax = createAgentX(node({ createDriver }));
669
+ * const ax = createAgentX(nodePlatform({ createDriver }));
652
670
  * await ax.agent.create({ imageId: "..." });
653
671
  * ```
654
672
  *
@@ -660,7 +678,7 @@ declare function createServer(config: ServerConfig): Promise<AgentXServer>;
660
678
  *
661
679
  * @example Server mode
662
680
  * ```typescript
663
- * const ax = createAgentX(node({ createDriver }));
681
+ * const ax = createAgentX(nodePlatform({ createDriver }));
664
682
  * const server = await ax.serve({ port: 5200 });
665
683
  * ```
666
684
  */
package/dist/index.js CHANGED
@@ -761,6 +761,12 @@ var LocalClient = class {
761
761
  }
762
762
  subscribe(_sessionId) {
763
763
  }
764
+ // ==================== Error Handling ====================
765
+ onError(handler) {
766
+ return this.runtime.platform.eventBus.on("agentx_error", (event) => {
767
+ handler(event.data);
768
+ });
769
+ }
764
770
  // ==================== RPC ====================
765
771
  async rpc(method, params) {
766
772
  if (!this.commandHandler) {
@@ -850,6 +856,12 @@ var RemoteClient = class {
850
856
  this.rpcClient.subscribe(sessionId);
851
857
  logger2.debug("Subscribed to session", { sessionId });
852
858
  }
859
+ // ==================== Error Handling ====================
860
+ onError(handler) {
861
+ return this.eventBus.on("agentx_error", (event) => {
862
+ handler(event.data);
863
+ });
864
+ }
853
865
  // ==================== RPC ====================
854
866
  async rpc(method, params) {
855
867
  return this.rpcClient.call(method, params);
@@ -857,6 +869,7 @@ var RemoteClient = class {
857
869
  };
858
870
 
859
871
  // src/index.ts
872
+ import { AgentXError, AgentXErrorCode } from "@agentxjs/core/error";
860
873
  function createAgentX(config) {
861
874
  let localClient = null;
862
875
  function getLocalClient() {
@@ -904,6 +917,9 @@ function createAgentX(config) {
904
917
  subscribe(sessionId) {
905
918
  getLocalClient().subscribe(sessionId);
906
919
  },
920
+ onError(handler) {
921
+ return getLocalClient().onError(handler);
922
+ },
907
923
  async disconnect() {
908
924
  await localClient?.disconnect();
909
925
  },
@@ -948,6 +964,8 @@ function createAgentX(config) {
948
964
  };
949
965
  }
950
966
  export {
967
+ AgentXError,
968
+ AgentXErrorCode,
951
969
  CommandHandler,
952
970
  Presentation,
953
971
  addUserConversation,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/LocalClient.ts","../src/namespaces/agents.ts","../src/namespaces/containers.ts","../src/namespaces/images.ts","../src/presentation/types.ts","../src/presentation/reducer.ts","../src/presentation/Presentation.ts","../src/namespaces/presentations.ts","../src/namespaces/sessions.ts","../src/RemoteClient.ts"],"sourcesContent":["/**\n * agentxjs - AgentX Client SDK\n *\n * Fluent API supporting local, remote, and server modes.\n *\n * @example Local mode\n * ```typescript\n * import { createAgentX } from \"agentxjs\";\n * import { node } from \"@agentxjs/node-platform\";\n *\n * const ax = createAgentX(node({ createDriver }));\n * await ax.agent.create({ imageId: \"...\" });\n * ```\n *\n * @example Remote mode\n * ```typescript\n * const ax = createAgentX();\n * const client = await ax.connect(\"ws://localhost:5200\");\n * ```\n *\n * @example Server mode\n * ```typescript\n * const ax = createAgentX(node({ createDriver }));\n * const server = await ax.serve({ port: 5200 });\n * ```\n */\n\nimport type { CreateDriver } from \"@agentxjs/core/driver\";\nimport type { AgentXPlatform } from \"@agentxjs/core/runtime\";\nimport { createAgentXRuntime } from \"@agentxjs/core/runtime\";\nimport { LocalClient } from \"./LocalClient\";\nimport { RemoteClient } from \"./RemoteClient\";\nimport type { AgentX, AgentXBuilder, AgentXServer, ConnectOptions, ServeConfig } from \"./types\";\n\n/**\n * Platform configuration for createAgentX\n */\nexport interface PlatformConfig {\n platform: AgentXPlatform;\n createDriver: CreateDriver;\n}\n\n/**\n * Create an AgentX builder\n *\n * @param config - Platform configuration (optional). Without it, only connect() is available.\n * @returns AgentXBuilder — local AgentX + connect() + serve()\n */\nexport function createAgentX(config?: PlatformConfig): AgentXBuilder {\n let localClient: LocalClient | null = null;\n\n function getLocalClient(): LocalClient {\n if (localClient) return localClient;\n if (!config) {\n throw new Error(\n \"Local mode requires a platform. Pass a PlatformConfig to createAgentX(), or use connect() for remote mode.\"\n );\n }\n const runtime = createAgentXRuntime(config.platform, config.createDriver);\n localClient = new LocalClient(runtime);\n return localClient;\n }\n\n if (config) {\n getLocalClient();\n }\n\n return {\n get connected() {\n return localClient?.connected ?? false;\n },\n\n get events() {\n return getLocalClient().events;\n },\n\n get container() {\n return getLocalClient().container;\n },\n\n get image() {\n return getLocalClient().image;\n },\n\n get agent() {\n return getLocalClient().agent;\n },\n\n get session() {\n return getLocalClient().session;\n },\n\n get presentation() {\n return getLocalClient().presentation;\n },\n\n on(type, handler) {\n return getLocalClient().on(type, handler);\n },\n\n onAny(handler) {\n return getLocalClient().onAny(handler);\n },\n\n subscribe(sessionId) {\n getLocalClient().subscribe(sessionId);\n },\n\n async disconnect() {\n await localClient?.disconnect();\n },\n\n async dispose() {\n await localClient?.dispose();\n localClient = null;\n },\n\n async connect(serverUrl: string, options?: ConnectOptions): Promise<AgentX> {\n const remoteClient = new RemoteClient({\n serverUrl,\n headers: options?.headers as Record<string, string> | undefined,\n context: options?.context,\n timeout: options?.timeout,\n autoReconnect: options?.autoReconnect,\n customPlatform: config?.platform,\n });\n await remoteClient.connect();\n return remoteClient;\n },\n\n async serve(serveConfig?: ServeConfig): Promise<AgentXServer> {\n if (!config) {\n throw new Error(\"serve() requires a platform. Pass a PlatformConfig to createAgentX().\");\n }\n if (!config.platform.channelServer) {\n throw new Error(\n \"serve() requires platform.channelServer. Ensure your platform supports server mode.\"\n );\n }\n\n const { createServer } = await import(\"./server\");\n return createServer({\n platform: config.platform,\n createDriver: config.createDriver,\n port: serveConfig?.port,\n host: serveConfig?.host,\n server: serveConfig?.server as any,\n wsPath: serveConfig?.wsPath,\n });\n },\n\n async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {\n return getLocalClient().rpc<T>(method, params);\n },\n };\n}\n\n// Re-export server\nexport { CommandHandler } from \"./CommandHandler\";\n// Re-export Presentation types and classes\nexport type {\n AssistantConversation,\n Block,\n Conversation,\n ErrorConversation,\n ImageBlock,\n PresentationErrorHandler,\n PresentationOptions,\n PresentationState,\n PresentationUpdateHandler,\n TextBlock,\n ToolBlock,\n UserConversation,\n} from \"./presentation\";\nexport {\n addUserConversation,\n createInitialState,\n initialPresentationState,\n messagesToConversations,\n Presentation,\n presentationReducer,\n} from \"./presentation\";\nexport { createServer, type ServerConfig } from \"./server\";\n// Re-export types\nexport type {\n AgentCreateResponse,\n AgentGetResponse,\n AgentInfo,\n AgentListResponse,\n AgentNamespace,\n AgentX,\n AgentXBuilder,\n AgentXServer,\n BaseResponse,\n ConnectOptions,\n ContainerCreateResponse,\n ContainerGetResponse,\n ContainerInfo,\n ContainerListResponse,\n ContainerNamespace,\n ImageCreateResponse,\n ImageGetResponse,\n ImageListResponse,\n ImageNamespace,\n ImageRecord,\n MaybeAsync,\n MessageSendResponse,\n PresentationNamespace,\n ServeConfig,\n SessionNamespace,\n} from \"./types\";\n","/**\n * LocalClient - AgentX client for local mode\n *\n * Runs an embedded Runtime + Driver directly, without WebSocket.\n * Implements the same AgentX interface as RemoteClient.\n */\n\nimport type { BusEvent, BusEventHandler, EventBus, Unsubscribe } from \"@agentxjs/core/event\";\nimport type { RpcMethod } from \"@agentxjs/core/network\";\nimport type { AgentXRuntime } from \"@agentxjs/core/runtime\";\nimport { createLogger } from \"commonxjs/logger\";\nimport { CommandHandler } from \"./CommandHandler\";\nimport { createLocalAgents } from \"./namespaces/agents\";\nimport { createLocalContainers } from \"./namespaces/containers\";\nimport { createLocalImages } from \"./namespaces/images\";\nimport { createPresentations } from \"./namespaces/presentations\";\nimport { createLocalSessions } from \"./namespaces/sessions\";\nimport type {\n AgentNamespace,\n AgentX,\n ContainerNamespace,\n ImageNamespace,\n PresentationNamespace,\n SessionNamespace,\n} from \"./types\";\n\nconst logger = createLogger(\"agentx/LocalClient\");\n\n/**\n * LocalClient - Embedded runtime implementation\n */\nexport class LocalClient implements AgentX {\n private readonly runtime: AgentXRuntime;\n private commandHandler: CommandHandler | null = null;\n private isDisposed = false;\n\n readonly container: ContainerNamespace;\n readonly image: ImageNamespace;\n readonly agent: AgentNamespace;\n readonly session: SessionNamespace;\n readonly presentation: PresentationNamespace;\n\n constructor(runtime: AgentXRuntime) {\n this.runtime = runtime;\n const platform = runtime.platform;\n\n this.container = createLocalContainers(platform);\n this.image = createLocalImages(platform);\n this.agent = createLocalAgents(runtime);\n this.session = createLocalSessions(runtime);\n this.presentation = createPresentations(this);\n\n logger.info(\"LocalClient initialized\");\n }\n\n // ==================== Properties ====================\n\n get connected(): boolean {\n return !this.isDisposed;\n }\n\n get events(): EventBus {\n return this.runtime.platform.eventBus;\n }\n\n // ==================== Event Subscription ====================\n\n on<T extends string>(type: T, handler: BusEventHandler<BusEvent & { type: T }>): Unsubscribe {\n return this.runtime.platform.eventBus.on(type, handler);\n }\n\n onAny(handler: BusEventHandler): Unsubscribe {\n return this.runtime.platform.eventBus.onAny(handler);\n }\n\n subscribe(_sessionId: string): void {\n // No-op for local mode - already subscribed via eventBus\n }\n\n // ==================== RPC ====================\n\n async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {\n if (!this.commandHandler) {\n this.commandHandler = new CommandHandler(this.runtime);\n }\n const result = await this.commandHandler.handle(method as RpcMethod, params);\n if (result.success) {\n return result.data as T;\n }\n throw new Error(result.message);\n }\n\n // ==================== Lifecycle ====================\n\n async disconnect(): Promise<void> {\n // No-op for local mode\n }\n\n async dispose(): Promise<void> {\n if (this.isDisposed) return;\n await this.runtime.shutdown();\n this.isDisposed = true;\n logger.info(\"LocalClient disposed\");\n }\n}\n","/**\n * Agent namespace factories\n */\n\nimport type { RpcClient, RpcMethod } from \"@agentxjs/core/network\";\nimport type { AgentXRuntime } from \"@agentxjs/core/runtime\";\nimport type {\n AgentCreateResponse,\n AgentGetResponse,\n AgentListResponse,\n AgentNamespace,\n BaseResponse,\n} from \"../types\";\n\n/**\n * Create local agent namespace backed by embedded runtime\n */\nexport function createLocalAgents(runtime: AgentXRuntime): AgentNamespace {\n return {\n async create(params: { imageId: string; agentId?: string }): Promise<AgentCreateResponse> {\n // Reuse existing running agent for this image\n const existingAgent = runtime\n .getAgents()\n .find((a) => a.imageId === params.imageId && a.lifecycle === \"running\");\n\n if (existingAgent) {\n return {\n agentId: existingAgent.agentId,\n imageId: existingAgent.imageId,\n containerId: existingAgent.containerId,\n sessionId: existingAgent.sessionId,\n requestId: \"\",\n };\n }\n\n const agent = await runtime.createAgent({\n imageId: params.imageId,\n agentId: params.agentId,\n });\n\n return {\n agentId: agent.agentId,\n imageId: agent.imageId,\n containerId: agent.containerId,\n sessionId: agent.sessionId,\n requestId: \"\",\n };\n },\n\n async get(agentId: string): Promise<AgentGetResponse> {\n const agent = runtime.getAgent(agentId);\n return {\n agent: agent\n ? {\n agentId: agent.agentId,\n imageId: agent.imageId,\n containerId: agent.containerId,\n sessionId: agent.sessionId,\n lifecycle: agent.lifecycle,\n }\n : null,\n exists: !!agent,\n requestId: \"\",\n };\n },\n\n async list(containerId?: string): Promise<AgentListResponse> {\n const agents = containerId ? runtime.getAgentsByContainer(containerId) : runtime.getAgents();\n\n return {\n agents: agents.map((a) => ({\n agentId: a.agentId,\n imageId: a.imageId,\n containerId: a.containerId,\n sessionId: a.sessionId,\n lifecycle: a.lifecycle,\n })),\n requestId: \"\",\n };\n },\n\n async destroy(agentId: string): Promise<BaseResponse> {\n const agent = runtime.getAgent(agentId);\n if (agent) {\n await runtime.destroyAgent(agentId);\n }\n return { requestId: \"\" };\n },\n };\n}\n\n/**\n * Create remote agent namespace backed by RPC client\n */\nexport function createRemoteAgents(rpcClient: RpcClient): AgentNamespace {\n return {\n async create(params: { imageId: string; agentId?: string }): Promise<AgentCreateResponse> {\n // Agent creation via image.run RPC\n const result = await rpcClient.call<AgentCreateResponse>(\"image.run\" as RpcMethod, {\n imageId: params.imageId,\n agentId: params.agentId,\n });\n return { ...result, requestId: \"\" };\n },\n\n async get(agentId: string): Promise<AgentGetResponse> {\n const result = await rpcClient.call<AgentGetResponse>(\"agent.get\", { agentId });\n return { ...result, requestId: \"\" };\n },\n\n async list(containerId?: string): Promise<AgentListResponse> {\n const result = await rpcClient.call<AgentListResponse>(\"agent.list\", { containerId });\n return { ...result, requestId: \"\" };\n },\n\n async destroy(agentId: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"agent.destroy\", { agentId });\n return { ...result, requestId: \"\" };\n },\n };\n}\n","/**\n * Container namespace factories\n */\n\nimport type { RpcClient } from \"@agentxjs/core/network\";\nimport type { AgentXPlatform } from \"@agentxjs/core/runtime\";\nimport type {\n ContainerCreateResponse,\n ContainerGetResponse,\n ContainerListResponse,\n ContainerNamespace,\n} from \"../types\";\n\n/**\n * Create local container namespace backed by embedded runtime\n */\nexport function createLocalContainers(platform: AgentXPlatform): ContainerNamespace {\n return {\n async create(containerId: string): Promise<ContainerCreateResponse> {\n const { getOrCreateContainer } = await import(\"@agentxjs/core/container\");\n const { containerRepository, imageRepository, sessionRepository } = platform;\n\n const container = await getOrCreateContainer(containerId, {\n containerRepository,\n imageRepository,\n sessionRepository,\n });\n\n return { containerId: container.containerId, requestId: \"\" };\n },\n\n async get(containerId: string): Promise<ContainerGetResponse> {\n const exists = await platform.containerRepository.containerExists(containerId);\n return { containerId, exists, requestId: \"\" };\n },\n\n async list(): Promise<ContainerListResponse> {\n const containers = await platform.containerRepository.findAllContainers();\n return { containerIds: containers.map((c) => c.containerId), requestId: \"\" };\n },\n };\n}\n\n/**\n * Create remote container namespace backed by RPC client\n */\nexport function createRemoteContainers(rpcClient: RpcClient): ContainerNamespace {\n return {\n async create(containerId: string): Promise<ContainerCreateResponse> {\n const result = await rpcClient.call<ContainerCreateResponse>(\"container.create\", {\n containerId,\n });\n return { ...result, requestId: \"\" };\n },\n\n async get(containerId: string): Promise<ContainerGetResponse> {\n const result = await rpcClient.call<ContainerGetResponse>(\"container.get\", {\n containerId,\n });\n return { ...result, requestId: \"\" };\n },\n\n async list(): Promise<ContainerListResponse> {\n const result = await rpcClient.call<ContainerListResponse>(\"container.list\", {});\n return { ...result, requestId: \"\" };\n },\n };\n}\n","/**\n * Image namespace factories\n */\n\nimport type { Message } from \"@agentxjs/core/agent\";\nimport type { RpcClient } from \"@agentxjs/core/network\";\nimport type { AgentXPlatform } from \"@agentxjs/core/runtime\";\nimport type {\n BaseResponse,\n ImageCreateResponse,\n ImageGetResponse,\n ImageListResponse,\n ImageNamespace,\n ImageUpdateResponse,\n} from \"../types\";\n\n/**\n * Create local image namespace backed by embedded runtime\n */\nexport function createLocalImages(platform: AgentXPlatform): ImageNamespace {\n return {\n async create(params: {\n containerId: string;\n name?: string;\n description?: string;\n systemPrompt?: string;\n mcpServers?: Record<string, unknown>;\n customData?: Record<string, unknown>;\n }): Promise<ImageCreateResponse> {\n const { imageRepository, sessionRepository } = platform;\n const { createImage } = await import(\"@agentxjs/core/image\");\n\n const image = await createImage(\n {\n containerId: params.containerId,\n name: params.name,\n description: params.description,\n systemPrompt: params.systemPrompt,\n mcpServers: params.mcpServers as any,\n customData: params.customData,\n },\n { imageRepository, sessionRepository }\n );\n\n return {\n record: image.toRecord(),\n __subscriptions: [image.sessionId],\n requestId: \"\",\n };\n },\n\n async get(imageId: string): Promise<ImageGetResponse> {\n const record = await platform.imageRepository.findImageById(imageId);\n return {\n record,\n __subscriptions: record?.sessionId ? [record.sessionId] : undefined,\n requestId: \"\",\n };\n },\n\n async list(containerId?: string): Promise<ImageListResponse> {\n const records = containerId\n ? await platform.imageRepository.findImagesByContainerId(containerId)\n : await platform.imageRepository.findAllImages();\n\n return {\n records,\n __subscriptions: records.map((r) => r.sessionId),\n requestId: \"\",\n };\n },\n\n async update(\n imageId: string,\n updates: {\n name?: string;\n description?: string;\n customData?: Record<string, unknown>;\n }\n ): Promise<ImageUpdateResponse> {\n const { loadImage } = await import(\"@agentxjs/core/image\");\n const { imageRepository, sessionRepository } = platform;\n\n const image = await loadImage(imageId, { imageRepository, sessionRepository });\n if (!image) {\n throw new Error(`Image not found: ${imageId}`);\n }\n\n const updated = await image.update(updates);\n return { record: updated.toRecord(), requestId: \"\" };\n },\n\n async delete(imageId: string): Promise<BaseResponse> {\n const { loadImage } = await import(\"@agentxjs/core/image\");\n const { imageRepository, sessionRepository } = platform;\n\n const image = await loadImage(imageId, { imageRepository, sessionRepository });\n if (image) {\n await image.delete();\n }\n\n return { requestId: \"\" };\n },\n\n async getMessages(imageId: string): Promise<Message[]> {\n const imageRecord = await platform.imageRepository.findImageById(imageId);\n if (!imageRecord) return [];\n return platform.sessionRepository.getMessages(imageRecord.sessionId);\n },\n };\n}\n\n/**\n * Create remote image namespace backed by RPC client\n */\nexport function createRemoteImages(\n rpcClient: RpcClient,\n subscribeFn: (sessionId: string) => void\n): ImageNamespace {\n return {\n async create(params: {\n containerId: string;\n name?: string;\n description?: string;\n systemPrompt?: string;\n mcpServers?: Record<string, unknown>;\n customData?: Record<string, unknown>;\n }): Promise<ImageCreateResponse> {\n const result = await rpcClient.call<ImageCreateResponse>(\"image.create\", params);\n\n // Auto subscribe to session events\n if (result.__subscriptions) {\n for (const sessionId of result.__subscriptions) {\n subscribeFn(sessionId);\n }\n }\n\n return { ...result, requestId: \"\" };\n },\n\n async get(imageId: string): Promise<ImageGetResponse> {\n const result = await rpcClient.call<ImageGetResponse>(\"image.get\", { imageId });\n\n // Auto subscribe\n if (result.__subscriptions) {\n for (const sessionId of result.__subscriptions) {\n subscribeFn(sessionId);\n }\n }\n\n return { ...result, requestId: \"\" };\n },\n\n async list(containerId?: string): Promise<ImageListResponse> {\n const result = await rpcClient.call<ImageListResponse>(\"image.list\", { containerId });\n\n // Auto subscribe\n if (result.__subscriptions) {\n for (const sessionId of result.__subscriptions) {\n subscribeFn(sessionId);\n }\n }\n\n return { ...result, requestId: \"\" };\n },\n\n async update(\n imageId: string,\n updates: {\n name?: string;\n description?: string;\n customData?: Record<string, unknown>;\n }\n ): Promise<ImageUpdateResponse> {\n const result = await rpcClient.call<ImageUpdateResponse>(\"image.update\", {\n imageId,\n updates,\n });\n return { ...result, requestId: \"\" };\n },\n\n async delete(imageId: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"image.delete\", { imageId });\n return { ...result, requestId: \"\" };\n },\n\n async getMessages(imageId: string): Promise<Message[]> {\n const result = await rpcClient.call<{ messages: Message[] }>(\"image.messages\", { imageId });\n return result.messages ?? [];\n },\n };\n}\n","/**\n * Presentation Types\n *\n * UI-friendly data model aggregated from stream events.\n * This implements the Presentation Model pattern.\n */\n\n// ============================================================================\n// Block Types - Basic content units\n// ============================================================================\n\n/**\n * Text block\n */\nexport interface TextBlock {\n type: \"text\";\n content: string;\n}\n\n/**\n * Tool block - represents a tool call and its result\n */\nexport interface ToolBlock {\n type: \"tool\";\n toolUseId: string;\n toolName: string;\n toolInput: Record<string, unknown>;\n toolResult?: string;\n status: \"pending\" | \"running\" | \"completed\" | \"error\";\n}\n\n/**\n * Image block\n */\nexport interface ImageBlock {\n type: \"image\";\n url: string;\n alt?: string;\n}\n\n/**\n * All block types\n */\nexport type Block = TextBlock | ToolBlock | ImageBlock;\n\n// ============================================================================\n// Conversation Types - A single turn in the conversation\n// ============================================================================\n\n/**\n * User conversation\n */\nexport interface UserConversation {\n role: \"user\";\n blocks: Block[];\n}\n\n/**\n * Token usage for a message (one LLM call / step)\n */\nexport interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n}\n\n/**\n * Assistant conversation\n */\nexport interface AssistantConversation {\n role: \"assistant\";\n blocks: Block[];\n isStreaming: boolean;\n /** Accumulated token usage across all steps in this conversation */\n usage?: TokenUsage;\n}\n\n/**\n * Error conversation\n */\nexport interface ErrorConversation {\n role: \"error\";\n message: string;\n}\n\n/**\n * All conversation types\n */\nexport type Conversation = UserConversation | AssistantConversation | ErrorConversation;\n\n// ============================================================================\n// Presentation State\n// ============================================================================\n\n/**\n * Presentation state - the complete UI state\n */\nexport interface PresentationState {\n /**\n * All completed conversations\n */\n conversations: Conversation[];\n\n /**\n * Current streaming conversation (null if not streaming)\n */\n streaming: AssistantConversation | null;\n\n /**\n * Current status\n */\n status: \"idle\" | \"thinking\" | \"responding\" | \"executing\";\n}\n\n/**\n * Initial presentation state\n */\nexport const initialPresentationState: PresentationState = {\n conversations: [],\n streaming: null,\n status: \"idle\",\n};\n","/**\n * Presentation Reducer\n *\n * Aggregates events into PresentationState.\n * Pure function: (state, event) => newState\n *\n * Event consumption strategy:\n * - Stream layer: message_start, text_delta, tool_use_start, tool_use_stop, message_stop\n * (for real-time streaming display)\n * - Message layer: tool_result_message\n * (for tool execution results — arrives after message_stop)\n *\n * Tool calls are stream-level blocks within the assistant turn,\n * matching the mainstream API pattern (Anthropic, OpenAI).\n */\n\nimport type {\n AssistantMessage,\n ErrorMessage,\n Message,\n ToolCallPart,\n ToolResultMessage,\n ToolResultOutput,\n UserMessage,\n} from \"@agentxjs/core/agent\";\nimport type { BusEvent } from \"@agentxjs/core/event\";\nimport type {\n AssistantConversation,\n Block,\n Conversation,\n PresentationState,\n TextBlock,\n TokenUsage,\n ToolBlock,\n} from \"./types\";\nimport { initialPresentationState } from \"./types\";\n\n// ============================================================================\n// Event Data Types\n// ============================================================================\n\ninterface MessageStartData {\n messageId?: string;\n model?: string;\n}\n\ninterface TextDeltaData {\n text: string;\n}\n\ninterface ToolUseStartData {\n toolCallId: string;\n toolName: string;\n}\n\ninterface ToolUseStopData {\n toolCallId: string;\n toolName: string;\n input: Record<string, unknown>;\n}\n\ninterface MessageDeltaData {\n usage?: {\n inputTokens: number;\n outputTokens: number;\n };\n}\n\ninterface MessageStopData {\n stopReason?: string;\n}\n\ninterface ErrorData {\n message: string;\n code?: string;\n}\n\n// ============================================================================\n// Reducer\n// ============================================================================\n\n/**\n * Reduce an event into presentation state.\n *\n * Consumes:\n * - Stream events: message_start, text_delta, tool_use_start, tool_use_stop, message_stop\n * - Message events: tool_result_message\n * - Error events: error\n */\nexport function presentationReducer(state: PresentationState, event: BusEvent): PresentationState {\n switch (event.type) {\n // Stream layer — real-time display\n case \"message_start\":\n return handleMessageStart(state, event.data as MessageStartData);\n\n case \"text_delta\":\n return handleTextDelta(state, event.data as TextDeltaData);\n\n case \"tool_use_start\":\n return handleToolUseStart(state, event.data as ToolUseStartData);\n\n case \"tool_use_stop\":\n return handleToolUseStop(state, event.data as ToolUseStopData);\n\n case \"message_delta\":\n return handleMessageDelta(state, event.data as MessageDeltaData);\n\n case \"message_stop\":\n return handleMessageStop(state, event.data as MessageStopData);\n\n // Message layer — tool results from Engine\n case \"tool_result_message\":\n return handleToolResultMessage(state, event.data as ToolResultMessage);\n\n case \"error\":\n return handleError(state, event.data as ErrorData);\n\n default:\n return state;\n }\n}\n\n// ============================================================================\n// Handlers\n// ============================================================================\n\nfunction handleMessageStart(state: PresentationState, _data: MessageStartData): PresentationState {\n // If streaming already exists (e.g. tool_use turn not yet flushed), flush it first\n let conversations = state.conversations;\n if (state.streaming && state.streaming.blocks.length > 0) {\n conversations = [...conversations, { ...state.streaming, isStreaming: false }];\n }\n\n const streaming: AssistantConversation = {\n role: \"assistant\",\n blocks: [],\n isStreaming: true,\n };\n\n return {\n ...state,\n conversations,\n streaming,\n status: \"thinking\",\n };\n}\n\nfunction handleTextDelta(state: PresentationState, data: TextDeltaData): PresentationState {\n if (!state.streaming) {\n return state;\n }\n\n const blocks = [...state.streaming.blocks];\n const lastBlock = blocks[blocks.length - 1];\n\n if (lastBlock && lastBlock.type === \"text\") {\n blocks[blocks.length - 1] = {\n ...lastBlock,\n content: lastBlock.content + data.text,\n };\n } else {\n blocks.push({\n type: \"text\",\n content: data.text,\n } as TextBlock);\n }\n\n return {\n ...state,\n streaming: {\n ...state.streaming,\n blocks,\n },\n status: \"responding\",\n };\n}\n\nfunction handleToolUseStart(state: PresentationState, data: ToolUseStartData): PresentationState {\n if (!state.streaming) {\n return state;\n }\n\n // Create a pending tool block — toolInput will be filled by tool_use_stop\n const toolBlock: ToolBlock = {\n type: \"tool\",\n toolUseId: data.toolCallId,\n toolName: data.toolName,\n toolInput: {},\n status: \"pending\",\n };\n\n return {\n ...state,\n streaming: {\n ...state.streaming,\n blocks: [...state.streaming.blocks, toolBlock],\n },\n status: \"executing\",\n };\n}\n\n/**\n * Handle tool_use_stop from stream layer.\n * Fills in the complete toolInput for the matching pending tool block.\n * The stream event carries the fully assembled input.\n */\nfunction handleToolUseStop(state: PresentationState, data: ToolUseStopData): PresentationState {\n if (!state.streaming) {\n return state;\n }\n\n const blocks = state.streaming.blocks.map((block): Block => {\n if (block.type === \"tool\" && block.toolUseId === data.toolCallId) {\n return {\n ...block,\n toolInput: data.input,\n status: \"running\",\n };\n }\n return block;\n });\n\n return {\n ...state,\n streaming: {\n ...state.streaming,\n blocks,\n },\n };\n}\n\nfunction handleMessageDelta(state: PresentationState, data: MessageDeltaData): PresentationState {\n if (!state.streaming || !data.usage) {\n return state;\n }\n\n const prev = state.streaming.usage;\n const usage: TokenUsage = {\n inputTokens: (prev?.inputTokens ?? 0) + data.usage.inputTokens,\n outputTokens: (prev?.outputTokens ?? 0) + data.usage.outputTokens,\n };\n\n return {\n ...state,\n streaming: {\n ...state.streaming,\n usage,\n },\n };\n}\n\nfunction handleMessageStop(state: PresentationState, data: MessageStopData): PresentationState {\n if (!state.streaming) {\n return state;\n }\n\n // tool_use stop → don't flush, tool results are still incoming\n if (data.stopReason === \"tool_use\") {\n return {\n ...state,\n status: \"executing\",\n };\n }\n\n // end_turn / max_tokens / etc → flush streaming to conversations\n const completedConversation: AssistantConversation = {\n ...state.streaming,\n isStreaming: false,\n };\n\n return {\n ...state,\n conversations: [...state.conversations, completedConversation],\n streaming: null,\n status: \"idle\",\n };\n}\n\n/**\n * Handle tool_result_message from Engine layer.\n * Fills in the toolResult for the matching tool block.\n *\n * Note: tool_result_message arrives after message_stop(tool_use),\n * but streaming is kept alive (not flushed) during tool_use turns.\n */\nfunction handleToolResultMessage(\n state: PresentationState,\n data: ToolResultMessage\n): PresentationState {\n if (!state.streaming) {\n return state;\n }\n\n const toolCallId = data.toolCallId;\n const blocks = state.streaming.blocks.map((block): Block => {\n if (block.type === \"tool\" && block.toolUseId === toolCallId) {\n return {\n ...block,\n toolResult: formatToolResultOutput(data.toolResult.output),\n status:\n data.toolResult.output.type === \"error-text\" ||\n data.toolResult.output.type === \"error-json\" ||\n data.toolResult.output.type === \"execution-denied\"\n ? \"error\"\n : \"completed\",\n };\n }\n return block;\n });\n\n return {\n ...state,\n streaming: {\n ...state.streaming,\n blocks,\n },\n status: \"responding\",\n };\n}\n\nfunction handleError(state: PresentationState, data: ErrorData): PresentationState {\n return {\n ...state,\n conversations: [\n ...state.conversations,\n {\n role: \"error\",\n message: data.message,\n },\n ],\n streaming: null,\n status: \"idle\",\n };\n}\n\n// ============================================================================\n// Helper: Add user conversation\n// ============================================================================\n\nexport function addUserConversation(state: PresentationState, content: string): PresentationState {\n return {\n ...state,\n conversations: [\n ...state.conversations,\n {\n role: \"user\",\n blocks: [{ type: \"text\", content }],\n },\n ],\n };\n}\n\nexport function createInitialState(): PresentationState {\n return { ...initialPresentationState };\n}\n\n// ============================================================================\n// Helper: Format tool result output\n// ============================================================================\n\nfunction formatToolResultOutput(output: ToolResultOutput): string {\n switch (output.type) {\n case \"text\":\n case \"error-text\":\n return output.value;\n case \"json\":\n case \"error-json\":\n return JSON.stringify(output.value);\n case \"execution-denied\":\n return output.reason ?? \"Execution denied\";\n case \"content\":\n return output.value\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\");\n }\n}\n\n// ============================================================================\n// Message → Conversation Converter\n// ============================================================================\n\n/**\n * Convert persisted Messages to Presentation Conversations.\n *\n * Groups consecutive assistant + tool-result messages\n * into a single AssistantConversation.\n *\n * Tool calls are now part of AssistantMessage.content (as ToolCallPart),\n * so we extract them directly from the assistant message.\n */\nexport function messagesToConversations(messages: Message[]): Conversation[] {\n const conversations: Conversation[] = [];\n let currentAssistant: AssistantConversation | null = null;\n\n function flushAssistant() {\n if (currentAssistant && currentAssistant.blocks.length > 0) {\n conversations.push(currentAssistant);\n }\n currentAssistant = null;\n }\n\n for (const msg of messages) {\n switch (msg.subtype) {\n case \"user\": {\n flushAssistant();\n const m = msg as UserMessage;\n const text =\n typeof m.content === \"string\"\n ? m.content\n : m.content\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\");\n conversations.push({\n role: \"user\",\n blocks: [{ type: \"text\", content: text }],\n });\n break;\n }\n\n case \"assistant\": {\n if (!currentAssistant) {\n currentAssistant = { role: \"assistant\", blocks: [], isStreaming: false };\n }\n const m = msg as AssistantMessage;\n if (typeof m.content === \"string\") {\n if (m.content) {\n currentAssistant.blocks.push({ type: \"text\", content: m.content } as TextBlock);\n }\n } else {\n // Extract text and tool call parts from content\n for (const part of m.content) {\n if (part.type === \"text\") {\n if (part.text) {\n currentAssistant.blocks.push({ type: \"text\", content: part.text } as TextBlock);\n }\n } else if (part.type === \"tool-call\") {\n const tc = part as ToolCallPart;\n currentAssistant.blocks.push({\n type: \"tool\",\n toolUseId: tc.id,\n toolName: tc.name,\n toolInput: tc.input,\n status: \"completed\",\n } as ToolBlock);\n }\n }\n }\n break;\n }\n\n case \"tool-result\": {\n const m = msg as ToolResultMessage;\n if (currentAssistant) {\n for (const block of currentAssistant.blocks) {\n if (block.type === \"tool\" && block.toolUseId === m.toolResult.id) {\n block.toolResult = formatToolResultOutput(m.toolResult.output);\n block.status =\n m.toolResult.output.type === \"error-text\" ||\n m.toolResult.output.type === \"error-json\" ||\n m.toolResult.output.type === \"execution-denied\"\n ? \"error\"\n : \"completed\";\n break;\n }\n }\n }\n break;\n }\n\n case \"error\": {\n flushAssistant();\n const m = msg as ErrorMessage;\n conversations.push({\n role: \"error\",\n message: m.content,\n });\n break;\n }\n }\n }\n\n flushAssistant();\n return conversations;\n}\n","/**\n * Presentation Class\n *\n * High-level API for UI integration.\n * Wraps AgentX client and provides presentation state management.\n */\n\nimport type { BusEvent, Unsubscribe } from \"@agentxjs/core/event\";\nimport type { AgentX } from \"../types\";\nimport { addUserConversation, createInitialState, presentationReducer } from \"./reducer\";\nimport type { Conversation, PresentationState } from \"./types\";\nimport { initialPresentationState } from \"./types\";\n\n/**\n * Presentation update handler\n */\nexport type PresentationUpdateHandler = (state: PresentationState) => void;\n\n/**\n * Presentation error handler\n */\nexport type PresentationErrorHandler = (error: Error) => void;\n\n/**\n * Presentation options\n */\nexport interface PresentationOptions {\n /**\n * Called on every state update\n */\n onUpdate?: PresentationUpdateHandler;\n\n /**\n * Called on errors\n */\n onError?: PresentationErrorHandler;\n}\n\n/**\n * Presentation - UI-friendly wrapper for AgentX\n */\nexport class Presentation {\n private agentx: AgentX;\n private agentId: string;\n private state: PresentationState;\n private updateHandlers: Set<PresentationUpdateHandler> = new Set();\n private errorHandlers: Set<PresentationErrorHandler> = new Set();\n private eventUnsubscribe: Unsubscribe | null = null;\n\n constructor(\n agentx: AgentX,\n agentId: string,\n options?: PresentationOptions,\n initialConversations?: Conversation[]\n ) {\n this.agentx = agentx;\n this.agentId = agentId;\n this.state = initialConversations?.length\n ? { ...initialPresentationState, conversations: initialConversations }\n : createInitialState();\n\n // Register initial handlers\n if (options?.onUpdate) {\n this.updateHandlers.add(options.onUpdate);\n }\n if (options?.onError) {\n this.errorHandlers.add(options.onError);\n }\n\n // Subscribe to all events\n this.subscribeToEvents();\n }\n\n /**\n * Get current state\n */\n getState(): PresentationState {\n return this.state;\n }\n\n /**\n * Subscribe to state updates\n */\n onUpdate(handler: PresentationUpdateHandler): Unsubscribe {\n this.updateHandlers.add(handler);\n // Immediately call with current state\n handler(this.state);\n return () => {\n this.updateHandlers.delete(handler);\n };\n }\n\n /**\n * Subscribe to errors\n */\n onError(handler: PresentationErrorHandler): Unsubscribe {\n this.errorHandlers.add(handler);\n return () => {\n this.errorHandlers.delete(handler);\n };\n }\n\n /**\n * Send a message\n */\n async send(content: string): Promise<void> {\n // Add user conversation\n this.state = addUserConversation(this.state, content);\n this.notify();\n\n try {\n // Send message via agentx\n await this.agentx.session.send(this.agentId, content);\n } catch (error) {\n this.notifyError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n /**\n * Interrupt current response\n */\n async interrupt(): Promise<void> {\n try {\n await this.agentx.session.interrupt(this.agentId);\n } catch (error) {\n this.notifyError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n /**\n * Reset state\n */\n reset(): void {\n this.state = createInitialState();\n this.notify();\n }\n\n /**\n * Dispose and cleanup\n */\n dispose(): void {\n if (this.eventUnsubscribe) {\n this.eventUnsubscribe();\n this.eventUnsubscribe = null;\n }\n this.updateHandlers.clear();\n this.errorHandlers.clear();\n }\n\n // ==================== Private ====================\n\n private subscribeToEvents(): void {\n // Subscribe to all events and filter by agentId\n this.eventUnsubscribe = this.agentx.onAny((event: BusEvent) => {\n // Filter events for this agent (if context is available)\n // Note: Events from server may or may not include context with agentId\n const eventWithContext = event as BusEvent & { context?: { agentId?: string } };\n const eventAgentId = eventWithContext.context?.agentId;\n\n // Only filter if event has agentId and it doesn't match\n if (eventAgentId && eventAgentId !== this.agentId) {\n return;\n }\n\n // Reduce event into state\n const newState = presentationReducer(this.state, event);\n if (newState !== this.state) {\n this.state = newState;\n this.notify();\n }\n });\n }\n\n private notify(): void {\n for (const handler of this.updateHandlers) {\n try {\n handler(this.state);\n } catch (error) {\n console.error(\"Presentation update handler error:\", error);\n }\n }\n }\n\n private notifyError(error: Error): void {\n for (const handler of this.errorHandlers) {\n try {\n handler(error);\n } catch (e) {\n console.error(\"Presentation error handler error:\", e);\n }\n }\n }\n}\n","/**\n * Presentation namespace factory\n *\n * Single factory for both local and remote modes —\n * Presentation only depends on the AgentX interface.\n */\n\nimport { messagesToConversations, Presentation, type PresentationOptions } from \"../presentation\";\nimport type { AgentX, PresentationNamespace } from \"../types\";\n\n/**\n * Create presentation namespace backed by any AgentX client\n */\nexport function createPresentations(agentx: AgentX): PresentationNamespace {\n return {\n async create(agentId: string, options?: PresentationOptions): Promise<Presentation> {\n const messages = await agentx.session.getMessages(agentId);\n const conversations = messagesToConversations(messages);\n return new Presentation(agentx, agentId, options, conversations);\n },\n };\n}\n","/**\n * Session namespace factories (messaging)\n */\n\nimport type { Message, UserContentPart } from \"@agentxjs/core/agent\";\nimport type { RpcClient } from \"@agentxjs/core/network\";\nimport type { AgentXRuntime } from \"@agentxjs/core/runtime\";\nimport type { AgentInfo, BaseResponse, MessageSendResponse, SessionNamespace } from \"../types\";\n\n/**\n * Create local session namespace backed by embedded runtime\n */\nexport function createLocalSessions(runtime: AgentXRuntime): SessionNamespace {\n return {\n async send(agentId: string, content: string | unknown[]): Promise<MessageSendResponse> {\n await runtime.receive(agentId, content as string | UserContentPart[]);\n return { agentId, requestId: \"\" };\n },\n\n async interrupt(agentId: string): Promise<BaseResponse> {\n runtime.interrupt(agentId);\n return { requestId: \"\" };\n },\n\n async getMessages(agentId: string): Promise<Message[]> {\n const agent = runtime.getAgent(agentId);\n if (!agent) return [];\n return runtime.platform.sessionRepository.getMessages(agent.sessionId);\n },\n };\n}\n\n/**\n * Create remote session namespace backed by RPC client\n */\nexport function createRemoteSessions(rpcClient: RpcClient): SessionNamespace {\n return {\n async send(agentId: string, content: string | unknown[]): Promise<MessageSendResponse> {\n const result = await rpcClient.call<MessageSendResponse>(\"message.send\", {\n agentId,\n content,\n });\n return { ...result, requestId: \"\" };\n },\n\n async interrupt(agentId: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"agent.interrupt\", { agentId });\n return { ...result, requestId: \"\" };\n },\n\n async getMessages(agentId: string): Promise<Message[]> {\n const agentRes = await rpcClient.call<{ agent: AgentInfo | null }>(\"agent.get\", { agentId });\n if (!agentRes.agent) return [];\n const msgRes = await rpcClient.call<{ messages: Message[] }>(\"image.messages\", {\n imageId: agentRes.agent.imageId,\n });\n return msgRes.messages ?? [];\n },\n };\n}\n","/**\n * RemoteClient - AgentX client for remote server\n *\n * Uses RpcClient from @agentxjs/core/network for JSON-RPC communication.\n * This class focuses on business logic, not protocol details.\n */\n\nimport type { BusEvent, BusEventHandler, EventBus, Unsubscribe } from \"@agentxjs/core/event\";\nimport { EventBusImpl } from \"@agentxjs/core/event\";\nimport { RpcClient } from \"@agentxjs/core/network\";\nimport { createLogger } from \"commonxjs/logger\";\nimport { createRemoteAgents } from \"./namespaces/agents\";\nimport { createRemoteContainers } from \"./namespaces/containers\";\nimport { createRemoteImages } from \"./namespaces/images\";\nimport { createPresentations } from \"./namespaces/presentations\";\nimport { createRemoteSessions } from \"./namespaces/sessions\";\nimport type {\n AgentNamespace,\n AgentX,\n ContainerNamespace,\n ImageNamespace,\n PresentationNamespace,\n RemoteClientConfig,\n SessionNamespace,\n} from \"./types\";\n\nconst logger = createLogger(\"agentx/RemoteClient\");\n\n/**\n * RemoteClient implementation using JSON-RPC 2.0\n */\nexport class RemoteClient implements AgentX {\n private readonly config: RemoteClientConfig;\n private readonly eventBus: EventBus;\n private readonly rpcClient: RpcClient;\n\n readonly container: ContainerNamespace;\n readonly image: ImageNamespace;\n readonly agent: AgentNamespace;\n readonly session: SessionNamespace;\n readonly presentation: PresentationNamespace;\n\n constructor(config: RemoteClientConfig) {\n this.config = config;\n this.eventBus = new EventBusImpl();\n\n // Create RPC client (WebSocket factory from platform if available)\n this.rpcClient = new RpcClient({\n url: config.serverUrl,\n createWebSocket: config.customPlatform?.channelClient,\n timeout: config.timeout ?? 30000,\n autoReconnect: config.autoReconnect ?? true,\n headers: config.headers as Record<string, string> | undefined,\n debug: false,\n });\n\n // Forward stream events to internal event bus\n this.rpcClient.onStreamEvent((topic, event) => {\n logger.debug(\"Received stream event\", { topic, type: event.type });\n this.eventBus.emit(event as BusEvent);\n });\n\n // Assemble namespaces\n this.container = createRemoteContainers(this.rpcClient);\n this.image = createRemoteImages(this.rpcClient, (sessionId) => this.subscribe(sessionId));\n this.agent = createRemoteAgents(this.rpcClient);\n this.session = createRemoteSessions(this.rpcClient);\n this.presentation = createPresentations(this);\n }\n\n // ==================== Properties ====================\n\n get connected(): boolean {\n return this.rpcClient.connected;\n }\n\n get events(): EventBus {\n return this.eventBus;\n }\n\n // ==================== Connection ====================\n\n async connect(): Promise<void> {\n await this.rpcClient.connect();\n logger.info(\"Connected to server\", { url: this.config.serverUrl });\n }\n\n async disconnect(): Promise<void> {\n this.rpcClient.disconnect();\n logger.info(\"Disconnected from server\");\n }\n\n async dispose(): Promise<void> {\n this.rpcClient.dispose();\n this.eventBus.destroy();\n logger.info(\"RemoteClient disposed\");\n }\n\n // ==================== Event Subscription ====================\n\n on<T extends string>(type: T, handler: BusEventHandler<BusEvent & { type: T }>): Unsubscribe {\n return this.eventBus.on(type, handler);\n }\n\n onAny(handler: BusEventHandler): Unsubscribe {\n return this.eventBus.onAny(handler);\n }\n\n subscribe(sessionId: string): void {\n this.rpcClient.subscribe(sessionId);\n logger.debug(\"Subscribed to session\", { sessionId });\n }\n\n // ==================== RPC ====================\n\n async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {\n return this.rpcClient.call<T>(method, params);\n }\n}\n"],"mappings":"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","names":["createLogger","logger","createLogger","createServer"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/LocalClient.ts","../src/namespaces/agents.ts","../src/namespaces/containers.ts","../src/namespaces/images.ts","../src/presentation/types.ts","../src/presentation/reducer.ts","../src/presentation/Presentation.ts","../src/namespaces/presentations.ts","../src/namespaces/sessions.ts","../src/RemoteClient.ts"],"sourcesContent":["/**\n * agentxjs - AgentX Client SDK\n *\n * Fluent API supporting local, remote, and server modes.\n *\n * @example Local mode\n * ```typescript\n * import { createAgentX } from \"agentxjs\";\n * import { nodePlatform } from \"@agentxjs/node-platform\";\n *\n * const ax = createAgentX(nodePlatform({ createDriver }));\n * await ax.agent.create({ imageId: \"...\" });\n * ```\n *\n * @example Remote mode\n * ```typescript\n * const ax = createAgentX();\n * const client = await ax.connect(\"ws://localhost:5200\");\n * ```\n *\n * @example Server mode\n * ```typescript\n * const ax = createAgentX(nodePlatform({ createDriver }));\n * const server = await ax.serve({ port: 5200 });\n * ```\n */\n\nimport type { CreateDriver } from \"@agentxjs/core/driver\";\nimport type { AgentXPlatform } from \"@agentxjs/core/runtime\";\nimport { createAgentXRuntime } from \"@agentxjs/core/runtime\";\nimport { LocalClient } from \"./LocalClient\";\nimport { RemoteClient } from \"./RemoteClient\";\nimport type { AgentX, AgentXBuilder, AgentXServer, ConnectOptions, ServeConfig } from \"./types\";\n\n/**\n * Platform configuration for createAgentX\n */\nexport interface PlatformConfig {\n platform: AgentXPlatform;\n createDriver: CreateDriver;\n}\n\n/**\n * Create an AgentX builder\n *\n * @param config - Platform configuration (optional). Without it, only connect() is available.\n * @returns AgentXBuilder — local AgentX + connect() + serve()\n */\nexport function createAgentX(config?: PlatformConfig): AgentXBuilder {\n let localClient: LocalClient | null = null;\n\n function getLocalClient(): LocalClient {\n if (localClient) return localClient;\n if (!config) {\n throw new Error(\n \"Local mode requires a platform. Pass a PlatformConfig to createAgentX(), or use connect() for remote mode.\"\n );\n }\n const runtime = createAgentXRuntime(config.platform, config.createDriver);\n localClient = new LocalClient(runtime);\n return localClient;\n }\n\n if (config) {\n getLocalClient();\n }\n\n return {\n get connected() {\n return localClient?.connected ?? false;\n },\n\n get events() {\n return getLocalClient().events;\n },\n\n get container() {\n return getLocalClient().container;\n },\n\n get image() {\n return getLocalClient().image;\n },\n\n get agent() {\n return getLocalClient().agent;\n },\n\n get session() {\n return getLocalClient().session;\n },\n\n get presentation() {\n return getLocalClient().presentation;\n },\n\n on(type, handler) {\n return getLocalClient().on(type, handler);\n },\n\n onAny(handler) {\n return getLocalClient().onAny(handler);\n },\n\n subscribe(sessionId) {\n getLocalClient().subscribe(sessionId);\n },\n\n onError(handler) {\n return getLocalClient().onError(handler);\n },\n\n async disconnect() {\n await localClient?.disconnect();\n },\n\n async dispose() {\n await localClient?.dispose();\n localClient = null;\n },\n\n async connect(serverUrl: string, options?: ConnectOptions): Promise<AgentX> {\n const remoteClient = new RemoteClient({\n serverUrl,\n headers: options?.headers as Record<string, string> | undefined,\n context: options?.context,\n timeout: options?.timeout,\n autoReconnect: options?.autoReconnect,\n customPlatform: config?.platform,\n });\n await remoteClient.connect();\n return remoteClient;\n },\n\n async serve(serveConfig?: ServeConfig): Promise<AgentXServer> {\n if (!config) {\n throw new Error(\"serve() requires a platform. Pass a PlatformConfig to createAgentX().\");\n }\n if (!config.platform.channelServer) {\n throw new Error(\n \"serve() requires platform.channelServer. Ensure your platform supports server mode.\"\n );\n }\n\n const { createServer } = await import(\"./server\");\n return createServer({\n platform: config.platform,\n createDriver: config.createDriver,\n port: serveConfig?.port,\n host: serveConfig?.host,\n server: serveConfig?.server as any,\n wsPath: serveConfig?.wsPath,\n });\n },\n\n async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {\n return getLocalClient().rpc<T>(method, params);\n },\n };\n}\n\nexport type { AgentXErrorCategory, AgentXErrorContext } from \"@agentxjs/core/error\";\n// Re-export error types\nexport { AgentXError, AgentXErrorCode } from \"@agentxjs/core/error\";\n// Re-export server\nexport { CommandHandler } from \"./CommandHandler\";\n// Re-export Presentation types and classes\nexport type {\n AssistantConversation,\n Block,\n Conversation,\n ErrorConversation,\n ImageBlock,\n PresentationErrorHandler,\n PresentationOptions,\n PresentationState,\n PresentationUpdateHandler,\n TextBlock,\n ToolBlock,\n UserConversation,\n} from \"./presentation\";\nexport {\n addUserConversation,\n createInitialState,\n initialPresentationState,\n messagesToConversations,\n Presentation,\n presentationReducer,\n} from \"./presentation\";\nexport { createServer, type ServerConfig } from \"./server\";\n// Re-export types\nexport type {\n AgentCreateResponse,\n AgentGetResponse,\n AgentInfo,\n AgentListResponse,\n AgentNamespace,\n AgentX,\n AgentXBuilder,\n AgentXServer,\n BaseResponse,\n ConnectOptions,\n ContainerCreateResponse,\n ContainerGetResponse,\n ContainerInfo,\n ContainerListResponse,\n ContainerNamespace,\n ImageCreateResponse,\n ImageGetResponse,\n ImageListResponse,\n ImageNamespace,\n ImageRecord,\n MaybeAsync,\n MessageSendResponse,\n PresentationNamespace,\n ServeConfig,\n SessionNamespace,\n} from \"./types\";\n","/**\n * LocalClient - AgentX client for local mode\n *\n * Runs an embedded Runtime + Driver directly, without WebSocket.\n * Implements the same AgentX interface as RemoteClient.\n */\n\nimport type { AgentXError } from \"@agentxjs/core/error\";\nimport type { BusEvent, BusEventHandler, EventBus, Unsubscribe } from \"@agentxjs/core/event\";\nimport type { RpcMethod } from \"@agentxjs/core/network\";\nimport type { AgentXRuntime } from \"@agentxjs/core/runtime\";\nimport { createLogger } from \"commonxjs/logger\";\nimport { CommandHandler } from \"./CommandHandler\";\nimport { createLocalAgents } from \"./namespaces/agents\";\nimport { createLocalContainers } from \"./namespaces/containers\";\nimport { createLocalImages } from \"./namespaces/images\";\nimport { createPresentations } from \"./namespaces/presentations\";\nimport { createLocalSessions } from \"./namespaces/sessions\";\nimport type {\n AgentNamespace,\n AgentX,\n ContainerNamespace,\n ImageNamespace,\n PresentationNamespace,\n SessionNamespace,\n} from \"./types\";\n\nconst logger = createLogger(\"agentx/LocalClient\");\n\n/**\n * LocalClient - Embedded runtime implementation\n */\nexport class LocalClient implements AgentX {\n private readonly runtime: AgentXRuntime;\n private commandHandler: CommandHandler | null = null;\n private isDisposed = false;\n\n readonly container: ContainerNamespace;\n readonly image: ImageNamespace;\n readonly agent: AgentNamespace;\n readonly session: SessionNamespace;\n readonly presentation: PresentationNamespace;\n\n constructor(runtime: AgentXRuntime) {\n this.runtime = runtime;\n const platform = runtime.platform;\n\n this.container = createLocalContainers(platform);\n this.image = createLocalImages(platform);\n this.agent = createLocalAgents(runtime);\n this.session = createLocalSessions(runtime);\n this.presentation = createPresentations(this);\n\n logger.info(\"LocalClient initialized\");\n }\n\n // ==================== Properties ====================\n\n get connected(): boolean {\n return !this.isDisposed;\n }\n\n get events(): EventBus {\n return this.runtime.platform.eventBus;\n }\n\n // ==================== Event Subscription ====================\n\n on<T extends string>(type: T, handler: BusEventHandler<BusEvent & { type: T }>): Unsubscribe {\n return this.runtime.platform.eventBus.on(type, handler);\n }\n\n onAny(handler: BusEventHandler): Unsubscribe {\n return this.runtime.platform.eventBus.onAny(handler);\n }\n\n subscribe(_sessionId: string): void {\n // No-op for local mode - already subscribed via eventBus\n }\n\n // ==================== Error Handling ====================\n\n onError(handler: (error: AgentXError) => void): Unsubscribe {\n return this.runtime.platform.eventBus.on(\"agentx_error\", (event) => {\n handler(event.data as AgentXError);\n });\n }\n\n // ==================== RPC ====================\n\n async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {\n if (!this.commandHandler) {\n this.commandHandler = new CommandHandler(this.runtime);\n }\n const result = await this.commandHandler.handle(method as RpcMethod, params);\n if (result.success) {\n return result.data as T;\n }\n throw new Error(result.message);\n }\n\n // ==================== Lifecycle ====================\n\n async disconnect(): Promise<void> {\n // No-op for local mode\n }\n\n async dispose(): Promise<void> {\n if (this.isDisposed) return;\n await this.runtime.shutdown();\n this.isDisposed = true;\n logger.info(\"LocalClient disposed\");\n }\n}\n","/**\n * Agent namespace factories\n */\n\nimport type { RpcClient, RpcMethod } from \"@agentxjs/core/network\";\nimport type { AgentXRuntime } from \"@agentxjs/core/runtime\";\nimport type {\n AgentCreateResponse,\n AgentGetResponse,\n AgentListResponse,\n AgentNamespace,\n BaseResponse,\n} from \"../types\";\n\n/**\n * Create local agent namespace backed by embedded runtime\n */\nexport function createLocalAgents(runtime: AgentXRuntime): AgentNamespace {\n return {\n async create(params: { imageId: string; agentId?: string }): Promise<AgentCreateResponse> {\n // Reuse existing running agent for this image\n const existingAgent = runtime\n .getAgents()\n .find((a) => a.imageId === params.imageId && a.lifecycle === \"running\");\n\n if (existingAgent) {\n return {\n agentId: existingAgent.agentId,\n imageId: existingAgent.imageId,\n containerId: existingAgent.containerId,\n sessionId: existingAgent.sessionId,\n requestId: \"\",\n };\n }\n\n const agent = await runtime.createAgent({\n imageId: params.imageId,\n agentId: params.agentId,\n });\n\n return {\n agentId: agent.agentId,\n imageId: agent.imageId,\n containerId: agent.containerId,\n sessionId: agent.sessionId,\n requestId: \"\",\n };\n },\n\n async get(agentId: string): Promise<AgentGetResponse> {\n const agent = runtime.getAgent(agentId);\n return {\n agent: agent\n ? {\n agentId: agent.agentId,\n imageId: agent.imageId,\n containerId: agent.containerId,\n sessionId: agent.sessionId,\n lifecycle: agent.lifecycle,\n }\n : null,\n exists: !!agent,\n requestId: \"\",\n };\n },\n\n async list(containerId?: string): Promise<AgentListResponse> {\n const agents = containerId ? runtime.getAgentsByContainer(containerId) : runtime.getAgents();\n\n return {\n agents: agents.map((a) => ({\n agentId: a.agentId,\n imageId: a.imageId,\n containerId: a.containerId,\n sessionId: a.sessionId,\n lifecycle: a.lifecycle,\n })),\n requestId: \"\",\n };\n },\n\n async destroy(agentId: string): Promise<BaseResponse> {\n const agent = runtime.getAgent(agentId);\n if (agent) {\n await runtime.destroyAgent(agentId);\n }\n return { requestId: \"\" };\n },\n };\n}\n\n/**\n * Create remote agent namespace backed by RPC client\n */\nexport function createRemoteAgents(rpcClient: RpcClient): AgentNamespace {\n return {\n async create(params: { imageId: string; agentId?: string }): Promise<AgentCreateResponse> {\n // Agent creation via image.run RPC\n const result = await rpcClient.call<AgentCreateResponse>(\"image.run\" as RpcMethod, {\n imageId: params.imageId,\n agentId: params.agentId,\n });\n return { ...result, requestId: \"\" };\n },\n\n async get(agentId: string): Promise<AgentGetResponse> {\n const result = await rpcClient.call<AgentGetResponse>(\"agent.get\", { agentId });\n return { ...result, requestId: \"\" };\n },\n\n async list(containerId?: string): Promise<AgentListResponse> {\n const result = await rpcClient.call<AgentListResponse>(\"agent.list\", { containerId });\n return { ...result, requestId: \"\" };\n },\n\n async destroy(agentId: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"agent.destroy\", { agentId });\n return { ...result, requestId: \"\" };\n },\n };\n}\n","/**\n * Container namespace factories\n */\n\nimport type { RpcClient } from \"@agentxjs/core/network\";\nimport type { AgentXPlatform } from \"@agentxjs/core/runtime\";\nimport type {\n ContainerCreateResponse,\n ContainerGetResponse,\n ContainerListResponse,\n ContainerNamespace,\n} from \"../types\";\n\n/**\n * Create local container namespace backed by embedded runtime\n */\nexport function createLocalContainers(platform: AgentXPlatform): ContainerNamespace {\n return {\n async create(containerId: string): Promise<ContainerCreateResponse> {\n const { getOrCreateContainer } = await import(\"@agentxjs/core/container\");\n const { containerRepository, imageRepository, sessionRepository } = platform;\n\n const container = await getOrCreateContainer(containerId, {\n containerRepository,\n imageRepository,\n sessionRepository,\n });\n\n return { containerId: container.containerId, requestId: \"\" };\n },\n\n async get(containerId: string): Promise<ContainerGetResponse> {\n const exists = await platform.containerRepository.containerExists(containerId);\n return { containerId, exists, requestId: \"\" };\n },\n\n async list(): Promise<ContainerListResponse> {\n const containers = await platform.containerRepository.findAllContainers();\n return { containerIds: containers.map((c) => c.containerId), requestId: \"\" };\n },\n };\n}\n\n/**\n * Create remote container namespace backed by RPC client\n */\nexport function createRemoteContainers(rpcClient: RpcClient): ContainerNamespace {\n return {\n async create(containerId: string): Promise<ContainerCreateResponse> {\n const result = await rpcClient.call<ContainerCreateResponse>(\"container.create\", {\n containerId,\n });\n return { ...result, requestId: \"\" };\n },\n\n async get(containerId: string): Promise<ContainerGetResponse> {\n const result = await rpcClient.call<ContainerGetResponse>(\"container.get\", {\n containerId,\n });\n return { ...result, requestId: \"\" };\n },\n\n async list(): Promise<ContainerListResponse> {\n const result = await rpcClient.call<ContainerListResponse>(\"container.list\", {});\n return { ...result, requestId: \"\" };\n },\n };\n}\n","/**\n * Image namespace factories\n */\n\nimport type { Message } from \"@agentxjs/core/agent\";\nimport type { RpcClient } from \"@agentxjs/core/network\";\nimport type { AgentXPlatform } from \"@agentxjs/core/runtime\";\nimport type {\n BaseResponse,\n ImageCreateResponse,\n ImageGetResponse,\n ImageListResponse,\n ImageNamespace,\n ImageUpdateResponse,\n} from \"../types\";\n\n/**\n * Create local image namespace backed by embedded runtime\n */\nexport function createLocalImages(platform: AgentXPlatform): ImageNamespace {\n return {\n async create(params: {\n containerId: string;\n name?: string;\n description?: string;\n systemPrompt?: string;\n mcpServers?: Record<string, unknown>;\n customData?: Record<string, unknown>;\n }): Promise<ImageCreateResponse> {\n const { imageRepository, sessionRepository } = platform;\n const { createImage } = await import(\"@agentxjs/core/image\");\n\n const image = await createImage(\n {\n containerId: params.containerId,\n name: params.name,\n description: params.description,\n systemPrompt: params.systemPrompt,\n mcpServers: params.mcpServers as any,\n customData: params.customData,\n },\n { imageRepository, sessionRepository }\n );\n\n return {\n record: image.toRecord(),\n __subscriptions: [image.sessionId],\n requestId: \"\",\n };\n },\n\n async get(imageId: string): Promise<ImageGetResponse> {\n const record = await platform.imageRepository.findImageById(imageId);\n return {\n record,\n __subscriptions: record?.sessionId ? [record.sessionId] : undefined,\n requestId: \"\",\n };\n },\n\n async list(containerId?: string): Promise<ImageListResponse> {\n const records = containerId\n ? await platform.imageRepository.findImagesByContainerId(containerId)\n : await platform.imageRepository.findAllImages();\n\n return {\n records,\n __subscriptions: records.map((r) => r.sessionId),\n requestId: \"\",\n };\n },\n\n async update(\n imageId: string,\n updates: {\n name?: string;\n description?: string;\n customData?: Record<string, unknown>;\n }\n ): Promise<ImageUpdateResponse> {\n const { loadImage } = await import(\"@agentxjs/core/image\");\n const { imageRepository, sessionRepository } = platform;\n\n const image = await loadImage(imageId, { imageRepository, sessionRepository });\n if (!image) {\n throw new Error(`Image not found: ${imageId}`);\n }\n\n const updated = await image.update(updates);\n return { record: updated.toRecord(), requestId: \"\" };\n },\n\n async delete(imageId: string): Promise<BaseResponse> {\n const { loadImage } = await import(\"@agentxjs/core/image\");\n const { imageRepository, sessionRepository } = platform;\n\n const image = await loadImage(imageId, { imageRepository, sessionRepository });\n if (image) {\n await image.delete();\n }\n\n return { requestId: \"\" };\n },\n\n async getMessages(imageId: string): Promise<Message[]> {\n const imageRecord = await platform.imageRepository.findImageById(imageId);\n if (!imageRecord) return [];\n return platform.sessionRepository.getMessages(imageRecord.sessionId);\n },\n };\n}\n\n/**\n * Create remote image namespace backed by RPC client\n */\nexport function createRemoteImages(\n rpcClient: RpcClient,\n subscribeFn: (sessionId: string) => void\n): ImageNamespace {\n return {\n async create(params: {\n containerId: string;\n name?: string;\n description?: string;\n systemPrompt?: string;\n mcpServers?: Record<string, unknown>;\n customData?: Record<string, unknown>;\n }): Promise<ImageCreateResponse> {\n const result = await rpcClient.call<ImageCreateResponse>(\"image.create\", params);\n\n // Auto subscribe to session events\n if (result.__subscriptions) {\n for (const sessionId of result.__subscriptions) {\n subscribeFn(sessionId);\n }\n }\n\n return { ...result, requestId: \"\" };\n },\n\n async get(imageId: string): Promise<ImageGetResponse> {\n const result = await rpcClient.call<ImageGetResponse>(\"image.get\", { imageId });\n\n // Auto subscribe\n if (result.__subscriptions) {\n for (const sessionId of result.__subscriptions) {\n subscribeFn(sessionId);\n }\n }\n\n return { ...result, requestId: \"\" };\n },\n\n async list(containerId?: string): Promise<ImageListResponse> {\n const result = await rpcClient.call<ImageListResponse>(\"image.list\", { containerId });\n\n // Auto subscribe\n if (result.__subscriptions) {\n for (const sessionId of result.__subscriptions) {\n subscribeFn(sessionId);\n }\n }\n\n return { ...result, requestId: \"\" };\n },\n\n async update(\n imageId: string,\n updates: {\n name?: string;\n description?: string;\n customData?: Record<string, unknown>;\n }\n ): Promise<ImageUpdateResponse> {\n const result = await rpcClient.call<ImageUpdateResponse>(\"image.update\", {\n imageId,\n updates,\n });\n return { ...result, requestId: \"\" };\n },\n\n async delete(imageId: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"image.delete\", { imageId });\n return { ...result, requestId: \"\" };\n },\n\n async getMessages(imageId: string): Promise<Message[]> {\n const result = await rpcClient.call<{ messages: Message[] }>(\"image.messages\", { imageId });\n return result.messages ?? [];\n },\n };\n}\n","/**\n * Presentation Types\n *\n * UI-friendly data model aggregated from stream events.\n * This implements the Presentation Model pattern.\n */\n\n// ============================================================================\n// Block Types - Basic content units\n// ============================================================================\n\n/**\n * Text block\n */\nexport interface TextBlock {\n type: \"text\";\n content: string;\n}\n\n/**\n * Tool block - represents a tool call and its result\n */\nexport interface ToolBlock {\n type: \"tool\";\n toolUseId: string;\n toolName: string;\n toolInput: Record<string, unknown>;\n toolResult?: string;\n status: \"pending\" | \"running\" | \"completed\" | \"error\";\n}\n\n/**\n * Image block\n */\nexport interface ImageBlock {\n type: \"image\";\n url: string;\n alt?: string;\n}\n\n/**\n * All block types\n */\nexport type Block = TextBlock | ToolBlock | ImageBlock;\n\n// ============================================================================\n// Conversation Types - A single turn in the conversation\n// ============================================================================\n\n/**\n * User conversation\n */\nexport interface UserConversation {\n role: \"user\";\n blocks: Block[];\n}\n\n/**\n * Token usage for a message (one LLM call / step)\n */\nexport interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n}\n\n/**\n * Assistant conversation\n */\nexport interface AssistantConversation {\n role: \"assistant\";\n blocks: Block[];\n isStreaming: boolean;\n /** Accumulated token usage across all steps in this conversation */\n usage?: TokenUsage;\n}\n\n/**\n * Error conversation\n */\nexport interface ErrorConversation {\n role: \"error\";\n message: string;\n}\n\n/**\n * All conversation types\n */\nexport type Conversation = UserConversation | AssistantConversation | ErrorConversation;\n\n// ============================================================================\n// Presentation State\n// ============================================================================\n\n/**\n * Presentation state - the complete UI state\n */\nexport interface PresentationState {\n /**\n * All completed conversations\n */\n conversations: Conversation[];\n\n /**\n * Current streaming conversation (null if not streaming)\n */\n streaming: AssistantConversation | null;\n\n /**\n * Current status\n */\n status: \"idle\" | \"thinking\" | \"responding\" | \"executing\";\n}\n\n/**\n * Initial presentation state\n */\nexport const initialPresentationState: PresentationState = {\n conversations: [],\n streaming: null,\n status: \"idle\",\n};\n","/**\n * Presentation Reducer\n *\n * Aggregates events into PresentationState.\n * Pure function: (state, event) => newState\n *\n * Event consumption strategy:\n * - Stream layer: message_start, text_delta, tool_use_start, tool_use_stop, message_stop\n * (for real-time streaming display)\n * - Message layer: tool_result_message\n * (for tool execution results — arrives after message_stop)\n *\n * Tool calls are stream-level blocks within the assistant turn,\n * matching the mainstream API pattern (Anthropic, OpenAI).\n */\n\nimport type {\n AssistantMessage,\n ErrorMessage,\n Message,\n ToolCallPart,\n ToolResultMessage,\n ToolResultOutput,\n UserMessage,\n} from \"@agentxjs/core/agent\";\nimport type { BusEvent } from \"@agentxjs/core/event\";\nimport type {\n AssistantConversation,\n Block,\n Conversation,\n PresentationState,\n TextBlock,\n TokenUsage,\n ToolBlock,\n} from \"./types\";\nimport { initialPresentationState } from \"./types\";\n\n// ============================================================================\n// Event Data Types\n// ============================================================================\n\ninterface MessageStartData {\n messageId?: string;\n model?: string;\n}\n\ninterface TextDeltaData {\n text: string;\n}\n\ninterface ToolUseStartData {\n toolCallId: string;\n toolName: string;\n}\n\ninterface ToolUseStopData {\n toolCallId: string;\n toolName: string;\n input: Record<string, unknown>;\n}\n\ninterface MessageDeltaData {\n usage?: {\n inputTokens: number;\n outputTokens: number;\n };\n}\n\ninterface MessageStopData {\n stopReason?: string;\n}\n\ninterface ErrorData {\n message: string;\n code?: string;\n}\n\n// ============================================================================\n// Reducer\n// ============================================================================\n\n/**\n * Reduce an event into presentation state.\n *\n * Consumes:\n * - Stream events: message_start, text_delta, tool_use_start, tool_use_stop, message_stop\n * - Message events: tool_result_message\n * - Error events: error\n */\nexport function presentationReducer(state: PresentationState, event: BusEvent): PresentationState {\n switch (event.type) {\n // Stream layer — real-time display\n case \"message_start\":\n return handleMessageStart(state, event.data as MessageStartData);\n\n case \"text_delta\":\n return handleTextDelta(state, event.data as TextDeltaData);\n\n case \"tool_use_start\":\n return handleToolUseStart(state, event.data as ToolUseStartData);\n\n case \"tool_use_stop\":\n return handleToolUseStop(state, event.data as ToolUseStopData);\n\n case \"message_delta\":\n return handleMessageDelta(state, event.data as MessageDeltaData);\n\n case \"message_stop\":\n return handleMessageStop(state, event.data as MessageStopData);\n\n // Message layer — tool results from Engine\n case \"tool_result_message\":\n return handleToolResultMessage(state, event.data as ToolResultMessage);\n\n case \"error\":\n return handleError(state, event.data as ErrorData);\n\n default:\n return state;\n }\n}\n\n// ============================================================================\n// Handlers\n// ============================================================================\n\nfunction handleMessageStart(state: PresentationState, _data: MessageStartData): PresentationState {\n // If streaming already exists (e.g. tool_use turn not yet flushed), flush it first\n let conversations = state.conversations;\n if (state.streaming && state.streaming.blocks.length > 0) {\n conversations = [...conversations, { ...state.streaming, isStreaming: false }];\n }\n\n const streaming: AssistantConversation = {\n role: \"assistant\",\n blocks: [],\n isStreaming: true,\n };\n\n return {\n ...state,\n conversations,\n streaming,\n status: \"thinking\",\n };\n}\n\nfunction handleTextDelta(state: PresentationState, data: TextDeltaData): PresentationState {\n if (!state.streaming) {\n return state;\n }\n\n const blocks = [...state.streaming.blocks];\n const lastBlock = blocks[blocks.length - 1];\n\n if (lastBlock && lastBlock.type === \"text\") {\n blocks[blocks.length - 1] = {\n ...lastBlock,\n content: lastBlock.content + data.text,\n };\n } else {\n blocks.push({\n type: \"text\",\n content: data.text,\n } as TextBlock);\n }\n\n return {\n ...state,\n streaming: {\n ...state.streaming,\n blocks,\n },\n status: \"responding\",\n };\n}\n\nfunction handleToolUseStart(state: PresentationState, data: ToolUseStartData): PresentationState {\n if (!state.streaming) {\n return state;\n }\n\n // Create a pending tool block — toolInput will be filled by tool_use_stop\n const toolBlock: ToolBlock = {\n type: \"tool\",\n toolUseId: data.toolCallId,\n toolName: data.toolName,\n toolInput: {},\n status: \"pending\",\n };\n\n return {\n ...state,\n streaming: {\n ...state.streaming,\n blocks: [...state.streaming.blocks, toolBlock],\n },\n status: \"executing\",\n };\n}\n\n/**\n * Handle tool_use_stop from stream layer.\n * Fills in the complete toolInput for the matching pending tool block.\n * The stream event carries the fully assembled input.\n */\nfunction handleToolUseStop(state: PresentationState, data: ToolUseStopData): PresentationState {\n if (!state.streaming) {\n return state;\n }\n\n const blocks = state.streaming.blocks.map((block): Block => {\n if (block.type === \"tool\" && block.toolUseId === data.toolCallId) {\n return {\n ...block,\n toolInput: data.input,\n status: \"running\",\n };\n }\n return block;\n });\n\n return {\n ...state,\n streaming: {\n ...state.streaming,\n blocks,\n },\n };\n}\n\nfunction handleMessageDelta(state: PresentationState, data: MessageDeltaData): PresentationState {\n if (!state.streaming || !data.usage) {\n return state;\n }\n\n const prev = state.streaming.usage;\n const usage: TokenUsage = {\n inputTokens: (prev?.inputTokens ?? 0) + data.usage.inputTokens,\n outputTokens: (prev?.outputTokens ?? 0) + data.usage.outputTokens,\n };\n\n return {\n ...state,\n streaming: {\n ...state.streaming,\n usage,\n },\n };\n}\n\nfunction handleMessageStop(state: PresentationState, data: MessageStopData): PresentationState {\n if (!state.streaming) {\n return state;\n }\n\n // tool_use stop → don't flush, tool results are still incoming\n if (data.stopReason === \"tool_use\") {\n return {\n ...state,\n status: \"executing\",\n };\n }\n\n // end_turn / max_tokens / etc → flush streaming to conversations\n const completedConversation: AssistantConversation = {\n ...state.streaming,\n isStreaming: false,\n };\n\n return {\n ...state,\n conversations: [...state.conversations, completedConversation],\n streaming: null,\n status: \"idle\",\n };\n}\n\n/**\n * Handle tool_result_message from Engine layer.\n * Fills in the toolResult for the matching tool block.\n *\n * Note: tool_result_message arrives after message_stop(tool_use),\n * but streaming is kept alive (not flushed) during tool_use turns.\n */\nfunction handleToolResultMessage(\n state: PresentationState,\n data: ToolResultMessage\n): PresentationState {\n if (!state.streaming) {\n return state;\n }\n\n const toolCallId = data.toolCallId;\n const blocks = state.streaming.blocks.map((block): Block => {\n if (block.type === \"tool\" && block.toolUseId === toolCallId) {\n return {\n ...block,\n toolResult: formatToolResultOutput(data.toolResult.output),\n status:\n data.toolResult.output.type === \"error-text\" ||\n data.toolResult.output.type === \"error-json\" ||\n data.toolResult.output.type === \"execution-denied\"\n ? \"error\"\n : \"completed\",\n };\n }\n return block;\n });\n\n return {\n ...state,\n streaming: {\n ...state.streaming,\n blocks,\n },\n status: \"responding\",\n };\n}\n\nfunction handleError(state: PresentationState, data: ErrorData): PresentationState {\n return {\n ...state,\n conversations: [\n ...state.conversations,\n {\n role: \"error\",\n message: data.message,\n },\n ],\n streaming: null,\n status: \"idle\",\n };\n}\n\n// ============================================================================\n// Helper: Add user conversation\n// ============================================================================\n\nexport function addUserConversation(state: PresentationState, content: string): PresentationState {\n return {\n ...state,\n conversations: [\n ...state.conversations,\n {\n role: \"user\",\n blocks: [{ type: \"text\", content }],\n },\n ],\n };\n}\n\nexport function createInitialState(): PresentationState {\n return { ...initialPresentationState };\n}\n\n// ============================================================================\n// Helper: Format tool result output\n// ============================================================================\n\nfunction formatToolResultOutput(output: ToolResultOutput): string {\n switch (output.type) {\n case \"text\":\n case \"error-text\":\n return output.value;\n case \"json\":\n case \"error-json\":\n return JSON.stringify(output.value);\n case \"execution-denied\":\n return output.reason ?? \"Execution denied\";\n case \"content\":\n return output.value\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\");\n }\n}\n\n// ============================================================================\n// Message → Conversation Converter\n// ============================================================================\n\n/**\n * Convert persisted Messages to Presentation Conversations.\n *\n * Groups consecutive assistant + tool-result messages\n * into a single AssistantConversation.\n *\n * Tool calls are now part of AssistantMessage.content (as ToolCallPart),\n * so we extract them directly from the assistant message.\n */\nexport function messagesToConversations(messages: Message[]): Conversation[] {\n const conversations: Conversation[] = [];\n let currentAssistant: AssistantConversation | null = null;\n\n function flushAssistant() {\n if (currentAssistant && currentAssistant.blocks.length > 0) {\n conversations.push(currentAssistant);\n }\n currentAssistant = null;\n }\n\n for (const msg of messages) {\n switch (msg.subtype) {\n case \"user\": {\n flushAssistant();\n const m = msg as UserMessage;\n const text =\n typeof m.content === \"string\"\n ? m.content\n : m.content\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\");\n conversations.push({\n role: \"user\",\n blocks: [{ type: \"text\", content: text }],\n });\n break;\n }\n\n case \"assistant\": {\n if (!currentAssistant) {\n currentAssistant = { role: \"assistant\", blocks: [], isStreaming: false };\n }\n const m = msg as AssistantMessage;\n if (typeof m.content === \"string\") {\n if (m.content) {\n currentAssistant.blocks.push({ type: \"text\", content: m.content } as TextBlock);\n }\n } else {\n // Extract text and tool call parts from content\n for (const part of m.content) {\n if (part.type === \"text\") {\n if (part.text) {\n currentAssistant.blocks.push({ type: \"text\", content: part.text } as TextBlock);\n }\n } else if (part.type === \"tool-call\") {\n const tc = part as ToolCallPart;\n currentAssistant.blocks.push({\n type: \"tool\",\n toolUseId: tc.id,\n toolName: tc.name,\n toolInput: tc.input,\n status: \"completed\",\n } as ToolBlock);\n }\n }\n }\n break;\n }\n\n case \"tool-result\": {\n const m = msg as ToolResultMessage;\n if (currentAssistant) {\n for (const block of currentAssistant.blocks) {\n if (block.type === \"tool\" && block.toolUseId === m.toolResult.id) {\n block.toolResult = formatToolResultOutput(m.toolResult.output);\n block.status =\n m.toolResult.output.type === \"error-text\" ||\n m.toolResult.output.type === \"error-json\" ||\n m.toolResult.output.type === \"execution-denied\"\n ? \"error\"\n : \"completed\";\n break;\n }\n }\n }\n break;\n }\n\n case \"error\": {\n flushAssistant();\n const m = msg as ErrorMessage;\n conversations.push({\n role: \"error\",\n message: m.content,\n });\n break;\n }\n }\n }\n\n flushAssistant();\n return conversations;\n}\n","/**\n * Presentation Class\n *\n * High-level API for UI integration.\n * Wraps AgentX client and provides presentation state management.\n */\n\nimport type { BusEvent, Unsubscribe } from \"@agentxjs/core/event\";\nimport type { AgentX } from \"../types\";\nimport { addUserConversation, createInitialState, presentationReducer } from \"./reducer\";\nimport type { Conversation, PresentationState } from \"./types\";\nimport { initialPresentationState } from \"./types\";\n\n/**\n * Presentation update handler\n */\nexport type PresentationUpdateHandler = (state: PresentationState) => void;\n\n/**\n * Presentation error handler\n */\nexport type PresentationErrorHandler = (error: Error) => void;\n\n/**\n * Presentation options\n */\nexport interface PresentationOptions {\n /**\n * Called on every state update\n */\n onUpdate?: PresentationUpdateHandler;\n\n /**\n * Called on errors\n */\n onError?: PresentationErrorHandler;\n}\n\n/**\n * Presentation - UI-friendly wrapper for AgentX\n */\nexport class Presentation {\n private agentx: AgentX;\n private agentId: string;\n private state: PresentationState;\n private updateHandlers: Set<PresentationUpdateHandler> = new Set();\n private errorHandlers: Set<PresentationErrorHandler> = new Set();\n private eventUnsubscribe: Unsubscribe | null = null;\n\n constructor(\n agentx: AgentX,\n agentId: string,\n options?: PresentationOptions,\n initialConversations?: Conversation[]\n ) {\n this.agentx = agentx;\n this.agentId = agentId;\n this.state = initialConversations?.length\n ? { ...initialPresentationState, conversations: initialConversations }\n : createInitialState();\n\n // Register initial handlers\n if (options?.onUpdate) {\n this.updateHandlers.add(options.onUpdate);\n }\n if (options?.onError) {\n this.errorHandlers.add(options.onError);\n }\n\n // Subscribe to all events\n this.subscribeToEvents();\n }\n\n /**\n * Get current state\n */\n getState(): PresentationState {\n return this.state;\n }\n\n /**\n * Subscribe to state updates\n */\n onUpdate(handler: PresentationUpdateHandler): Unsubscribe {\n this.updateHandlers.add(handler);\n // Immediately call with current state\n handler(this.state);\n return () => {\n this.updateHandlers.delete(handler);\n };\n }\n\n /**\n * Subscribe to errors\n */\n onError(handler: PresentationErrorHandler): Unsubscribe {\n this.errorHandlers.add(handler);\n return () => {\n this.errorHandlers.delete(handler);\n };\n }\n\n /**\n * Send a message\n */\n async send(content: string): Promise<void> {\n // Add user conversation\n this.state = addUserConversation(this.state, content);\n this.notify();\n\n try {\n // Send message via agentx\n await this.agentx.session.send(this.agentId, content);\n } catch (error) {\n this.notifyError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n /**\n * Interrupt current response\n */\n async interrupt(): Promise<void> {\n try {\n await this.agentx.session.interrupt(this.agentId);\n } catch (error) {\n this.notifyError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n /**\n * Reset state\n */\n reset(): void {\n this.state = createInitialState();\n this.notify();\n }\n\n /**\n * Dispose and cleanup\n */\n dispose(): void {\n if (this.eventUnsubscribe) {\n this.eventUnsubscribe();\n this.eventUnsubscribe = null;\n }\n this.updateHandlers.clear();\n this.errorHandlers.clear();\n }\n\n // ==================== Private ====================\n\n private subscribeToEvents(): void {\n // Subscribe to all events and filter by agentId\n this.eventUnsubscribe = this.agentx.onAny((event: BusEvent) => {\n // Filter events for this agent (if context is available)\n // Note: Events from server may or may not include context with agentId\n const eventWithContext = event as BusEvent & { context?: { agentId?: string } };\n const eventAgentId = eventWithContext.context?.agentId;\n\n // Only filter if event has agentId and it doesn't match\n if (eventAgentId && eventAgentId !== this.agentId) {\n return;\n }\n\n // Reduce event into state\n const newState = presentationReducer(this.state, event);\n if (newState !== this.state) {\n this.state = newState;\n this.notify();\n }\n });\n }\n\n private notify(): void {\n for (const handler of this.updateHandlers) {\n try {\n handler(this.state);\n } catch (error) {\n console.error(\"Presentation update handler error:\", error);\n }\n }\n }\n\n private notifyError(error: Error): void {\n for (const handler of this.errorHandlers) {\n try {\n handler(error);\n } catch (e) {\n console.error(\"Presentation error handler error:\", e);\n }\n }\n }\n}\n","/**\n * Presentation namespace factory\n *\n * Single factory for both local and remote modes —\n * Presentation only depends on the AgentX interface.\n */\n\nimport { messagesToConversations, Presentation, type PresentationOptions } from \"../presentation\";\nimport type { AgentX, PresentationNamespace } from \"../types\";\n\n/**\n * Create presentation namespace backed by any AgentX client\n */\nexport function createPresentations(agentx: AgentX): PresentationNamespace {\n return {\n async create(agentId: string, options?: PresentationOptions): Promise<Presentation> {\n const messages = await agentx.session.getMessages(agentId);\n const conversations = messagesToConversations(messages);\n return new Presentation(agentx, agentId, options, conversations);\n },\n };\n}\n","/**\n * Session namespace factories (messaging)\n */\n\nimport type { Message, UserContentPart } from \"@agentxjs/core/agent\";\nimport type { RpcClient } from \"@agentxjs/core/network\";\nimport type { AgentXRuntime } from \"@agentxjs/core/runtime\";\nimport type { AgentInfo, BaseResponse, MessageSendResponse, SessionNamespace } from \"../types\";\n\n/**\n * Create local session namespace backed by embedded runtime\n */\nexport function createLocalSessions(runtime: AgentXRuntime): SessionNamespace {\n return {\n async send(agentId: string, content: string | unknown[]): Promise<MessageSendResponse> {\n await runtime.receive(agentId, content as string | UserContentPart[]);\n return { agentId, requestId: \"\" };\n },\n\n async interrupt(agentId: string): Promise<BaseResponse> {\n runtime.interrupt(agentId);\n return { requestId: \"\" };\n },\n\n async getMessages(agentId: string): Promise<Message[]> {\n const agent = runtime.getAgent(agentId);\n if (!agent) return [];\n return runtime.platform.sessionRepository.getMessages(agent.sessionId);\n },\n };\n}\n\n/**\n * Create remote session namespace backed by RPC client\n */\nexport function createRemoteSessions(rpcClient: RpcClient): SessionNamespace {\n return {\n async send(agentId: string, content: string | unknown[]): Promise<MessageSendResponse> {\n const result = await rpcClient.call<MessageSendResponse>(\"message.send\", {\n agentId,\n content,\n });\n return { ...result, requestId: \"\" };\n },\n\n async interrupt(agentId: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"agent.interrupt\", { agentId });\n return { ...result, requestId: \"\" };\n },\n\n async getMessages(agentId: string): Promise<Message[]> {\n const agentRes = await rpcClient.call<{ agent: AgentInfo | null }>(\"agent.get\", { agentId });\n if (!agentRes.agent) return [];\n const msgRes = await rpcClient.call<{ messages: Message[] }>(\"image.messages\", {\n imageId: agentRes.agent.imageId,\n });\n return msgRes.messages ?? [];\n },\n };\n}\n","/**\n * RemoteClient - AgentX client for remote server\n *\n * Uses RpcClient from @agentxjs/core/network for JSON-RPC communication.\n * This class focuses on business logic, not protocol details.\n */\n\nimport type { AgentXError } from \"@agentxjs/core/error\";\nimport type { BusEvent, BusEventHandler, EventBus, Unsubscribe } from \"@agentxjs/core/event\";\nimport { EventBusImpl } from \"@agentxjs/core/event\";\nimport { RpcClient } from \"@agentxjs/core/network\";\nimport { createLogger } from \"commonxjs/logger\";\nimport { createRemoteAgents } from \"./namespaces/agents\";\nimport { createRemoteContainers } from \"./namespaces/containers\";\nimport { createRemoteImages } from \"./namespaces/images\";\nimport { createPresentations } from \"./namespaces/presentations\";\nimport { createRemoteSessions } from \"./namespaces/sessions\";\nimport type {\n AgentNamespace,\n AgentX,\n ContainerNamespace,\n ImageNamespace,\n PresentationNamespace,\n RemoteClientConfig,\n SessionNamespace,\n} from \"./types\";\n\nconst logger = createLogger(\"agentx/RemoteClient\");\n\n/**\n * RemoteClient implementation using JSON-RPC 2.0\n */\nexport class RemoteClient implements AgentX {\n private readonly config: RemoteClientConfig;\n private readonly eventBus: EventBus;\n private readonly rpcClient: RpcClient;\n\n readonly container: ContainerNamespace;\n readonly image: ImageNamespace;\n readonly agent: AgentNamespace;\n readonly session: SessionNamespace;\n readonly presentation: PresentationNamespace;\n\n constructor(config: RemoteClientConfig) {\n this.config = config;\n this.eventBus = new EventBusImpl();\n\n // Create RPC client (WebSocket factory from platform if available)\n this.rpcClient = new RpcClient({\n url: config.serverUrl,\n createWebSocket: config.customPlatform?.channelClient,\n timeout: config.timeout ?? 30000,\n autoReconnect: config.autoReconnect ?? true,\n headers: config.headers as Record<string, string> | undefined,\n debug: false,\n });\n\n // Forward stream events to internal event bus\n this.rpcClient.onStreamEvent((topic, event) => {\n logger.debug(\"Received stream event\", { topic, type: event.type });\n this.eventBus.emit(event as BusEvent);\n });\n\n // Assemble namespaces\n this.container = createRemoteContainers(this.rpcClient);\n this.image = createRemoteImages(this.rpcClient, (sessionId) => this.subscribe(sessionId));\n this.agent = createRemoteAgents(this.rpcClient);\n this.session = createRemoteSessions(this.rpcClient);\n this.presentation = createPresentations(this);\n }\n\n // ==================== Properties ====================\n\n get connected(): boolean {\n return this.rpcClient.connected;\n }\n\n get events(): EventBus {\n return this.eventBus;\n }\n\n // ==================== Connection ====================\n\n async connect(): Promise<void> {\n await this.rpcClient.connect();\n logger.info(\"Connected to server\", { url: this.config.serverUrl });\n }\n\n async disconnect(): Promise<void> {\n this.rpcClient.disconnect();\n logger.info(\"Disconnected from server\");\n }\n\n async dispose(): Promise<void> {\n this.rpcClient.dispose();\n this.eventBus.destroy();\n logger.info(\"RemoteClient disposed\");\n }\n\n // ==================== Event Subscription ====================\n\n on<T extends string>(type: T, handler: BusEventHandler<BusEvent & { type: T }>): Unsubscribe {\n return this.eventBus.on(type, handler);\n }\n\n onAny(handler: BusEventHandler): Unsubscribe {\n return this.eventBus.onAny(handler);\n }\n\n subscribe(sessionId: string): void {\n this.rpcClient.subscribe(sessionId);\n logger.debug(\"Subscribed to session\", { sessionId });\n }\n\n // ==================== Error Handling ====================\n\n onError(handler: (error: AgentXError) => void): Unsubscribe {\n return this.eventBus.on(\"agentx_error\", (event) => {\n handler(event.data as AgentXError);\n });\n }\n\n // ==================== RPC ====================\n\n async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {\n return this.rpcClient.call<T>(method, params);\n }\n}\n"],"mappings":"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","names":["createLogger","logger","createLogger","createServer"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentxjs",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "AgentX Client SDK - Local and remote AI agent management",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,14 +25,11 @@
25
25
  "bdd:developer": "bdd --tags @developer"
26
26
  },
27
27
  "dependencies": {
28
- "@agentxjs/core": "^2.1.0",
29
- "@deepracticex/logger": "^1.2.0",
30
- "reconnecting-websocket": "^4.4.0",
31
- "ws": "^8.18.0"
28
+ "@agentxjs/core": "^2.2.0",
29
+ "@deepracticex/logger": "^1.2.0"
32
30
  },
33
31
  "devDependencies": {
34
- "@agentxjs/devtools": "^2.1.0",
35
- "@types/ws": "^8.5.10",
32
+ "@agentxjs/devtools": "^2.2.0",
36
33
  "tsx": "^4.19.0",
37
34
  "typescript": "^5.3.3"
38
35
  },
@@ -5,6 +5,7 @@
5
5
  * Implements the same AgentX interface as RemoteClient.
6
6
  */
7
7
 
8
+ import type { AgentXError } from "@agentxjs/core/error";
8
9
  import type { BusEvent, BusEventHandler, EventBus, Unsubscribe } from "@agentxjs/core/event";
9
10
  import type { RpcMethod } from "@agentxjs/core/network";
10
11
  import type { AgentXRuntime } from "@agentxjs/core/runtime";
@@ -77,6 +78,14 @@ export class LocalClient implements AgentX {
77
78
  // No-op for local mode - already subscribed via eventBus
78
79
  }
79
80
 
81
+ // ==================== Error Handling ====================
82
+
83
+ onError(handler: (error: AgentXError) => void): Unsubscribe {
84
+ return this.runtime.platform.eventBus.on("agentx_error", (event) => {
85
+ handler(event.data as AgentXError);
86
+ });
87
+ }
88
+
80
89
  // ==================== RPC ====================
81
90
 
82
91
  async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {
@@ -5,6 +5,7 @@
5
5
  * This class focuses on business logic, not protocol details.
6
6
  */
7
7
 
8
+ import type { AgentXError } from "@agentxjs/core/error";
8
9
  import type { BusEvent, BusEventHandler, EventBus, Unsubscribe } from "@agentxjs/core/event";
9
10
  import { EventBusImpl } from "@agentxjs/core/event";
10
11
  import { RpcClient } from "@agentxjs/core/network";
@@ -111,6 +112,14 @@ export class RemoteClient implements AgentX {
111
112
  logger.debug("Subscribed to session", { sessionId });
112
113
  }
113
114
 
115
+ // ==================== Error Handling ====================
116
+
117
+ onError(handler: (error: AgentXError) => void): Unsubscribe {
118
+ return this.eventBus.on("agentx_error", (event) => {
119
+ handler(event.data as AgentXError);
120
+ });
121
+ }
122
+
114
123
  // ==================== RPC ====================
115
124
 
116
125
  async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {
package/src/index.ts CHANGED
@@ -6,9 +6,9 @@
6
6
  * @example Local mode
7
7
  * ```typescript
8
8
  * import { createAgentX } from "agentxjs";
9
- * import { node } from "@agentxjs/node-platform";
9
+ * import { nodePlatform } from "@agentxjs/node-platform";
10
10
  *
11
- * const ax = createAgentX(node({ createDriver }));
11
+ * const ax = createAgentX(nodePlatform({ createDriver }));
12
12
  * await ax.agent.create({ imageId: "..." });
13
13
  * ```
14
14
  *
@@ -20,7 +20,7 @@
20
20
  *
21
21
  * @example Server mode
22
22
  * ```typescript
23
- * const ax = createAgentX(node({ createDriver }));
23
+ * const ax = createAgentX(nodePlatform({ createDriver }));
24
24
  * const server = await ax.serve({ port: 5200 });
25
25
  * ```
26
26
  */
@@ -106,6 +106,10 @@ export function createAgentX(config?: PlatformConfig): AgentXBuilder {
106
106
  getLocalClient().subscribe(sessionId);
107
107
  },
108
108
 
109
+ onError(handler) {
110
+ return getLocalClient().onError(handler);
111
+ },
112
+
109
113
  async disconnect() {
110
114
  await localClient?.disconnect();
111
115
  },
@@ -155,6 +159,9 @@ export function createAgentX(config?: PlatformConfig): AgentXBuilder {
155
159
  };
156
160
  }
157
161
 
162
+ export type { AgentXErrorCategory, AgentXErrorContext } from "@agentxjs/core/error";
163
+ // Re-export error types
164
+ export { AgentXError, AgentXErrorCode } from "@agentxjs/core/error";
158
165
  // Re-export server
159
166
  export { CommandHandler } from "./CommandHandler";
160
167
  // Re-export Presentation types and classes
package/src/types.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  */
4
4
 
5
5
  import type { Message } from "@agentxjs/core/agent";
6
+ import type { AgentXError } from "@agentxjs/core/error";
6
7
  import type { BusEvent, BusEventHandler, EventBus, Unsubscribe } from "@agentxjs/core/event";
7
8
  import type { AgentXPlatform } from "@agentxjs/core/runtime";
8
9
  import type { Presentation, PresentationOptions } from "./presentation";
@@ -334,6 +335,25 @@ export interface AgentX {
334
335
  onAny(handler: BusEventHandler): Unsubscribe;
335
336
  subscribe(sessionId: string): void;
336
337
 
338
+ // ==================== Error Handling ====================
339
+
340
+ /**
341
+ * Top-level error handler — receives all AgentXError instances from any layer.
342
+ *
343
+ * Independent of `on("error", ...)` (stream events) and `presentation.onError` (UI errors).
344
+ *
345
+ * @example
346
+ * ```typescript
347
+ * ax.onError((error) => {
348
+ * console.error(`[${error.category}] ${error.code}: ${error.message}`);
349
+ * if (!error.recoverable) {
350
+ * // Circuit is open, stop sending requests
351
+ * }
352
+ * });
353
+ * ```
354
+ */
355
+ onError(handler: (error: AgentXError) => void): Unsubscribe;
356
+
337
357
  // ==================== RPC ====================
338
358
 
339
359
  /**