agentxjs 0.0.0-dev-20260312143810

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 ADDED
@@ -0,0 +1,1088 @@
1
+ import {
2
+ CommandHandler,
3
+ createServer
4
+ } from "./chunk-X44CQZPK.js";
5
+
6
+ // src/index.ts
7
+ import { createAgentXRuntime } from "@agentxjs/core/runtime";
8
+
9
+ // src/LocalClient.ts
10
+ import { createLogger } from "commonxjs/logger";
11
+
12
+ // src/namespaces/agents.ts
13
+ function createLocalAgents(runtime) {
14
+ return {
15
+ async create(params) {
16
+ const existingAgent = runtime.getAgents().find((a) => a.imageId === params.imageId && a.lifecycle === "running");
17
+ if (existingAgent) {
18
+ return {
19
+ agentId: existingAgent.agentId,
20
+ imageId: existingAgent.imageId,
21
+ containerId: existingAgent.containerId,
22
+ sessionId: existingAgent.sessionId,
23
+ requestId: ""
24
+ };
25
+ }
26
+ const agent = await runtime.createAgent({
27
+ imageId: params.imageId,
28
+ agentId: params.agentId
29
+ });
30
+ return {
31
+ agentId: agent.agentId,
32
+ imageId: agent.imageId,
33
+ containerId: agent.containerId,
34
+ sessionId: agent.sessionId,
35
+ requestId: ""
36
+ };
37
+ },
38
+ async get(agentId) {
39
+ const agent = runtime.getAgent(agentId);
40
+ return {
41
+ agent: agent ? {
42
+ agentId: agent.agentId,
43
+ imageId: agent.imageId,
44
+ containerId: agent.containerId,
45
+ sessionId: agent.sessionId,
46
+ lifecycle: agent.lifecycle
47
+ } : null,
48
+ exists: !!agent,
49
+ requestId: ""
50
+ };
51
+ },
52
+ async list(containerId) {
53
+ const agents = containerId ? runtime.getAgentsByContainer(containerId) : runtime.getAgents();
54
+ return {
55
+ agents: agents.map((a) => ({
56
+ agentId: a.agentId,
57
+ imageId: a.imageId,
58
+ containerId: a.containerId,
59
+ sessionId: a.sessionId,
60
+ lifecycle: a.lifecycle
61
+ })),
62
+ requestId: ""
63
+ };
64
+ },
65
+ async destroy(agentId) {
66
+ const agent = runtime.getAgent(agentId);
67
+ if (agent) {
68
+ await runtime.destroyAgent(agentId);
69
+ }
70
+ return { requestId: "" };
71
+ }
72
+ };
73
+ }
74
+ function createRemoteAgents(rpcClient) {
75
+ return {
76
+ async create(params) {
77
+ const result = await rpcClient.call("image.run", {
78
+ imageId: params.imageId,
79
+ agentId: params.agentId
80
+ });
81
+ return { ...result, requestId: "" };
82
+ },
83
+ async get(agentId) {
84
+ const result = await rpcClient.call("agent.get", { agentId });
85
+ return { ...result, requestId: "" };
86
+ },
87
+ async list(containerId) {
88
+ const result = await rpcClient.call("agent.list", { containerId });
89
+ return { ...result, requestId: "" };
90
+ },
91
+ async destroy(agentId) {
92
+ const result = await rpcClient.call("agent.destroy", { agentId });
93
+ return { ...result, requestId: "" };
94
+ }
95
+ };
96
+ }
97
+
98
+ // src/namespaces/containers.ts
99
+ function createLocalContainers(platform) {
100
+ return {
101
+ async create(containerId) {
102
+ const { getOrCreateContainer } = await import("@agentxjs/core/container");
103
+ const { containerRepository, imageRepository, sessionRepository } = platform;
104
+ const container = await getOrCreateContainer(containerId, {
105
+ containerRepository,
106
+ imageRepository,
107
+ sessionRepository
108
+ });
109
+ return { containerId: container.containerId, requestId: "" };
110
+ },
111
+ async get(containerId) {
112
+ const exists = await platform.containerRepository.containerExists(containerId);
113
+ return { containerId, exists, requestId: "" };
114
+ },
115
+ async list() {
116
+ const containers = await platform.containerRepository.findAllContainers();
117
+ return { containerIds: containers.map((c) => c.containerId), requestId: "" };
118
+ }
119
+ };
120
+ }
121
+ function createRemoteContainers(rpcClient) {
122
+ return {
123
+ async create(containerId) {
124
+ const result = await rpcClient.call("container.create", {
125
+ containerId
126
+ });
127
+ return { ...result, requestId: "" };
128
+ },
129
+ async get(containerId) {
130
+ const result = await rpcClient.call("container.get", {
131
+ containerId
132
+ });
133
+ return { ...result, requestId: "" };
134
+ },
135
+ async list() {
136
+ const result = await rpcClient.call("container.list", {});
137
+ return { ...result, requestId: "" };
138
+ }
139
+ };
140
+ }
141
+
142
+ // src/namespaces/images.ts
143
+ function createLocalImages(platform) {
144
+ return {
145
+ async create(params) {
146
+ const { imageRepository, sessionRepository } = platform;
147
+ const { createImage } = await import("@agentxjs/core/image");
148
+ const image = await createImage(
149
+ {
150
+ containerId: params.containerId,
151
+ name: params.name,
152
+ description: params.description,
153
+ systemPrompt: params.systemPrompt,
154
+ mcpServers: params.mcpServers,
155
+ customData: params.customData
156
+ },
157
+ { imageRepository, sessionRepository }
158
+ );
159
+ return {
160
+ record: image.toRecord(),
161
+ __subscriptions: [image.sessionId],
162
+ requestId: ""
163
+ };
164
+ },
165
+ async get(imageId) {
166
+ const record = await platform.imageRepository.findImageById(imageId);
167
+ return {
168
+ record,
169
+ __subscriptions: record?.sessionId ? [record.sessionId] : void 0,
170
+ requestId: ""
171
+ };
172
+ },
173
+ async list(containerId) {
174
+ const records = containerId ? await platform.imageRepository.findImagesByContainerId(containerId) : await platform.imageRepository.findAllImages();
175
+ return {
176
+ records,
177
+ __subscriptions: records.map((r) => r.sessionId),
178
+ requestId: ""
179
+ };
180
+ },
181
+ async update(imageId, updates) {
182
+ const { loadImage } = await import("@agentxjs/core/image");
183
+ const { imageRepository, sessionRepository } = platform;
184
+ const image = await loadImage(imageId, { imageRepository, sessionRepository });
185
+ if (!image) {
186
+ throw new Error(`Image not found: ${imageId}`);
187
+ }
188
+ const updated = await image.update(updates);
189
+ return { record: updated.toRecord(), requestId: "" };
190
+ },
191
+ async delete(imageId) {
192
+ const { loadImage } = await import("@agentxjs/core/image");
193
+ const { imageRepository, sessionRepository } = platform;
194
+ const image = await loadImage(imageId, { imageRepository, sessionRepository });
195
+ if (image) {
196
+ await image.delete();
197
+ }
198
+ return { requestId: "" };
199
+ },
200
+ async getMessages(imageId) {
201
+ const imageRecord = await platform.imageRepository.findImageById(imageId);
202
+ if (!imageRecord) return [];
203
+ return platform.sessionRepository.getMessages(imageRecord.sessionId);
204
+ }
205
+ };
206
+ }
207
+ function createRemoteImages(rpcClient, subscribeFn) {
208
+ return {
209
+ async create(params) {
210
+ const result = await rpcClient.call("image.create", params);
211
+ if (result.__subscriptions) {
212
+ for (const sessionId of result.__subscriptions) {
213
+ subscribeFn(sessionId);
214
+ }
215
+ }
216
+ return { ...result, requestId: "" };
217
+ },
218
+ async get(imageId) {
219
+ const result = await rpcClient.call("image.get", { imageId });
220
+ if (result.__subscriptions) {
221
+ for (const sessionId of result.__subscriptions) {
222
+ subscribeFn(sessionId);
223
+ }
224
+ }
225
+ return { ...result, requestId: "" };
226
+ },
227
+ async list(containerId) {
228
+ const result = await rpcClient.call("image.list", { containerId });
229
+ if (result.__subscriptions) {
230
+ for (const sessionId of result.__subscriptions) {
231
+ subscribeFn(sessionId);
232
+ }
233
+ }
234
+ return { ...result, requestId: "" };
235
+ },
236
+ async update(imageId, updates) {
237
+ const result = await rpcClient.call("image.update", {
238
+ imageId,
239
+ updates
240
+ });
241
+ return { ...result, requestId: "" };
242
+ },
243
+ async delete(imageId) {
244
+ const result = await rpcClient.call("image.delete", { imageId });
245
+ return { ...result, requestId: "" };
246
+ },
247
+ async getMessages(imageId) {
248
+ const result = await rpcClient.call("image.messages", { imageId });
249
+ return result.messages ?? [];
250
+ }
251
+ };
252
+ }
253
+
254
+ // src/namespaces/llm.ts
255
+ import { generateId } from "@deepracticex/id";
256
+ function createLocalLLM(platform) {
257
+ const repo = platform.llmProviderRepository;
258
+ if (!repo) {
259
+ throw new Error("LLM provider repository not available on this platform");
260
+ }
261
+ return {
262
+ async create(params) {
263
+ const now = Date.now();
264
+ const record = {
265
+ id: generateId("llm"),
266
+ containerId: params.containerId,
267
+ name: params.name,
268
+ vendor: params.vendor,
269
+ protocol: params.protocol,
270
+ apiKey: params.apiKey,
271
+ baseUrl: params.baseUrl,
272
+ model: params.model,
273
+ isDefault: false,
274
+ createdAt: now,
275
+ updatedAt: now
276
+ };
277
+ await repo.saveLLMProvider(record);
278
+ return { record, requestId: "" };
279
+ },
280
+ async get(id) {
281
+ const record = await repo.findLLMProviderById(id);
282
+ return { record, requestId: "" };
283
+ },
284
+ async list(containerId) {
285
+ const records = await repo.findLLMProvidersByContainerId(containerId);
286
+ return { records, requestId: "" };
287
+ },
288
+ async update(id, updates) {
289
+ const existing = await repo.findLLMProviderById(id);
290
+ if (!existing) {
291
+ throw new Error(`LLM provider not found: ${id}`);
292
+ }
293
+ const updated = {
294
+ ...existing,
295
+ ...updates,
296
+ id: existing.id,
297
+ containerId: existing.containerId,
298
+ createdAt: existing.createdAt,
299
+ updatedAt: Date.now()
300
+ };
301
+ await repo.saveLLMProvider(updated);
302
+ return { record: updated, requestId: "" };
303
+ },
304
+ async delete(id) {
305
+ await repo.deleteLLMProvider(id);
306
+ return { requestId: "" };
307
+ },
308
+ async setDefault(id) {
309
+ await repo.setDefaultLLMProvider(id);
310
+ return { requestId: "" };
311
+ },
312
+ async getDefault(containerId) {
313
+ const record = await repo.findDefaultLLMProvider(containerId);
314
+ return { record, requestId: "" };
315
+ }
316
+ };
317
+ }
318
+ function createRemoteLLM(rpcClient) {
319
+ return {
320
+ async create(params) {
321
+ const result = await rpcClient.call("llm.create", params);
322
+ return { ...result, requestId: "" };
323
+ },
324
+ async get(id) {
325
+ const result = await rpcClient.call("llm.get", { id });
326
+ return { ...result, requestId: "" };
327
+ },
328
+ async list(containerId) {
329
+ const result = await rpcClient.call("llm.list", { containerId });
330
+ return { ...result, requestId: "" };
331
+ },
332
+ async update(id, updates) {
333
+ const result = await rpcClient.call("llm.update", {
334
+ id,
335
+ updates
336
+ });
337
+ return { ...result, requestId: "" };
338
+ },
339
+ async delete(id) {
340
+ const result = await rpcClient.call("llm.delete", { id });
341
+ return { ...result, requestId: "" };
342
+ },
343
+ async setDefault(id) {
344
+ const result = await rpcClient.call("llm.default", { id });
345
+ return { ...result, requestId: "" };
346
+ },
347
+ async getDefault(containerId) {
348
+ const result = await rpcClient.call("llm.default", {
349
+ containerId
350
+ });
351
+ return { ...result, requestId: "" };
352
+ }
353
+ };
354
+ }
355
+
356
+ // src/presentation/types.ts
357
+ var initialPresentationState = {
358
+ conversations: [],
359
+ streaming: null,
360
+ status: "idle"
361
+ };
362
+
363
+ // src/presentation/reducer.ts
364
+ function presentationReducer(state, event) {
365
+ switch (event.type) {
366
+ // Stream layer — real-time display
367
+ case "message_start":
368
+ return handleMessageStart(state, event.data);
369
+ case "text_delta":
370
+ return handleTextDelta(state, event.data);
371
+ case "tool_use_start":
372
+ return handleToolUseStart(state, event.data);
373
+ case "tool_use_stop":
374
+ return handleToolUseStop(state, event.data);
375
+ case "message_delta":
376
+ return handleMessageDelta(state, event.data);
377
+ case "message_stop":
378
+ return handleMessageStop(state, event.data);
379
+ // Message layer — tool results from Engine
380
+ case "tool_result_message":
381
+ return handleToolResultMessage(state, event.data);
382
+ case "error":
383
+ return handleError(state, event.data);
384
+ default:
385
+ return state;
386
+ }
387
+ }
388
+ function handleMessageStart(state, _data) {
389
+ let conversations = state.conversations;
390
+ if (state.streaming && state.streaming.blocks.length > 0) {
391
+ conversations = [...conversations, { ...state.streaming, isStreaming: false }];
392
+ }
393
+ const streaming = {
394
+ role: "assistant",
395
+ blocks: [],
396
+ isStreaming: true
397
+ };
398
+ return {
399
+ ...state,
400
+ conversations,
401
+ streaming,
402
+ status: "thinking"
403
+ };
404
+ }
405
+ function handleTextDelta(state, data) {
406
+ if (!state.streaming) {
407
+ return state;
408
+ }
409
+ const blocks = [...state.streaming.blocks];
410
+ const lastBlock = blocks[blocks.length - 1];
411
+ if (lastBlock && lastBlock.type === "text") {
412
+ blocks[blocks.length - 1] = {
413
+ ...lastBlock,
414
+ content: lastBlock.content + data.text
415
+ };
416
+ } else {
417
+ blocks.push({
418
+ type: "text",
419
+ content: data.text
420
+ });
421
+ }
422
+ return {
423
+ ...state,
424
+ streaming: {
425
+ ...state.streaming,
426
+ blocks
427
+ },
428
+ status: "responding"
429
+ };
430
+ }
431
+ function handleToolUseStart(state, data) {
432
+ if (!state.streaming) {
433
+ return state;
434
+ }
435
+ const toolBlock = {
436
+ type: "tool",
437
+ toolUseId: data.toolCallId,
438
+ toolName: data.toolName,
439
+ toolInput: {},
440
+ status: "pending"
441
+ };
442
+ return {
443
+ ...state,
444
+ streaming: {
445
+ ...state.streaming,
446
+ blocks: [...state.streaming.blocks, toolBlock]
447
+ },
448
+ status: "executing"
449
+ };
450
+ }
451
+ function handleToolUseStop(state, data) {
452
+ if (!state.streaming) {
453
+ return state;
454
+ }
455
+ const blocks = state.streaming.blocks.map((block) => {
456
+ if (block.type === "tool" && block.toolUseId === data.toolCallId) {
457
+ return {
458
+ ...block,
459
+ toolInput: data.input,
460
+ status: "running"
461
+ };
462
+ }
463
+ return block;
464
+ });
465
+ return {
466
+ ...state,
467
+ streaming: {
468
+ ...state.streaming,
469
+ blocks
470
+ }
471
+ };
472
+ }
473
+ function handleMessageDelta(state, data) {
474
+ if (!state.streaming || !data.usage) {
475
+ return state;
476
+ }
477
+ const prev = state.streaming.usage;
478
+ const usage = {
479
+ inputTokens: (prev?.inputTokens ?? 0) + data.usage.inputTokens,
480
+ outputTokens: (prev?.outputTokens ?? 0) + data.usage.outputTokens
481
+ };
482
+ return {
483
+ ...state,
484
+ streaming: {
485
+ ...state.streaming,
486
+ usage
487
+ }
488
+ };
489
+ }
490
+ function handleMessageStop(state, data) {
491
+ if (!state.streaming) {
492
+ return state;
493
+ }
494
+ if (data.stopReason === "tool_use") {
495
+ return {
496
+ ...state,
497
+ status: "executing"
498
+ };
499
+ }
500
+ const completedConversation = {
501
+ ...state.streaming,
502
+ isStreaming: false
503
+ };
504
+ return {
505
+ ...state,
506
+ conversations: [...state.conversations, completedConversation],
507
+ streaming: null,
508
+ status: "idle"
509
+ };
510
+ }
511
+ function handleToolResultMessage(state, data) {
512
+ if (!state.streaming) {
513
+ return state;
514
+ }
515
+ const toolCallId = data.toolCallId;
516
+ const blocks = state.streaming.blocks.map((block) => {
517
+ if (block.type === "tool" && block.toolUseId === toolCallId) {
518
+ return {
519
+ ...block,
520
+ toolResult: formatToolResultOutput(data.toolResult.output),
521
+ status: data.toolResult.output.type === "error-text" || data.toolResult.output.type === "error-json" || data.toolResult.output.type === "execution-denied" ? "error" : "completed"
522
+ };
523
+ }
524
+ return block;
525
+ });
526
+ return {
527
+ ...state,
528
+ streaming: {
529
+ ...state.streaming,
530
+ blocks
531
+ },
532
+ status: "responding"
533
+ };
534
+ }
535
+ function handleError(state, data) {
536
+ return {
537
+ ...state,
538
+ conversations: [
539
+ ...state.conversations,
540
+ {
541
+ role: "error",
542
+ message: data.message
543
+ }
544
+ ],
545
+ streaming: null,
546
+ status: "idle"
547
+ };
548
+ }
549
+ function addUserConversation(state, content) {
550
+ return {
551
+ ...state,
552
+ conversations: [
553
+ ...state.conversations,
554
+ {
555
+ role: "user",
556
+ blocks: [{ type: "text", content }]
557
+ }
558
+ ]
559
+ };
560
+ }
561
+ function createInitialState() {
562
+ return { ...initialPresentationState };
563
+ }
564
+ function formatToolResultOutput(output) {
565
+ switch (output.type) {
566
+ case "text":
567
+ case "error-text":
568
+ return output.value;
569
+ case "json":
570
+ case "error-json":
571
+ return JSON.stringify(output.value);
572
+ case "execution-denied":
573
+ return output.reason ?? "Execution denied";
574
+ case "content":
575
+ return output.value.filter((p) => p.type === "text").map((p) => p.text).join("");
576
+ }
577
+ }
578
+ function messagesToConversations(messages) {
579
+ const conversations = [];
580
+ let currentAssistant = null;
581
+ function flushAssistant() {
582
+ if (currentAssistant && currentAssistant.blocks.length > 0) {
583
+ conversations.push(currentAssistant);
584
+ }
585
+ currentAssistant = null;
586
+ }
587
+ for (const msg of messages) {
588
+ switch (msg.subtype) {
589
+ case "user": {
590
+ flushAssistant();
591
+ const m = msg;
592
+ const text = typeof m.content === "string" ? m.content : m.content.filter((p) => p.type === "text").map((p) => p.text).join("");
593
+ conversations.push({
594
+ role: "user",
595
+ blocks: [{ type: "text", content: text }]
596
+ });
597
+ break;
598
+ }
599
+ case "assistant": {
600
+ if (!currentAssistant) {
601
+ currentAssistant = { role: "assistant", blocks: [], isStreaming: false };
602
+ }
603
+ const m = msg;
604
+ if (typeof m.content === "string") {
605
+ if (m.content) {
606
+ currentAssistant.blocks.push({ type: "text", content: m.content });
607
+ }
608
+ } else {
609
+ for (const part of m.content) {
610
+ if (part.type === "text") {
611
+ if (part.text) {
612
+ currentAssistant.blocks.push({ type: "text", content: part.text });
613
+ }
614
+ } else if (part.type === "tool-call") {
615
+ const tc = part;
616
+ currentAssistant.blocks.push({
617
+ type: "tool",
618
+ toolUseId: tc.id,
619
+ toolName: tc.name,
620
+ toolInput: tc.input,
621
+ status: "completed"
622
+ });
623
+ }
624
+ }
625
+ }
626
+ break;
627
+ }
628
+ case "tool-result": {
629
+ const m = msg;
630
+ if (currentAssistant) {
631
+ for (const block of currentAssistant.blocks) {
632
+ if (block.type === "tool" && block.toolUseId === m.toolResult.id) {
633
+ block.toolResult = formatToolResultOutput(m.toolResult.output);
634
+ block.status = m.toolResult.output.type === "error-text" || m.toolResult.output.type === "error-json" || m.toolResult.output.type === "execution-denied" ? "error" : "completed";
635
+ break;
636
+ }
637
+ }
638
+ }
639
+ break;
640
+ }
641
+ case "error": {
642
+ flushAssistant();
643
+ const m = msg;
644
+ conversations.push({
645
+ role: "error",
646
+ message: m.content
647
+ });
648
+ break;
649
+ }
650
+ }
651
+ }
652
+ flushAssistant();
653
+ return conversations;
654
+ }
655
+
656
+ // src/presentation/Presentation.ts
657
+ var Presentation = class {
658
+ agentx;
659
+ agentId;
660
+ state;
661
+ updateHandlers = /* @__PURE__ */ new Set();
662
+ errorHandlers = /* @__PURE__ */ new Set();
663
+ eventUnsubscribe = null;
664
+ constructor(agentx, agentId, options, initialConversations) {
665
+ this.agentx = agentx;
666
+ this.agentId = agentId;
667
+ this.state = initialConversations?.length ? { ...initialPresentationState, conversations: initialConversations } : createInitialState();
668
+ if (options?.onUpdate) {
669
+ this.updateHandlers.add(options.onUpdate);
670
+ }
671
+ if (options?.onError) {
672
+ this.errorHandlers.add(options.onError);
673
+ }
674
+ this.subscribeToEvents();
675
+ }
676
+ /**
677
+ * Get current state
678
+ */
679
+ getState() {
680
+ return this.state;
681
+ }
682
+ /**
683
+ * Subscribe to state updates
684
+ */
685
+ onUpdate(handler) {
686
+ this.updateHandlers.add(handler);
687
+ handler(this.state);
688
+ return () => {
689
+ this.updateHandlers.delete(handler);
690
+ };
691
+ }
692
+ /**
693
+ * Subscribe to errors
694
+ */
695
+ onError(handler) {
696
+ this.errorHandlers.add(handler);
697
+ return () => {
698
+ this.errorHandlers.delete(handler);
699
+ };
700
+ }
701
+ /**
702
+ * Send a message
703
+ */
704
+ async send(content) {
705
+ this.state = addUserConversation(this.state, content);
706
+ this.notify();
707
+ try {
708
+ await this.agentx.session.send(this.agentId, content);
709
+ } catch (error) {
710
+ this.notifyError(error instanceof Error ? error : new Error(String(error)));
711
+ }
712
+ }
713
+ /**
714
+ * Interrupt current response
715
+ */
716
+ async interrupt() {
717
+ try {
718
+ await this.agentx.session.interrupt(this.agentId);
719
+ } catch (error) {
720
+ this.notifyError(error instanceof Error ? error : new Error(String(error)));
721
+ }
722
+ }
723
+ /**
724
+ * Reset state
725
+ */
726
+ reset() {
727
+ this.state = createInitialState();
728
+ this.notify();
729
+ }
730
+ /**
731
+ * Dispose and cleanup
732
+ */
733
+ dispose() {
734
+ if (this.eventUnsubscribe) {
735
+ this.eventUnsubscribe();
736
+ this.eventUnsubscribe = null;
737
+ }
738
+ this.updateHandlers.clear();
739
+ this.errorHandlers.clear();
740
+ }
741
+ // ==================== Private ====================
742
+ subscribeToEvents() {
743
+ this.eventUnsubscribe = this.agentx.onAny((event) => {
744
+ const eventWithContext = event;
745
+ const eventAgentId = eventWithContext.context?.agentId;
746
+ if (eventAgentId && eventAgentId !== this.agentId) {
747
+ return;
748
+ }
749
+ const newState = presentationReducer(this.state, event);
750
+ if (newState !== this.state) {
751
+ this.state = newState;
752
+ this.notify();
753
+ }
754
+ });
755
+ }
756
+ notify() {
757
+ for (const handler of this.updateHandlers) {
758
+ try {
759
+ handler(this.state);
760
+ } catch (error) {
761
+ console.error("Presentation update handler error:", error);
762
+ }
763
+ }
764
+ }
765
+ notifyError(error) {
766
+ for (const handler of this.errorHandlers) {
767
+ try {
768
+ handler(error);
769
+ } catch (e) {
770
+ console.error("Presentation error handler error:", e);
771
+ }
772
+ }
773
+ }
774
+ };
775
+
776
+ // src/namespaces/presentations.ts
777
+ function createPresentations(agentx) {
778
+ return {
779
+ async create(agentId, options) {
780
+ const messages = await agentx.session.getMessages(agentId);
781
+ const conversations = messagesToConversations(messages);
782
+ return new Presentation(agentx, agentId, options, conversations);
783
+ }
784
+ };
785
+ }
786
+
787
+ // src/namespaces/sessions.ts
788
+ function createLocalSessions(runtime) {
789
+ return {
790
+ async send(agentId, content) {
791
+ await runtime.receive(agentId, content);
792
+ return { agentId, requestId: "" };
793
+ },
794
+ async interrupt(agentId) {
795
+ runtime.interrupt(agentId);
796
+ return { requestId: "" };
797
+ },
798
+ async getMessages(agentId) {
799
+ const agent = runtime.getAgent(agentId);
800
+ if (!agent) return [];
801
+ return runtime.platform.sessionRepository.getMessages(agent.sessionId);
802
+ }
803
+ };
804
+ }
805
+ function createRemoteSessions(rpcClient) {
806
+ return {
807
+ async send(agentId, content) {
808
+ const result = await rpcClient.call("message.send", {
809
+ agentId,
810
+ content
811
+ });
812
+ return { ...result, requestId: "" };
813
+ },
814
+ async interrupt(agentId) {
815
+ const result = await rpcClient.call("agent.interrupt", { agentId });
816
+ return { ...result, requestId: "" };
817
+ },
818
+ async getMessages(agentId) {
819
+ const agentRes = await rpcClient.call("agent.get", { agentId });
820
+ if (!agentRes.agent) return [];
821
+ const msgRes = await rpcClient.call("image.messages", {
822
+ imageId: agentRes.agent.imageId
823
+ });
824
+ return msgRes.messages ?? [];
825
+ }
826
+ };
827
+ }
828
+
829
+ // src/LocalClient.ts
830
+ var logger = createLogger("agentx/LocalClient");
831
+ var LocalClient = class {
832
+ runtime;
833
+ commandHandler = null;
834
+ isDisposed = false;
835
+ container;
836
+ image;
837
+ agent;
838
+ session;
839
+ presentation;
840
+ llm;
841
+ constructor(runtime) {
842
+ this.runtime = runtime;
843
+ const platform = runtime.platform;
844
+ this.container = createLocalContainers(platform);
845
+ this.image = createLocalImages(platform);
846
+ this.agent = createLocalAgents(runtime);
847
+ this.session = createLocalSessions(runtime);
848
+ this.presentation = createPresentations(this);
849
+ this.llm = createLocalLLM(platform);
850
+ logger.info("LocalClient initialized");
851
+ }
852
+ // ==================== Properties ====================
853
+ get connected() {
854
+ return !this.isDisposed;
855
+ }
856
+ get events() {
857
+ return this.runtime.platform.eventBus;
858
+ }
859
+ // ==================== Event Subscription ====================
860
+ on(type, handler) {
861
+ return this.runtime.platform.eventBus.on(type, handler);
862
+ }
863
+ onAny(handler) {
864
+ return this.runtime.platform.eventBus.onAny(handler);
865
+ }
866
+ subscribe(_sessionId) {
867
+ }
868
+ // ==================== Error Handling ====================
869
+ onError(handler) {
870
+ return this.runtime.platform.eventBus.on("agentx_error", (event) => {
871
+ handler(event.data);
872
+ });
873
+ }
874
+ // ==================== RPC ====================
875
+ async rpc(method, params) {
876
+ if (!this.commandHandler) {
877
+ this.commandHandler = new CommandHandler(this.runtime);
878
+ }
879
+ const result = await this.commandHandler.handle(method, params);
880
+ if (result.success) {
881
+ return result.data;
882
+ }
883
+ throw new Error(result.message);
884
+ }
885
+ // ==================== Lifecycle ====================
886
+ async disconnect() {
887
+ }
888
+ async dispose() {
889
+ if (this.isDisposed) return;
890
+ await this.runtime.shutdown();
891
+ this.isDisposed = true;
892
+ logger.info("LocalClient disposed");
893
+ }
894
+ };
895
+
896
+ // src/RemoteClient.ts
897
+ import { EventBusImpl } from "@agentxjs/core/event";
898
+ import { RpcClient } from "@agentxjs/core/network";
899
+ import { createLogger as createLogger2 } from "commonxjs/logger";
900
+ var logger2 = createLogger2("agentx/RemoteClient");
901
+ var RemoteClient = class {
902
+ config;
903
+ eventBus;
904
+ rpcClient;
905
+ container;
906
+ image;
907
+ agent;
908
+ session;
909
+ presentation;
910
+ llm;
911
+ constructor(config) {
912
+ this.config = config;
913
+ this.eventBus = new EventBusImpl();
914
+ this.rpcClient = new RpcClient({
915
+ url: config.serverUrl,
916
+ createWebSocket: config.customPlatform?.channelClient,
917
+ timeout: config.timeout ?? 3e4,
918
+ autoReconnect: config.autoReconnect ?? true,
919
+ headers: config.headers,
920
+ debug: false
921
+ });
922
+ this.rpcClient.onStreamEvent((topic, event) => {
923
+ logger2.debug("Received stream event", { topic, type: event.type });
924
+ this.eventBus.emit(event);
925
+ });
926
+ this.container = createRemoteContainers(this.rpcClient);
927
+ this.image = createRemoteImages(this.rpcClient, (sessionId) => this.subscribe(sessionId));
928
+ this.agent = createRemoteAgents(this.rpcClient);
929
+ this.session = createRemoteSessions(this.rpcClient);
930
+ this.presentation = createPresentations(this);
931
+ this.llm = createRemoteLLM(this.rpcClient);
932
+ }
933
+ // ==================== Properties ====================
934
+ get connected() {
935
+ return this.rpcClient.connected;
936
+ }
937
+ get events() {
938
+ return this.eventBus;
939
+ }
940
+ // ==================== Connection ====================
941
+ async connect() {
942
+ await this.rpcClient.connect();
943
+ logger2.info("Connected to server", { url: this.config.serverUrl });
944
+ }
945
+ async disconnect() {
946
+ this.rpcClient.disconnect();
947
+ logger2.info("Disconnected from server");
948
+ }
949
+ async dispose() {
950
+ this.rpcClient.dispose();
951
+ this.eventBus.destroy();
952
+ logger2.info("RemoteClient disposed");
953
+ }
954
+ // ==================== Event Subscription ====================
955
+ on(type, handler) {
956
+ return this.eventBus.on(type, handler);
957
+ }
958
+ onAny(handler) {
959
+ return this.eventBus.onAny(handler);
960
+ }
961
+ subscribe(sessionId) {
962
+ this.rpcClient.subscribe(sessionId);
963
+ logger2.debug("Subscribed to session", { sessionId });
964
+ }
965
+ // ==================== Error Handling ====================
966
+ onError(handler) {
967
+ return this.eventBus.on("agentx_error", (event) => {
968
+ handler(event.data);
969
+ });
970
+ }
971
+ // ==================== RPC ====================
972
+ async rpc(method, params) {
973
+ return this.rpcClient.call(method, params);
974
+ }
975
+ };
976
+
977
+ // src/index.ts
978
+ import { AgentXError, AgentXErrorCode } from "@agentxjs/core/error";
979
+ function createAgentX(config) {
980
+ let localClient = null;
981
+ function getLocalClient() {
982
+ if (localClient) return localClient;
983
+ if (!config) {
984
+ throw new Error(
985
+ "Local mode requires a platform. Pass a PlatformConfig to createAgentX(), or use connect() for remote mode."
986
+ );
987
+ }
988
+ const runtime = createAgentXRuntime(config.platform, config.createDriver);
989
+ localClient = new LocalClient(runtime);
990
+ return localClient;
991
+ }
992
+ if (config) {
993
+ getLocalClient();
994
+ }
995
+ return {
996
+ get connected() {
997
+ return localClient?.connected ?? false;
998
+ },
999
+ get events() {
1000
+ return getLocalClient().events;
1001
+ },
1002
+ get container() {
1003
+ return getLocalClient().container;
1004
+ },
1005
+ get image() {
1006
+ return getLocalClient().image;
1007
+ },
1008
+ get agent() {
1009
+ return getLocalClient().agent;
1010
+ },
1011
+ get session() {
1012
+ return getLocalClient().session;
1013
+ },
1014
+ get presentation() {
1015
+ return getLocalClient().presentation;
1016
+ },
1017
+ get llm() {
1018
+ return getLocalClient().llm;
1019
+ },
1020
+ on(type, handler) {
1021
+ return getLocalClient().on(type, handler);
1022
+ },
1023
+ onAny(handler) {
1024
+ return getLocalClient().onAny(handler);
1025
+ },
1026
+ subscribe(sessionId) {
1027
+ getLocalClient().subscribe(sessionId);
1028
+ },
1029
+ onError(handler) {
1030
+ return getLocalClient().onError(handler);
1031
+ },
1032
+ async disconnect() {
1033
+ await localClient?.disconnect();
1034
+ },
1035
+ async dispose() {
1036
+ await localClient?.dispose();
1037
+ localClient = null;
1038
+ },
1039
+ async connect(serverUrl, options) {
1040
+ const remoteClient = new RemoteClient({
1041
+ serverUrl,
1042
+ headers: options?.headers,
1043
+ context: options?.context,
1044
+ timeout: options?.timeout,
1045
+ autoReconnect: options?.autoReconnect,
1046
+ customPlatform: config?.platform
1047
+ });
1048
+ await remoteClient.connect();
1049
+ return remoteClient;
1050
+ },
1051
+ async serve(serveConfig) {
1052
+ if (!config) {
1053
+ throw new Error("serve() requires a platform. Pass a PlatformConfig to createAgentX().");
1054
+ }
1055
+ if (!config.platform.channelServer) {
1056
+ throw new Error(
1057
+ "serve() requires platform.channelServer. Ensure your platform supports server mode."
1058
+ );
1059
+ }
1060
+ const { createServer: createServer2 } = await import("./server-BWI5JE4B.js");
1061
+ return createServer2({
1062
+ platform: config.platform,
1063
+ createDriver: config.createDriver,
1064
+ port: serveConfig?.port,
1065
+ host: serveConfig?.host,
1066
+ server: serveConfig?.server,
1067
+ wsPath: serveConfig?.wsPath
1068
+ });
1069
+ },
1070
+ async rpc(method, params) {
1071
+ return getLocalClient().rpc(method, params);
1072
+ }
1073
+ };
1074
+ }
1075
+ export {
1076
+ AgentXError,
1077
+ AgentXErrorCode,
1078
+ CommandHandler,
1079
+ Presentation,
1080
+ addUserConversation,
1081
+ createAgentX,
1082
+ createInitialState,
1083
+ createServer,
1084
+ initialPresentationState,
1085
+ messagesToConversations,
1086
+ presentationReducer
1087
+ };
1088
+ //# sourceMappingURL=index.js.map