agentxjs 1.9.9-dev → 2.0.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/dist/index.js CHANGED
@@ -1,174 +1,281 @@
1
1
  // src/RemoteClient.ts
2
2
  import { EventBusImpl } from "@agentxjs/core/event";
3
3
  import { RpcClient } from "@agentxjs/core/network";
4
+ import { createLogger } from "commonxjs/logger";
4
5
 
5
- // ../../node_modules/commonxjs/dist/logger/index.js
6
- var ConsoleLogger = class _ConsoleLogger {
7
- name;
8
- level;
9
- colors;
10
- timestamps;
11
- static COLORS = {
12
- DEBUG: "\x1B[36m",
13
- INFO: "\x1B[32m",
14
- WARN: "\x1B[33m",
15
- ERROR: "\x1B[31m",
16
- RESET: "\x1B[0m"
17
- };
18
- constructor(name, options = {}) {
19
- this.name = name;
20
- this.level = options.level ?? "info";
21
- this.colors = options.colors ?? this.isNodeEnvironment();
22
- this.timestamps = options.timestamps ?? true;
23
- }
24
- debug(message, context) {
25
- if (this.isDebugEnabled()) {
26
- this.log("DEBUG", message, context);
27
- }
28
- }
29
- info(message, context) {
30
- if (this.isInfoEnabled()) {
31
- this.log("INFO", message, context);
6
+ // src/namespaces/containers.ts
7
+ function createLocalContainers(platform) {
8
+ return {
9
+ async create(containerId) {
10
+ const { getOrCreateContainer } = await import("@agentxjs/core/container");
11
+ const { containerRepository, imageRepository, sessionRepository } = platform;
12
+ const container = await getOrCreateContainer(containerId, {
13
+ containerRepository,
14
+ imageRepository,
15
+ sessionRepository
16
+ });
17
+ return { containerId: container.containerId, requestId: "" };
18
+ },
19
+ async get(containerId) {
20
+ const exists = await platform.containerRepository.containerExists(containerId);
21
+ return { containerId, exists, requestId: "" };
22
+ },
23
+ async list() {
24
+ const containers = await platform.containerRepository.findAllContainers();
25
+ return { containerIds: containers.map((c) => c.containerId), requestId: "" };
32
26
  }
33
- }
34
- warn(message, context) {
35
- if (this.isWarnEnabled()) {
36
- this.log("WARN", message, context);
27
+ };
28
+ }
29
+ function createRemoteContainers(rpcClient) {
30
+ return {
31
+ async create(containerId) {
32
+ const result = await rpcClient.call("container.create", {
33
+ containerId
34
+ });
35
+ return { ...result, requestId: "" };
36
+ },
37
+ async get(containerId) {
38
+ const result = await rpcClient.call("container.get", {
39
+ containerId
40
+ });
41
+ return { ...result, requestId: "" };
42
+ },
43
+ async list() {
44
+ const result = await rpcClient.call("container.list", {});
45
+ return { ...result, requestId: "" };
37
46
  }
38
- }
39
- error(message, context) {
40
- if (this.isErrorEnabled()) {
41
- if (message instanceof Error) {
42
- this.log("ERROR", message.message, { ...context, stack: message.stack });
43
- } else {
44
- this.log("ERROR", message, context);
47
+ };
48
+ }
49
+
50
+ // src/namespaces/images.ts
51
+ function createLocalImages(platform) {
52
+ return {
53
+ async create(params) {
54
+ const { imageRepository, sessionRepository } = platform;
55
+ const { createImage } = await import("@agentxjs/core/image");
56
+ const image = await createImage(
57
+ {
58
+ containerId: params.containerId,
59
+ name: params.name,
60
+ description: params.description,
61
+ systemPrompt: params.systemPrompt,
62
+ mcpServers: params.mcpServers,
63
+ customData: params.customData
64
+ },
65
+ { imageRepository, sessionRepository }
66
+ );
67
+ return {
68
+ record: image.toRecord(),
69
+ __subscriptions: [image.sessionId],
70
+ requestId: ""
71
+ };
72
+ },
73
+ async get(imageId) {
74
+ const record = await platform.imageRepository.findImageById(imageId);
75
+ return {
76
+ record,
77
+ __subscriptions: record?.sessionId ? [record.sessionId] : void 0,
78
+ requestId: ""
79
+ };
80
+ },
81
+ async list(containerId) {
82
+ const records = containerId ? await platform.imageRepository.findImagesByContainerId(containerId) : await platform.imageRepository.findAllImages();
83
+ return {
84
+ records,
85
+ __subscriptions: records.map((r) => r.sessionId),
86
+ requestId: ""
87
+ };
88
+ },
89
+ async update(imageId, updates) {
90
+ const { loadImage } = await import("@agentxjs/core/image");
91
+ const { imageRepository, sessionRepository } = platform;
92
+ const image = await loadImage(imageId, { imageRepository, sessionRepository });
93
+ if (!image) {
94
+ throw new Error(`Image not found: ${imageId}`);
45
95
  }
96
+ const updated = await image.update(updates);
97
+ return { record: updated.toRecord(), requestId: "" };
98
+ },
99
+ async delete(imageId) {
100
+ const { loadImage } = await import("@agentxjs/core/image");
101
+ const { imageRepository, sessionRepository } = platform;
102
+ const image = await loadImage(imageId, { imageRepository, sessionRepository });
103
+ if (image) {
104
+ await image.delete();
105
+ }
106
+ return { requestId: "" };
46
107
  }
47
- }
48
- isDebugEnabled() {
49
- return this.getLevelValue(this.level) <= this.getLevelValue("debug");
50
- }
51
- isInfoEnabled() {
52
- return this.getLevelValue(this.level) <= this.getLevelValue("info");
53
- }
54
- isWarnEnabled() {
55
- return this.getLevelValue(this.level) <= this.getLevelValue("warn");
56
- }
57
- isErrorEnabled() {
58
- return this.getLevelValue(this.level) <= this.getLevelValue("error");
59
- }
60
- getLevelValue(level) {
61
- const levels = {
62
- debug: 0,
63
- info: 1,
64
- warn: 2,
65
- error: 3,
66
- silent: 4
67
- };
68
- return levels[level];
69
- }
70
- log(level, message, context) {
71
- const parts = [];
72
- if (this.timestamps) {
73
- parts.push((/* @__PURE__ */ new Date()).toISOString());
74
- }
75
- if (this.colors) {
76
- const color = _ConsoleLogger.COLORS[level];
77
- parts.push(`${color}${level.padEnd(5)}${_ConsoleLogger.COLORS.RESET}`);
78
- } else {
79
- parts.push(level.padEnd(5));
80
- }
81
- parts.push(`[${this.name}]`);
82
- parts.push(message);
83
- const logLine = parts.join(" ");
84
- const consoleMethod = this.getConsoleMethod(level);
85
- if (context && Object.keys(context).length > 0) {
86
- consoleMethod(logLine, context);
87
- } else {
88
- consoleMethod(logLine);
108
+ };
109
+ }
110
+ function createRemoteImages(rpcClient, subscribeFn) {
111
+ return {
112
+ async create(params) {
113
+ const result = await rpcClient.call("image.create", params);
114
+ if (result.__subscriptions) {
115
+ for (const sessionId of result.__subscriptions) {
116
+ subscribeFn(sessionId);
117
+ }
118
+ }
119
+ return { ...result, requestId: "" };
120
+ },
121
+ async get(imageId) {
122
+ const result = await rpcClient.call("image.get", { imageId });
123
+ if (result.__subscriptions) {
124
+ for (const sessionId of result.__subscriptions) {
125
+ subscribeFn(sessionId);
126
+ }
127
+ }
128
+ return { ...result, requestId: "" };
129
+ },
130
+ async list(containerId) {
131
+ const result = await rpcClient.call("image.list", { containerId });
132
+ if (result.__subscriptions) {
133
+ for (const sessionId of result.__subscriptions) {
134
+ subscribeFn(sessionId);
135
+ }
136
+ }
137
+ return { ...result, requestId: "" };
138
+ },
139
+ async update(imageId, updates) {
140
+ const result = await rpcClient.call("image.update", {
141
+ imageId,
142
+ updates
143
+ });
144
+ return { ...result, requestId: "" };
145
+ },
146
+ async delete(imageId) {
147
+ const result = await rpcClient.call("image.delete", { imageId });
148
+ return { ...result, requestId: "" };
89
149
  }
90
- }
91
- getConsoleMethod(level) {
92
- switch (level) {
93
- case "DEBUG":
94
- return console.debug.bind(console);
95
- case "INFO":
96
- return console.info.bind(console);
97
- case "WARN":
98
- return console.warn.bind(console);
99
- case "ERROR":
100
- return console.error.bind(console);
101
- default:
102
- return console.log.bind(console);
150
+ };
151
+ }
152
+
153
+ // src/namespaces/agents.ts
154
+ function createLocalAgents(runtime) {
155
+ return {
156
+ async create(params) {
157
+ const existingAgent = runtime.getAgents().find((a) => a.imageId === params.imageId && a.lifecycle === "running");
158
+ if (existingAgent) {
159
+ return {
160
+ agentId: existingAgent.agentId,
161
+ imageId: existingAgent.imageId,
162
+ containerId: existingAgent.containerId,
163
+ sessionId: existingAgent.sessionId,
164
+ requestId: ""
165
+ };
166
+ }
167
+ const agent = await runtime.createAgent({
168
+ imageId: params.imageId,
169
+ agentId: params.agentId
170
+ });
171
+ return {
172
+ agentId: agent.agentId,
173
+ imageId: agent.imageId,
174
+ containerId: agent.containerId,
175
+ sessionId: agent.sessionId,
176
+ requestId: ""
177
+ };
178
+ },
179
+ async get(agentId) {
180
+ const agent = runtime.getAgent(agentId);
181
+ return {
182
+ agent: agent ? {
183
+ agentId: agent.agentId,
184
+ imageId: agent.imageId,
185
+ containerId: agent.containerId,
186
+ sessionId: agent.sessionId,
187
+ lifecycle: agent.lifecycle
188
+ } : null,
189
+ exists: !!agent,
190
+ requestId: ""
191
+ };
192
+ },
193
+ async list(containerId) {
194
+ const agents = containerId ? runtime.getAgentsByContainer(containerId) : runtime.getAgents();
195
+ return {
196
+ agents: agents.map((a) => ({
197
+ agentId: a.agentId,
198
+ imageId: a.imageId,
199
+ containerId: a.containerId,
200
+ sessionId: a.sessionId,
201
+ lifecycle: a.lifecycle
202
+ })),
203
+ requestId: ""
204
+ };
205
+ },
206
+ async destroy(agentId) {
207
+ const agent = runtime.getAgent(agentId);
208
+ if (agent) {
209
+ await runtime.destroyAgent(agentId);
210
+ }
211
+ return { requestId: "" };
103
212
  }
104
- }
105
- isNodeEnvironment() {
106
- return typeof process !== "undefined" && process.versions?.node !== void 0;
107
- }
108
- };
109
- var externalFactory = null;
110
- var factoryVersion = 0;
111
- var LoggerFactoryImpl = class {
112
- static loggers = /* @__PURE__ */ new Map();
113
- static config = {
114
- defaultLevel: "info"
115
213
  };
116
- static getLogger(nameOrClass) {
117
- const name = typeof nameOrClass === "string" ? nameOrClass : nameOrClass.name;
118
- if (this.loggers.has(name)) {
119
- return this.loggers.get(name);
214
+ }
215
+ function createRemoteAgents(rpcClient) {
216
+ return {
217
+ async create(params) {
218
+ const result = await rpcClient.call("image.run", {
219
+ imageId: params.imageId,
220
+ agentId: params.agentId
221
+ });
222
+ return { ...result, requestId: "" };
223
+ },
224
+ async get(agentId) {
225
+ const result = await rpcClient.call("agent.get", { agentId });
226
+ return { ...result, requestId: "" };
227
+ },
228
+ async list(containerId) {
229
+ const result = await rpcClient.call("agent.list", { containerId });
230
+ return { ...result, requestId: "" };
231
+ },
232
+ async destroy(agentId) {
233
+ const result = await rpcClient.call("agent.destroy", { agentId });
234
+ return { ...result, requestId: "" };
120
235
  }
121
- const lazyLogger = this.createLazyLogger(name);
122
- this.loggers.set(name, lazyLogger);
123
- return lazyLogger;
124
- }
125
- static configure(config) {
126
- this.config = { ...this.config, ...config };
127
- }
128
- static reset() {
129
- this.loggers.clear();
130
- this.config = { defaultLevel: "info" };
131
- externalFactory = null;
132
- factoryVersion++;
133
- }
134
- static createLazyLogger(name) {
135
- let realLogger = null;
136
- let loggerVersion = -1;
137
- const getRealLogger = () => {
138
- if (!realLogger || loggerVersion !== factoryVersion) {
139
- realLogger = this.createLogger(name);
140
- loggerVersion = factoryVersion;
141
- }
142
- return realLogger;
143
- };
144
- return {
145
- name,
146
- level: this.config.defaultLevel || "info",
147
- debug: (message, context) => getRealLogger().debug(message, context),
148
- info: (message, context) => getRealLogger().info(message, context),
149
- warn: (message, context) => getRealLogger().warn(message, context),
150
- error: (message, context) => getRealLogger().error(message, context),
151
- isDebugEnabled: () => getRealLogger().isDebugEnabled(),
152
- isInfoEnabled: () => getRealLogger().isInfoEnabled(),
153
- isWarnEnabled: () => getRealLogger().isWarnEnabled(),
154
- isErrorEnabled: () => getRealLogger().isErrorEnabled()
155
- };
156
- }
157
- static createLogger(name) {
158
- if (externalFactory) {
159
- return externalFactory.getLogger(name);
236
+ };
237
+ }
238
+
239
+ // src/namespaces/sessions.ts
240
+ function createLocalSessions(runtime) {
241
+ return {
242
+ async send(agentId, content) {
243
+ await runtime.receive(agentId, content);
244
+ return { agentId, requestId: "" };
245
+ },
246
+ async interrupt(agentId) {
247
+ runtime.interrupt(agentId);
248
+ return { requestId: "" };
249
+ },
250
+ async getMessages(agentId) {
251
+ const agent = runtime.getAgent(agentId);
252
+ if (!agent) return [];
253
+ return runtime.platform.sessionRepository.getMessages(agent.sessionId);
160
254
  }
161
- if (this.config.defaultImplementation) {
162
- return this.config.defaultImplementation(name);
255
+ };
256
+ }
257
+ function createRemoteSessions(rpcClient) {
258
+ return {
259
+ async send(agentId, content) {
260
+ const result = await rpcClient.call("message.send", {
261
+ agentId,
262
+ content
263
+ });
264
+ return { ...result, requestId: "" };
265
+ },
266
+ async interrupt(agentId) {
267
+ const result = await rpcClient.call("agent.interrupt", { agentId });
268
+ return { ...result, requestId: "" };
269
+ },
270
+ async getMessages(agentId) {
271
+ const agentRes = await rpcClient.call("agent.get", { agentId });
272
+ if (!agentRes.agent) return [];
273
+ const msgRes = await rpcClient.call("image.messages", {
274
+ imageId: agentRes.agent.imageId
275
+ });
276
+ return msgRes.messages ?? [];
163
277
  }
164
- return new ConsoleLogger(name, {
165
- level: this.config.defaultLevel,
166
- ...this.config.consoleOptions
167
- });
168
- }
169
- };
170
- function createLogger(name) {
171
- return LoggerFactoryImpl.getLogger(name);
278
+ };
172
279
  }
173
280
 
174
281
  // src/presentation/types.ts
@@ -181,18 +288,22 @@ var initialPresentationState = {
181
288
  // src/presentation/reducer.ts
182
289
  function presentationReducer(state, event) {
183
290
  switch (event.type) {
291
+ // Stream layer — real-time display
184
292
  case "message_start":
185
293
  return handleMessageStart(state, event.data);
186
294
  case "text_delta":
187
295
  return handleTextDelta(state, event.data);
188
296
  case "tool_use_start":
189
297
  return handleToolUseStart(state, event.data);
190
- case "input_json_delta":
191
- return handleInputJsonDelta(state, event.data);
192
- case "tool_result":
193
- return handleToolResult(state, event.data);
298
+ case "tool_use_stop":
299
+ return handleToolUseStop(state, event.data);
300
+ case "message_delta":
301
+ return handleMessageDelta(state, event.data);
194
302
  case "message_stop":
195
303
  return handleMessageStop(state, event.data);
304
+ // Message layer — tool results from Engine
305
+ case "tool_result_message":
306
+ return handleToolResultMessage(state, event.data);
196
307
  case "error":
197
308
  return handleError(state, event.data);
198
309
  default:
@@ -200,6 +311,10 @@ function presentationReducer(state, event) {
200
311
  }
201
312
  }
202
313
  function handleMessageStart(state, _data) {
314
+ let conversations = state.conversations;
315
+ if (state.streaming && state.streaming.blocks.length > 0) {
316
+ conversations = [...conversations, { ...state.streaming, isStreaming: false }];
317
+ }
203
318
  const streaming = {
204
319
  role: "assistant",
205
320
  blocks: [],
@@ -207,6 +322,7 @@ function handleMessageStart(state, _data) {
207
322
  };
208
323
  return {
209
324
  ...state,
325
+ conversations,
210
326
  streaming,
211
327
  status: "thinking"
212
328
  };
@@ -243,7 +359,7 @@ function handleToolUseStart(state, data) {
243
359
  }
244
360
  const toolBlock = {
245
361
  type: "tool",
246
- toolUseId: data.toolUseId,
362
+ toolUseId: data.toolCallId,
247
363
  toolName: data.toolName,
248
364
  toolInput: {},
249
365
  status: "pending"
@@ -257,46 +373,16 @@ function handleToolUseStart(state, data) {
257
373
  status: "executing"
258
374
  };
259
375
  }
260
- function handleInputJsonDelta(state, data) {
261
- if (!state.streaming) {
262
- return state;
263
- }
264
- const blocks = [...state.streaming.blocks];
265
- const lastBlock = blocks[blocks.length - 1];
266
- if (lastBlock && lastBlock.type === "tool") {
267
- const currentInput = lastBlock._rawInput || "";
268
- const newInput = currentInput + data.delta;
269
- let toolInput = lastBlock.toolInput;
270
- try {
271
- toolInput = JSON.parse(newInput);
272
- } catch {
273
- }
274
- blocks[blocks.length - 1] = {
275
- ...lastBlock,
276
- toolInput,
277
- _rawInput: newInput,
278
- status: "running"
279
- };
280
- return {
281
- ...state,
282
- streaming: {
283
- ...state.streaming,
284
- blocks
285
- }
286
- };
287
- }
288
- return state;
289
- }
290
- function handleToolResult(state, data) {
376
+ function handleToolUseStop(state, data) {
291
377
  if (!state.streaming) {
292
378
  return state;
293
379
  }
294
380
  const blocks = state.streaming.blocks.map((block) => {
295
- if (block.type === "tool" && block.toolUseId === data.toolUseId) {
381
+ if (block.type === "tool" && block.toolUseId === data.toolCallId) {
296
382
  return {
297
383
  ...block,
298
- toolResult: data.result,
299
- status: data.isError ? "error" : "completed"
384
+ toolInput: data.input,
385
+ status: "running"
300
386
  };
301
387
  }
302
388
  return block;
@@ -306,14 +392,36 @@ function handleToolResult(state, data) {
306
392
  streaming: {
307
393
  ...state.streaming,
308
394
  blocks
309
- },
310
- status: "responding"
395
+ }
396
+ };
397
+ }
398
+ function handleMessageDelta(state, data) {
399
+ if (!state.streaming || !data.usage) {
400
+ return state;
401
+ }
402
+ const prev = state.streaming.usage;
403
+ const usage = {
404
+ inputTokens: (prev?.inputTokens ?? 0) + data.usage.inputTokens,
405
+ outputTokens: (prev?.outputTokens ?? 0) + data.usage.outputTokens
406
+ };
407
+ return {
408
+ ...state,
409
+ streaming: {
410
+ ...state.streaming,
411
+ usage
412
+ }
311
413
  };
312
414
  }
313
- function handleMessageStop(state, _data) {
415
+ function handleMessageStop(state, data) {
314
416
  if (!state.streaming) {
315
417
  return state;
316
418
  }
419
+ if (data.stopReason === "tool_use") {
420
+ return {
421
+ ...state,
422
+ status: "executing"
423
+ };
424
+ }
317
425
  const completedConversation = {
318
426
  ...state.streaming,
319
427
  isStreaming: false
@@ -325,6 +433,30 @@ function handleMessageStop(state, _data) {
325
433
  status: "idle"
326
434
  };
327
435
  }
436
+ function handleToolResultMessage(state, data) {
437
+ if (!state.streaming) {
438
+ return state;
439
+ }
440
+ const toolCallId = data.toolCallId;
441
+ const blocks = state.streaming.blocks.map((block) => {
442
+ if (block.type === "tool" && block.toolUseId === toolCallId) {
443
+ return {
444
+ ...block,
445
+ toolResult: formatToolResultOutput(data.toolResult.output),
446
+ status: data.toolResult.output.type === "error-text" || data.toolResult.output.type === "error-json" || data.toolResult.output.type === "execution-denied" ? "error" : "completed"
447
+ };
448
+ }
449
+ return block;
450
+ });
451
+ return {
452
+ ...state,
453
+ streaming: {
454
+ ...state.streaming,
455
+ blocks
456
+ },
457
+ status: "responding"
458
+ };
459
+ }
328
460
  function handleError(state, data) {
329
461
  return {
330
462
  ...state,
@@ -354,6 +486,97 @@ function addUserConversation(state, content) {
354
486
  function createInitialState() {
355
487
  return { ...initialPresentationState };
356
488
  }
489
+ function formatToolResultOutput(output) {
490
+ switch (output.type) {
491
+ case "text":
492
+ case "error-text":
493
+ return output.value;
494
+ case "json":
495
+ case "error-json":
496
+ return JSON.stringify(output.value);
497
+ case "execution-denied":
498
+ return output.reason ?? "Execution denied";
499
+ case "content":
500
+ return output.value.filter((p) => p.type === "text").map((p) => p.text).join("");
501
+ }
502
+ }
503
+ function messagesToConversations(messages) {
504
+ const conversations = [];
505
+ let currentAssistant = null;
506
+ function flushAssistant() {
507
+ if (currentAssistant && currentAssistant.blocks.length > 0) {
508
+ conversations.push(currentAssistant);
509
+ }
510
+ currentAssistant = null;
511
+ }
512
+ for (const msg of messages) {
513
+ switch (msg.subtype) {
514
+ case "user": {
515
+ flushAssistant();
516
+ const m = msg;
517
+ const text = typeof m.content === "string" ? m.content : m.content.filter((p) => p.type === "text").map((p) => p.text).join("");
518
+ conversations.push({
519
+ role: "user",
520
+ blocks: [{ type: "text", content: text }]
521
+ });
522
+ break;
523
+ }
524
+ case "assistant": {
525
+ if (!currentAssistant) {
526
+ currentAssistant = { role: "assistant", blocks: [], isStreaming: false };
527
+ }
528
+ const m = msg;
529
+ if (typeof m.content === "string") {
530
+ if (m.content) {
531
+ currentAssistant.blocks.push({ type: "text", content: m.content });
532
+ }
533
+ } else {
534
+ for (const part of m.content) {
535
+ if (part.type === "text") {
536
+ if (part.text) {
537
+ currentAssistant.blocks.push({ type: "text", content: part.text });
538
+ }
539
+ } else if (part.type === "tool-call") {
540
+ const tc = part;
541
+ currentAssistant.blocks.push({
542
+ type: "tool",
543
+ toolUseId: tc.id,
544
+ toolName: tc.name,
545
+ toolInput: tc.input,
546
+ status: "completed"
547
+ });
548
+ }
549
+ }
550
+ }
551
+ break;
552
+ }
553
+ case "tool-result": {
554
+ const m = msg;
555
+ if (currentAssistant) {
556
+ for (const block of currentAssistant.blocks) {
557
+ if (block.type === "tool" && block.toolUseId === m.toolResult.id) {
558
+ block.toolResult = formatToolResultOutput(m.toolResult.output);
559
+ block.status = m.toolResult.output.type === "error-text" || m.toolResult.output.type === "error-json" || m.toolResult.output.type === "execution-denied" ? "error" : "completed";
560
+ break;
561
+ }
562
+ }
563
+ }
564
+ break;
565
+ }
566
+ case "error": {
567
+ flushAssistant();
568
+ const m = msg;
569
+ conversations.push({
570
+ role: "error",
571
+ message: m.content
572
+ });
573
+ break;
574
+ }
575
+ }
576
+ }
577
+ flushAssistant();
578
+ return conversations;
579
+ }
357
580
 
358
581
  // src/presentation/Presentation.ts
359
582
  var Presentation = class {
@@ -363,10 +586,10 @@ var Presentation = class {
363
586
  updateHandlers = /* @__PURE__ */ new Set();
364
587
  errorHandlers = /* @__PURE__ */ new Set();
365
588
  eventUnsubscribe = null;
366
- constructor(agentx, agentId, options) {
589
+ constructor(agentx, agentId, options, initialConversations) {
367
590
  this.agentx = agentx;
368
591
  this.agentId = agentId;
369
- this.state = createInitialState();
592
+ this.state = initialConversations?.length ? { ...initialPresentationState, conversations: initialConversations } : createInitialState();
370
593
  if (options?.onUpdate) {
371
594
  this.updateHandlers.add(options.onUpdate);
372
595
  }
@@ -407,7 +630,7 @@ var Presentation = class {
407
630
  this.state = addUserConversation(this.state, content);
408
631
  this.notify();
409
632
  try {
410
- await this.agentx.sendMessage(this.agentId, content);
633
+ await this.agentx.sessions.send(this.agentId, content);
411
634
  } catch (error) {
412
635
  this.notifyError(error instanceof Error ? error : new Error(String(error)));
413
636
  }
@@ -417,7 +640,7 @@ var Presentation = class {
417
640
  */
418
641
  async interrupt() {
419
642
  try {
420
- await this.agentx.interrupt(this.agentId);
643
+ await this.agentx.sessions.interrupt(this.agentId);
421
644
  } catch (error) {
422
645
  this.notifyError(error instanceof Error ? error : new Error(String(error)));
423
646
  }
@@ -475,17 +698,34 @@ var Presentation = class {
475
698
  }
476
699
  };
477
700
 
701
+ // src/namespaces/presentations.ts
702
+ function createPresentations(agentx) {
703
+ return {
704
+ async create(agentId, options) {
705
+ const messages = await agentx.sessions.getMessages(agentId);
706
+ const conversations = messagesToConversations(messages);
707
+ return new Presentation(agentx, agentId, options, conversations);
708
+ }
709
+ };
710
+ }
711
+
478
712
  // src/RemoteClient.ts
479
713
  var logger = createLogger("agentx/RemoteClient");
480
714
  var RemoteClient = class {
481
715
  config;
482
716
  eventBus;
483
717
  rpcClient;
718
+ containers;
719
+ images;
720
+ agents;
721
+ sessions;
722
+ presentations;
484
723
  constructor(config) {
485
724
  this.config = config;
486
725
  this.eventBus = new EventBusImpl();
487
726
  this.rpcClient = new RpcClient({
488
727
  url: config.serverUrl,
728
+ createWebSocket: config.customPlatform?.webSocketFactory,
489
729
  timeout: config.timeout ?? 3e4,
490
730
  autoReconnect: config.autoReconnect ?? true,
491
731
  headers: config.headers,
@@ -495,6 +735,11 @@ var RemoteClient = class {
495
735
  logger.debug("Received stream event", { topic, type: event.type });
496
736
  this.eventBus.emit(event);
497
737
  });
738
+ this.containers = createRemoteContainers(this.rpcClient);
739
+ this.images = createRemoteImages(this.rpcClient, (sessionId) => this.subscribe(sessionId));
740
+ this.agents = createRemoteAgents(this.rpcClient);
741
+ this.sessions = createRemoteSessions(this.rpcClient);
742
+ this.presentations = createPresentations(this);
498
743
  }
499
744
  // ==================== Properties ====================
500
745
  get connected() {
@@ -517,109 +762,133 @@ var RemoteClient = class {
517
762
  this.eventBus.destroy();
518
763
  logger.info("RemoteClient disposed");
519
764
  }
520
- // ==================== Container Operations ====================
521
- async createContainer(containerId) {
522
- const result = await this.rpcClient.call("container.create", {
523
- containerId
524
- });
525
- return { ...result, requestId: "" };
526
- }
527
- async getContainer(containerId) {
528
- const result = await this.rpcClient.call("container.get", {
529
- containerId
530
- });
531
- return { ...result, requestId: "" };
532
- }
533
- async listContainers() {
534
- const result = await this.rpcClient.call("container.list", {});
535
- return { ...result, requestId: "" };
536
- }
537
- // ==================== Image Operations ====================
538
- async createImage(params) {
539
- const result = await this.rpcClient.call("image.create", params);
540
- if (result.__subscriptions) {
541
- for (const sessionId of result.__subscriptions) {
542
- this.subscribe(sessionId);
543
- }
544
- }
545
- return { ...result, requestId: "" };
546
- }
547
- async getImage(imageId) {
548
- const result = await this.rpcClient.call("image.get", { imageId });
549
- if (result.__subscriptions) {
550
- for (const sessionId of result.__subscriptions) {
551
- this.subscribe(sessionId);
552
- }
553
- }
554
- return { ...result, requestId: "" };
555
- }
556
- async listImages(containerId) {
557
- const result = await this.rpcClient.call("image.list", { containerId });
558
- if (result.__subscriptions) {
559
- for (const sessionId of result.__subscriptions) {
560
- this.subscribe(sessionId);
561
- }
562
- }
563
- return { ...result, requestId: "" };
564
- }
565
- async deleteImage(imageId) {
566
- const result = await this.rpcClient.call("image.delete", { imageId });
567
- return { ...result, requestId: "" };
568
- }
569
- // ==================== Agent Operations ====================
570
- async createAgent(params) {
571
- const result = await this.rpcClient.call("image.run", {
572
- imageId: params.imageId,
573
- agentId: params.agentId
574
- });
575
- return { ...result, requestId: "" };
765
+ // ==================== Event Subscription ====================
766
+ on(type, handler) {
767
+ return this.eventBus.on(type, handler);
576
768
  }
577
- async getAgent(agentId) {
578
- const result = await this.rpcClient.call("agent.get", { agentId });
579
- return { ...result, requestId: "" };
769
+ onAny(handler) {
770
+ return this.eventBus.onAny(handler);
580
771
  }
581
- async listAgents(containerId) {
582
- const result = await this.rpcClient.call("agent.list", { containerId });
583
- return { ...result, requestId: "" };
772
+ subscribe(sessionId) {
773
+ this.rpcClient.subscribe(sessionId);
774
+ logger.debug("Subscribed to session", { sessionId });
584
775
  }
585
- async destroyAgent(agentId) {
586
- const result = await this.rpcClient.call("agent.destroy", { agentId });
587
- return { ...result, requestId: "" };
776
+ };
777
+
778
+ // src/LocalClient.ts
779
+ import { createLogger as createLogger2 } from "commonxjs/logger";
780
+ var logger2 = createLogger2("agentx/LocalClient");
781
+ var LocalClient = class {
782
+ runtime;
783
+ isDisposed = false;
784
+ containers;
785
+ images;
786
+ agents;
787
+ sessions;
788
+ presentations;
789
+ constructor(runtime) {
790
+ this.runtime = runtime;
791
+ const platform = runtime.platform;
792
+ this.containers = createLocalContainers(platform);
793
+ this.images = createLocalImages(platform);
794
+ this.agents = createLocalAgents(runtime);
795
+ this.sessions = createLocalSessions(runtime);
796
+ this.presentations = createPresentations(this);
797
+ logger2.info("LocalClient initialized");
588
798
  }
589
- // ==================== Message Operations ====================
590
- async sendMessage(agentId, content) {
591
- const result = await this.rpcClient.call("message.send", {
592
- agentId,
593
- content
594
- });
595
- return { ...result, requestId: "" };
799
+ // ==================== Properties ====================
800
+ get connected() {
801
+ return !this.isDisposed;
596
802
  }
597
- async interrupt(agentId) {
598
- const result = await this.rpcClient.call("agent.interrupt", { agentId });
599
- return { ...result, requestId: "" };
803
+ get events() {
804
+ return this.runtime.platform.eventBus;
600
805
  }
601
806
  // ==================== Event Subscription ====================
602
807
  on(type, handler) {
603
- return this.eventBus.on(type, handler);
808
+ return this.runtime.platform.eventBus.on(type, handler);
604
809
  }
605
810
  onAny(handler) {
606
- return this.eventBus.onAny(handler);
811
+ return this.runtime.platform.eventBus.onAny(handler);
607
812
  }
608
- subscribe(sessionId) {
609
- this.rpcClient.subscribe(sessionId);
610
- logger.debug("Subscribed to session", { sessionId });
813
+ subscribe(_sessionId) {
611
814
  }
612
- // ==================== Presentation ====================
613
- presentation(agentId, options) {
614
- return new Presentation(this, agentId, options);
815
+ // ==================== Lifecycle ====================
816
+ async disconnect() {
817
+ }
818
+ async dispose() {
819
+ if (this.isDisposed) return;
820
+ await this.runtime.shutdown();
821
+ this.isDisposed = true;
822
+ logger2.info("LocalClient disposed");
615
823
  }
616
824
  };
617
825
 
618
826
  // src/index.ts
619
827
  async function createAgentX(config) {
620
- const client = new RemoteClient(config);
621
- await client.connect();
622
- return client;
828
+ if (config.serverUrl) {
829
+ const resolvedConfig = await resolvePlatformForRemote(config);
830
+ const client = new RemoteClient(resolvedConfig);
831
+ await client.connect();
832
+ return client;
833
+ }
834
+ if (config.apiKey || config.createDriver || config.customPlatform) {
835
+ return createLocalClient(config);
836
+ }
837
+ throw new Error(
838
+ "Invalid AgentX config: provide either 'serverUrl' (remote mode) or 'apiKey' (local mode)"
839
+ );
840
+ }
841
+ async function resolvePlatformForRemote(config) {
842
+ if (config.customPlatform?.webSocketFactory) {
843
+ return config;
844
+ }
845
+ if (typeof globalThis !== "undefined" && globalThis.window?.document !== void 0) {
846
+ return config;
847
+ }
848
+ try {
849
+ const { createNodeWebSocket } = await import("@agentxjs/node-platform/network");
850
+ return {
851
+ ...config,
852
+ customPlatform: {
853
+ ...config.customPlatform,
854
+ webSocketFactory: createNodeWebSocket
855
+ }
856
+ };
857
+ } catch {
858
+ return config;
859
+ }
860
+ }
861
+ async function createLocalClient(config) {
862
+ const { createAgentXRuntime } = await import("@agentxjs/core/runtime");
863
+ let platform;
864
+ if (config.customPlatform) {
865
+ platform = config.customPlatform;
866
+ } else {
867
+ const { createNodePlatform } = await import("@agentxjs/node-platform");
868
+ platform = await createNodePlatform({
869
+ dataPath: config.dataPath ?? ":memory:",
870
+ logLevel: config.logLevel ?? (config.debug ? "debug" : void 0)
871
+ });
872
+ }
873
+ let createDriver = config.createDriver;
874
+ if (!createDriver) {
875
+ const { createMonoDriver } = await import("@agentxjs/mono-driver");
876
+ createDriver = (driverConfig) => {
877
+ const existingOptions = driverConfig.options ?? {};
878
+ return createMonoDriver({
879
+ ...driverConfig,
880
+ apiKey: config.apiKey ?? driverConfig.apiKey,
881
+ baseUrl: config.baseUrl ?? driverConfig.baseUrl,
882
+ model: config.model ?? driverConfig.model,
883
+ options: {
884
+ ...existingOptions,
885
+ provider: config.provider ?? existingOptions.provider ?? "anthropic"
886
+ }
887
+ });
888
+ };
889
+ }
890
+ const runtime = createAgentXRuntime(platform, createDriver);
891
+ return new LocalClient(runtime);
623
892
  }
624
893
  export {
625
894
  Presentation,
@@ -627,6 +896,7 @@ export {
627
896
  createAgentX,
628
897
  createInitialState,
629
898
  initialPresentationState,
899
+ messagesToConversations,
630
900
  presentationReducer
631
901
  };
632
902
  //# sourceMappingURL=index.js.map