agentxjs 0.0.9 → 0.1.2

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.
Files changed (54) hide show
  1. package/README.md +255 -464
  2. package/dist/browser.cjs +395 -0
  3. package/dist/browser.cjs.map +1 -0
  4. package/dist/browser.d.cts +32 -0
  5. package/dist/browser.d.ts +32 -0
  6. package/dist/browser.js +377 -0
  7. package/dist/browser.js.map +1 -0
  8. package/dist/index.cjs +521 -2779
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +27 -69
  11. package/dist/index.d.ts +27 -69
  12. package/dist/index.js +504 -2773
  13. package/dist/index.js.map +1 -1
  14. package/package.json +17 -40
  15. package/dist/runtime/sse/index.cjs +0 -633
  16. package/dist/runtime/sse/index.cjs.map +0 -1
  17. package/dist/runtime/sse/index.d.cts +0 -159
  18. package/dist/runtime/sse/index.d.ts +0 -159
  19. package/dist/runtime/sse/index.js +0 -621
  20. package/dist/runtime/sse/index.js.map +0 -1
  21. package/dist/server/adapters/express.cjs +0 -81
  22. package/dist/server/adapters/express.cjs.map +0 -1
  23. package/dist/server/adapters/express.d.cts +0 -75
  24. package/dist/server/adapters/express.d.ts +0 -75
  25. package/dist/server/adapters/express.js +0 -78
  26. package/dist/server/adapters/express.js.map +0 -1
  27. package/dist/server/adapters/hono.cjs +0 -32
  28. package/dist/server/adapters/hono.cjs.map +0 -1
  29. package/dist/server/adapters/hono.d.cts +0 -96
  30. package/dist/server/adapters/hono.d.ts +0 -96
  31. package/dist/server/adapters/hono.js +0 -28
  32. package/dist/server/adapters/hono.js.map +0 -1
  33. package/dist/server/adapters/index.cjs +0 -135
  34. package/dist/server/adapters/index.cjs.map +0 -1
  35. package/dist/server/adapters/index.d.cts +0 -5
  36. package/dist/server/adapters/index.d.ts +0 -5
  37. package/dist/server/adapters/index.js +0 -125
  38. package/dist/server/adapters/index.js.map +0 -1
  39. package/dist/server/adapters/next.cjs +0 -30
  40. package/dist/server/adapters/next.cjs.map +0 -1
  41. package/dist/server/adapters/next.d.cts +0 -107
  42. package/dist/server/adapters/next.d.ts +0 -107
  43. package/dist/server/adapters/next.js +0 -25
  44. package/dist/server/adapters/next.js.map +0 -1
  45. package/dist/server/index.cjs +0 -1093
  46. package/dist/server/index.cjs.map +0 -1
  47. package/dist/server/index.d.cts +0 -131
  48. package/dist/server/index.d.ts +0 -131
  49. package/dist/server/index.js +0 -1080
  50. package/dist/server/index.js.map +0 -1
  51. package/dist/types-Cgfcw91r.d.cts +0 -282
  52. package/dist/types-Cgfcw91r.d.ts +0 -282
  53. package/dist/types-OVKV6qpE.d.cts +0 -118
  54. package/dist/types-OVKV6qpE.d.ts +0 -118
package/dist/index.cjs CHANGED
@@ -1,2825 +1,567 @@
1
1
  'use strict';
2
2
 
3
- var common = require('@agentxjs/common');
4
- var ky = require('ky');
5
- var types = require('@agentxjs/types');
6
- var rxjs = require('rxjs');
7
- var operators = require('rxjs/operators');
8
-
9
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
-
11
- var ky__default = /*#__PURE__*/_interopDefault(ky);
12
-
13
- var __defProp = Object.defineProperty;
14
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
15
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
16
-
17
- // src/defineAgent.ts
18
- function defineAgent(input) {
19
- const { name, description, systemPrompt } = input;
20
- return {
21
- name,
22
- description,
23
- systemPrompt
24
- };
25
- }
26
- var logger = common.createLogger("agentx/DefinitionManager");
27
- function generateMetaImageId(definitionName) {
28
- return `meta_${definitionName}`;
29
- }
30
- function toDefinitionRecord(definition) {
31
- const now = /* @__PURE__ */ new Date();
32
- return {
33
- name: definition.name,
34
- description: definition.description,
35
- systemPrompt: definition.systemPrompt,
36
- definition,
37
- source: "code",
38
- createdAt: now,
39
- updatedAt: now
40
- };
41
- }
42
- var DefinitionManagerImpl = class {
43
- constructor(repository) {
44
- this.repository = repository;
45
- // Local cache for sync access
46
- __publicField(this, "cache", /* @__PURE__ */ new Map());
47
- }
48
- register(definition) {
49
- if (this.cache.has(definition.name)) {
50
- throw new Error(`Definition already exists: ${definition.name}`);
51
- }
52
- this.cache.set(definition.name, definition);
53
- const definitionRecord = toDefinitionRecord(definition);
54
- this.repository.saveDefinition(definitionRecord).catch((err) => {
55
- logger.error("Failed to save definition", { name: definition.name, error: err });
56
- });
57
- const metaImageId = generateMetaImageId(definition.name);
58
- const imageRecord = {
59
- imageId: metaImageId,
60
- type: "meta",
61
- definitionName: definition.name,
62
- parentImageId: null,
63
- definition,
64
- config: {},
65
- messages: [],
66
- createdAt: /* @__PURE__ */ new Date()
67
- };
68
- this.repository.saveImage(imageRecord).catch((err) => {
69
- logger.error("Failed to save MetaImage", { definitionName: definition.name, error: err });
70
- });
71
- logger.info("Definition registered", {
72
- name: definition.name,
73
- metaImageId
74
- });
75
- }
76
- get(name) {
77
- return this.cache.get(name);
78
- }
79
- list() {
80
- return Array.from(this.cache.values());
81
- }
82
- has(name) {
83
- return this.cache.has(name);
84
- }
85
- unregister(name) {
86
- const definition = this.cache.get(name);
87
- if (!definition) {
88
- return false;
89
- }
90
- this.cache.delete(name);
91
- this.repository.deleteDefinition(name).catch((err) => {
92
- logger.error("Failed to delete definition", { name, error: err });
93
- });
94
- const metaImageId = generateMetaImageId(name);
95
- this.repository.deleteImage(metaImageId).catch((err) => {
96
- logger.error("Failed to delete MetaImage", { definitionName: name, error: err });
97
- });
98
- logger.info("Definition unregistered", { name });
99
- return true;
100
- }
101
- };
102
- var logger2 = common.createLogger("agentx/ImageManager");
103
- function generateMetaImageId2(definitionName) {
104
- return `meta_${definitionName}`;
105
- }
106
- function toAgentImage(record) {
107
- const definition = record.definition;
108
- if (record.type === "meta") {
109
- const metaImage = {
110
- type: "meta",
111
- imageId: record.imageId,
112
- definitionName: record.definitionName,
113
- definition,
114
- config: record.config,
115
- messages: [],
116
- createdAt: record.createdAt
117
- };
118
- return metaImage;
119
- } else {
120
- return {
121
- type: "derived",
122
- imageId: record.imageId,
123
- parentImageId: record.parentImageId,
124
- definitionName: record.definitionName,
125
- definition,
126
- config: record.config,
127
- messages: record.messages,
128
- createdAt: record.createdAt
129
- };
130
- }
131
- }
132
- var ImageManagerImpl = class {
133
- constructor(repository, containerManager, defaultContainerId) {
134
- __publicField(this, "repository");
135
- __publicField(this, "containerManager");
136
- __publicField(this, "defaultContainerId");
137
- this.repository = repository;
138
- this.containerManager = containerManager;
139
- this.defaultContainerId = defaultContainerId;
140
- }
141
- async get(imageId) {
142
- const record = await this.repository.findImageById(imageId);
143
- if (!record) {
144
- return void 0;
145
- }
146
- return toAgentImage(record);
147
- }
148
- async getMetaImage(definitionName) {
149
- const metaImageId = generateMetaImageId2(definitionName);
150
- const record = await this.repository.findImageById(metaImageId);
151
- if (!record || record.type !== "meta") {
152
- return void 0;
153
- }
154
- return toAgentImage(record);
155
- }
156
- async list() {
157
- const records = await this.repository.findAllImages();
158
- return records.map(toAgentImage);
159
- }
160
- async listByDefinition(definitionName) {
161
- const allRecords = await this.repository.findAllImages();
162
- const filtered = allRecords.filter((r) => r.definitionName === definitionName);
163
- return filtered.map(toAgentImage);
164
- }
165
- async exists(imageId) {
166
- return this.repository.imageExists(imageId);
167
- }
168
- async delete(imageId) {
169
- const record = await this.repository.findImageById(imageId);
170
- if (!record) {
171
- return false;
172
- }
173
- if (record.type === "meta") {
174
- logger2.warn("Cannot delete MetaImage directly", { imageId });
175
- return false;
176
- }
177
- await this.repository.deleteImage(imageId);
178
- logger2.info("Image deleted", { imageId });
179
- return true;
180
- }
181
- async run(imageId, options) {
182
- logger2.info("Running agent from image", { imageId, containerId: options?.containerId });
183
- const image = await this.get(imageId);
184
- if (!image) {
185
- throw new Error(`Image not found: ${imageId}`);
186
- }
187
- let containerId = options?.containerId || this.defaultContainerId;
188
- if (!containerId) {
189
- const container = await this.containerManager.create();
190
- containerId = container.containerId;
191
- this.defaultContainerId = containerId;
192
- logger2.debug("Auto-created default container", { containerId });
193
- }
194
- return this.containerManager.run(image, containerId);
195
- }
196
- };
197
- var logger3 = common.createLogger("agentx/AgentManager");
198
- var AgentManager = class {
199
- constructor(containerManager) {
200
- this.containerManager = containerManager;
201
- }
202
- /**
203
- * Get an existing agent by ID
204
- */
205
- get(agentId) {
206
- return this.containerManager.getAgent(agentId);
207
- }
208
- /**
209
- * Check if an agent exists
210
- */
211
- has(agentId) {
212
- return this.containerManager.hasAgent(agentId);
213
- }
214
- /**
215
- * List all agents
216
- */
217
- list() {
218
- return this.containerManager.listAgents();
219
- }
220
- /**
221
- * Destroy an agent by ID
222
- */
223
- async destroy(agentId) {
224
- logger3.debug("Destroying agent", { agentId });
225
- await this.containerManager.destroyAgent(agentId);
226
- logger3.info("Agent destroyed", { agentId });
227
- }
228
- /**
229
- * Destroy all agents
230
- */
231
- async destroyAll() {
232
- const agents = this.containerManager.listAgents();
233
- logger3.debug("Destroying all agents", { count: agents.length });
234
- await this.containerManager.destroyAllAgents();
235
- logger3.info("All agents destroyed", { count: agents.length });
236
- }
237
- };
238
- var logger4 = common.createLogger("agentx/SessionManager");
239
- function generateSessionId() {
240
- const timestamp = Date.now().toString(36);
241
- const random = Math.random().toString(36).substring(2, 8);
242
- return `session_${timestamp}_${random}`;
243
- }
244
- function generateImageId() {
245
- const timestamp = Date.now().toString(36);
246
- const random = Math.random().toString(36).substring(2, 8);
247
- return `image_${timestamp}_${random}`;
248
- }
249
- var SessionImpl = class _SessionImpl {
250
- constructor(record, repository, containerManager, defaultContainerId) {
251
- __publicField(this, "sessionId");
252
- __publicField(this, "userId");
253
- __publicField(this, "imageId");
254
- __publicField(this, "createdAt");
255
- __publicField(this, "_title");
256
- __publicField(this, "_updatedAt");
257
- __publicField(this, "repository");
258
- __publicField(this, "containerManager");
259
- __publicField(this, "defaultContainerId");
260
- this.sessionId = record.sessionId;
261
- this.userId = record.userId;
262
- this.imageId = record.imageId;
263
- this._title = record.title;
264
- this.createdAt = record.createdAt.getTime();
265
- this._updatedAt = record.updatedAt.getTime();
266
- this.repository = repository;
267
- this.containerManager = containerManager;
268
- this.defaultContainerId = defaultContainerId;
269
- }
270
- get title() {
271
- return this._title;
272
- }
273
- get updatedAt() {
274
- return this._updatedAt;
275
- }
276
- async resume(options) {
277
- logger4.info("Resuming agent from session", {
278
- sessionId: this.sessionId,
279
- imageId: this.imageId,
280
- containerId: options?.containerId
281
- });
282
- let containerId = options?.containerId || this.defaultContainerId;
283
- if (!containerId) {
284
- const container = await this.containerManager.create();
285
- containerId = container.containerId;
286
- logger4.debug("Auto-created default container for session", {
287
- containerId,
288
- sessionId: this.sessionId
289
- });
290
- }
291
- const agent = await this.containerManager.resume(this, containerId);
292
- this.collect(agent);
293
- return agent;
294
- }
295
- collect(agent) {
296
- logger4.debug("Collecting messages from agent", {
297
- sessionId: this.sessionId,
298
- agentId: agent.agentId
299
- });
300
- const sessionId = this.sessionId;
301
- const repository = this.repository;
302
- const saveMessage = (data, role) => {
303
- const record = {
304
- messageId: data.id,
305
- sessionId,
306
- role,
307
- content: data,
308
- createdAt: new Date(data.timestamp ?? Date.now())
309
- };
310
- repository.saveMessage(record).catch((error) => {
311
- logger4.error("Failed to persist message", {
312
- sessionId,
313
- messageId: record.messageId,
314
- error
315
- });
316
- });
317
- };
318
- agent.on("user_message", (event) => saveMessage(event.data, "user"));
319
- agent.on("assistant_message", (event) => saveMessage(event.data, "assistant"));
320
- agent.on("tool_call_message", (event) => saveMessage(event.data, "tool"));
321
- agent.on("tool_result_message", (event) => saveMessage(event.data, "tool"));
322
- }
323
- async getMessages() {
324
- logger4.debug("Getting messages for session", { sessionId: this.sessionId });
325
- const records = await this.repository.findMessagesBySessionId(this.sessionId);
326
- return records.map((record) => record.content);
327
- }
328
- async fork() {
329
- logger4.info("Forking session", { sessionId: this.sessionId });
330
- const imageRecord = await this.repository.findImageById(this.imageId);
331
- if (!imageRecord) {
332
- throw new Error(`Image not found: ${this.imageId}`);
333
- }
334
- const newImageId = generateImageId();
335
- const newImageRecord = {
336
- imageId: newImageId,
337
- type: "derived",
338
- definitionName: imageRecord.definitionName,
339
- parentImageId: imageRecord.imageId,
340
- definition: imageRecord.definition,
341
- config: imageRecord.config,
342
- messages: [...imageRecord.messages],
343
- // Copy messages
344
- createdAt: /* @__PURE__ */ new Date()
345
- };
346
- await this.repository.saveImage(newImageRecord);
347
- const newSessionId = generateSessionId();
348
- const now = /* @__PURE__ */ new Date();
349
- const newSessionRecord = {
350
- sessionId: newSessionId,
351
- userId: this.userId,
352
- imageId: newImageId,
353
- title: this._title ? `Fork of ${this._title}` : null,
354
- createdAt: now,
355
- updatedAt: now
356
- };
357
- await this.repository.saveSession(newSessionRecord);
358
- logger4.info("Session forked", {
359
- originalSessionId: this.sessionId,
360
- newSessionId,
361
- newImageId
362
- });
363
- return new _SessionImpl(
364
- newSessionRecord,
365
- this.repository,
366
- this.containerManager,
367
- this.defaultContainerId
368
- );
369
- }
370
- async setTitle(title) {
371
- logger4.debug("Setting session title", { sessionId: this.sessionId, title });
372
- const now = /* @__PURE__ */ new Date();
373
- await this.repository.saveSession({
374
- sessionId: this.sessionId,
375
- userId: this.userId,
376
- imageId: this.imageId,
377
- title,
378
- createdAt: new Date(this.createdAt),
379
- updatedAt: now
380
- });
381
- this._title = title;
382
- this._updatedAt = now.getTime();
383
- logger4.info("Session title updated", { sessionId: this.sessionId, title });
384
- }
385
- };
386
- var SessionManagerImpl = class {
387
- constructor(repository, containerManager, defaultContainerId) {
388
- __publicField(this, "repository");
389
- __publicField(this, "containerManager");
390
- __publicField(this, "defaultContainerId");
391
- this.repository = repository;
392
- this.containerManager = containerManager;
393
- this.defaultContainerId = defaultContainerId;
394
- }
395
- async create(imageId, userId) {
396
- const sessionId = generateSessionId();
397
- const now = /* @__PURE__ */ new Date();
398
- const record = {
399
- sessionId,
400
- userId,
401
- imageId,
402
- title: null,
403
- createdAt: now,
404
- updatedAt: now
405
- };
406
- await this.repository.saveSession(record);
407
- logger4.info("Session created", { sessionId, imageId, userId });
408
- return new SessionImpl(record, this.repository, this.containerManager, this.defaultContainerId);
409
- }
410
- async get(sessionId) {
411
- const record = await this.repository.findSessionById(sessionId);
412
- if (!record) return void 0;
413
- return new SessionImpl(record, this.repository, this.containerManager, this.defaultContainerId);
414
- }
415
- async has(sessionId) {
416
- return this.repository.sessionExists(sessionId);
417
- }
418
- async list() {
419
- const records = await this.repository.findAllSessions();
420
- return records.map(
421
- (r) => new SessionImpl(r, this.repository, this.containerManager, this.defaultContainerId)
422
- );
423
- }
424
- async listByImage(imageId) {
425
- const records = await this.repository.findSessionsByImageId(imageId);
426
- return records.map(
427
- (r) => new SessionImpl(r, this.repository, this.containerManager, this.defaultContainerId)
428
- );
429
- }
430
- async listByUser(userId) {
431
- const records = await this.repository.findSessionsByUserId(userId);
432
- return records.map(
433
- (r) => new SessionImpl(r, this.repository, this.containerManager, this.defaultContainerId)
434
- );
435
- }
436
- async destroy(sessionId) {
437
- await this.repository.deleteSession(sessionId);
438
- logger4.info("Session destroyed", { sessionId });
439
- }
440
- async destroyByImage(imageId) {
441
- await this.repository.deleteSessionsByImageId(imageId);
442
- logger4.info("Sessions destroyed by image", { imageId });
443
- }
444
- async destroyAll() {
445
- const sessions = await this.repository.findAllSessions();
446
- for (const session of sessions) {
447
- await this.repository.deleteSession(session.sessionId);
448
- }
449
- logger4.info("All sessions destroyed");
450
- }
451
- };
452
- var logger5 = common.createLogger("agentx/ErrorManager");
453
- var ErrorManager = class {
454
- constructor() {
455
- __publicField(this, "handlers", /* @__PURE__ */ new Set());
456
- }
457
- /**
458
- * Handle an error from any agent
459
- *
460
- * Called internally when an agent emits an error event.
461
- * 1. Default logging (always)
462
- * 2. Custom handlers (user-registered)
463
- */
464
- handle(agentId, error, event) {
465
- this.logError(agentId, error);
466
- for (const handler of this.handlers) {
467
- try {
468
- handler.handle(agentId, error, event);
469
- } catch (e) {
470
- logger5.error("ErrorHandler failed", { error: e });
471
- }
472
- }
473
- }
474
- /**
475
- * Add a custom error handler
476
- */
477
- addHandler(handler) {
478
- this.handlers.add(handler);
479
- return () => {
480
- this.handlers.delete(handler);
481
- };
482
- }
483
- /**
484
- * Remove an error handler
485
- */
486
- removeHandler(handler) {
487
- this.handlers.delete(handler);
488
- }
489
- /**
490
- * Default error logging
491
- */
492
- logError(agentId, error) {
493
- const prefix = `[${agentId}] ${error.category}/${error.code}`;
494
- if (error.severity === "fatal") {
495
- logger5.error(`${prefix}: ${error.message}`, { error });
496
- } else if (error.severity === "error") {
497
- logger5.error(`${prefix}: ${error.message}`);
498
- } else {
499
- logger5.warn(`${prefix}: ${error.message}`);
500
- }
501
- }
502
- };
503
- var ApiError = class extends Error {
504
- constructor(code, message, details) {
505
- super(message);
506
- this.code = code;
507
- this.details = details;
508
- this.name = "ApiError";
509
- }
510
- };
511
- function createHttpClient(options) {
512
- return ky__default.default.create({
513
- prefixUrl: options.baseUrl.replace(/\/+$/, ""),
514
- headers: options.headers,
515
- timeout: options.timeout || 3e4,
516
- hooks: {
517
- afterResponse: [
518
- async (_request, _options, response) => {
519
- if (!response.ok) {
520
- const data = await response.json().catch(() => ({}));
521
- throw new ApiError(
522
- data.error?.code || "UNKNOWN_ERROR",
523
- data.error?.message || `Request failed: ${response.status}`,
524
- data.error?.details
525
- );
526
- }
527
- return response;
528
- }
529
- ]
530
- }
531
- });
532
- }
533
- var logger6 = common.createLogger("core/AgentStateMachine");
534
- var AgentStateMachine = class {
535
- constructor() {
536
- __publicField(this, "_state", "idle");
537
- __publicField(this, "handlers", /* @__PURE__ */ new Set());
538
- }
539
- /**
540
- * Current agent state
541
- */
542
- get state() {
543
- return this._state;
544
- }
545
- /**
546
- * Process a StateEvent and update internal state
547
- *
548
- * @param event - StateEvent from Engine layer
549
- */
550
- process(event) {
551
- const prev = this._state;
552
- const next = this.mapEventToState(event);
553
- if (next !== null && prev !== next) {
554
- this._state = next;
555
- logger6.debug("State transition", {
556
- eventType: event.type,
557
- from: prev,
558
- to: next
559
- });
560
- this.notifyHandlers({ prev, current: next });
561
- }
562
- }
563
- /**
564
- * Subscribe to state changes
565
- *
566
- * @param handler - Callback receiving { prev, current } state change
567
- * @returns Unsubscribe function
568
- */
569
- onStateChange(handler) {
570
- this.handlers.add(handler);
571
- return () => {
572
- this.handlers.delete(handler);
573
- };
574
- }
575
- /**
576
- * Reset state machine (used on destroy)
577
- */
578
- reset() {
579
- this._state;
580
- this._state = "idle";
581
- this.handlers.clear();
582
- }
583
- /**
584
- * Map StateEvent type to AgentState
585
- *
586
- * @param event - StateEvent from Engine
587
- * @returns New AgentState or null if no transition needed
588
- */
589
- mapEventToState(event) {
590
- switch (event.type) {
591
- // Agent lifecycle
592
- case "agent_initializing":
593
- return "initializing";
594
- case "agent_ready":
595
- return "idle";
596
- case "agent_destroyed":
597
- return "idle";
598
- // Conversation lifecycle
599
- case "conversation_queued":
600
- return "queued";
601
- case "conversation_start":
602
- return "conversation_active";
603
- case "conversation_thinking":
604
- return "thinking";
605
- case "conversation_responding":
606
- return "responding";
607
- case "conversation_end":
608
- return "idle";
609
- case "conversation_interrupted":
610
- return "idle";
611
- // Return to idle on interrupt
612
- // Tool lifecycle
613
- case "tool_planned":
614
- return "planning_tool";
615
- case "tool_executing":
616
- return "awaiting_tool_result";
617
- case "tool_completed":
618
- return "responding";
619
- // Back to responding after tool completes
620
- case "tool_failed":
621
- return "responding";
622
- // Continue responding after tool failure
623
- // Error
624
- case "error_occurred":
625
- return "idle";
626
- // Reset to idle on error
627
- default:
628
- return null;
629
- }
630
- }
631
- /**
632
- * Notify all registered handlers of state change
633
- */
634
- notifyHandlers(change) {
635
- for (const handler of this.handlers) {
636
- try {
637
- handler(change);
638
- } catch (error) {
639
- logger6.error("State change handler error", {
640
- from: change.prev,
641
- to: change.current,
642
- error
643
- });
644
- }
645
- }
646
- }
647
- };
648
- var logger22 = common.createLogger("core/AgentEventBus");
649
- var AgentEventBus = class {
650
- constructor() {
651
- __publicField(this, "subject", new rxjs.Subject());
652
- __publicField(this, "typeSubscriptions", /* @__PURE__ */ new Map());
653
- __publicField(this, "globalSubscriptions", []);
654
- __publicField(this, "nextId", 0);
655
- __publicField(this, "isDestroyed", false);
656
- // Cached views
657
- __publicField(this, "producerView", null);
658
- __publicField(this, "consumerView", null);
659
- }
660
- // ===== Producer Methods =====
661
- emit(event) {
662
- if (this.isDestroyed) {
663
- logger22.warn("Emit called on destroyed EventBus", { eventType: event.type });
664
- return;
665
- }
666
- this.subject.next(event);
667
- }
668
- emitBatch(events) {
669
- for (const event of events) {
670
- this.emit(event);
671
- }
672
- }
673
- on(typeOrTypes, handler, options = {}) {
674
- if (this.isDestroyed) {
675
- logger22.warn("Subscribe called on destroyed EventBus");
676
- return () => {
677
- };
678
- }
679
- const types = Array.isArray(typeOrTypes) ? typeOrTypes : [typeOrTypes];
680
- const unsubscribes = [];
681
- for (const type of types) {
682
- const unsub = this.subscribeToType(type, handler, options);
683
- unsubscribes.push(unsub);
684
- }
685
- return () => unsubscribes.forEach((u) => u());
686
- }
687
- onAny(handler, options = {}) {
688
- if (this.isDestroyed) {
689
- logger22.warn("Subscribe called on destroyed EventBus");
690
- return () => {
691
- };
692
- }
693
- return this.subscribeGlobal(handler, options);
694
- }
695
- once(type, handler) {
696
- return this.on(type, handler, { once: true });
697
- }
698
- // ===== View Methods =====
699
- asConsumer() {
700
- if (!this.consumerView) {
701
- this.consumerView = {
702
- on: this.on.bind(this),
703
- onAny: this.onAny.bind(this),
704
- once: this.once.bind(this)
705
- };
706
- }
707
- return this.consumerView;
708
- }
709
- asProducer() {
710
- if (!this.producerView) {
711
- this.producerView = {
712
- emit: this.emit.bind(this),
713
- emitBatch: this.emitBatch.bind(this)
714
- };
715
- }
716
- return this.producerView;
717
- }
718
- // ===== Lifecycle =====
719
- destroy() {
720
- if (this.isDestroyed) return;
721
- this.isDestroyed = true;
722
- for (const records of this.typeSubscriptions.values()) {
723
- for (const record of records) {
724
- record.unsubscribe();
725
- }
726
- }
727
- this.typeSubscriptions.clear();
728
- for (const record of this.globalSubscriptions) {
729
- record.unsubscribe();
730
- }
731
- this.globalSubscriptions.length = 0;
732
- this.subject.complete();
733
- logger22.debug("EventBus destroyed");
734
- }
735
- // ===== Private Methods =====
736
- subscribeToType(type, handler, options) {
737
- const { filter: filter$1, priority = 0, once = false } = options;
738
- const id = this.nextId++;
739
- let observable = this.subject.pipe(operators.filter((e) => e.type === type));
740
- if (filter$1) {
741
- observable = observable.pipe(operators.filter(filter$1));
742
- }
743
- if (once) {
744
- observable = observable.pipe(operators.take(1));
745
- }
746
- const subscription = observable.subscribe({
747
- next: (event) => {
748
- this.executeWithPriority(type, event, handler, id);
749
- }
750
- });
751
- const unsubscribe = () => {
752
- subscription.unsubscribe();
753
- const records2 = this.typeSubscriptions.get(type);
754
- if (records2) {
755
- const idx = records2.findIndex((r) => r.id === id);
756
- if (idx !== -1) records2.splice(idx, 1);
757
- }
758
- };
759
- if (!this.typeSubscriptions.has(type)) {
760
- this.typeSubscriptions.set(type, []);
761
- }
762
- const record = { id, priority, handler, unsubscribe };
763
- const records = this.typeSubscriptions.get(type);
764
- records.push(record);
765
- records.sort((a, b) => b.priority - a.priority);
766
- return unsubscribe;
767
- }
768
- subscribeGlobal(handler, options) {
769
- const { filter: filter$1, priority = 0, once = false } = options;
770
- const id = this.nextId++;
771
- let observable = this.subject.asObservable();
772
- if (filter$1) {
773
- observable = observable.pipe(operators.filter(filter$1));
774
- }
775
- if (once) {
776
- observable = observable.pipe(operators.take(1));
777
- }
778
- const subscription = observable.subscribe({
779
- next: (event) => {
780
- this.executeGlobalWithPriority(event, handler, id);
781
- }
782
- });
783
- const unsubscribe = () => {
784
- subscription.unsubscribe();
785
- const idx = this.globalSubscriptions.findIndex((r) => r.id === id);
786
- if (idx !== -1) this.globalSubscriptions.splice(idx, 1);
787
- };
788
- const record = { id, priority, handler, unsubscribe };
789
- this.globalSubscriptions.push(record);
790
- this.globalSubscriptions.sort((a, b) => b.priority - a.priority);
791
- return unsubscribe;
792
- }
793
- /**
794
- * Execute handler respecting priority order for typed subscriptions
795
- */
796
- executeWithPriority(type, event, handler, handlerId) {
797
- const records = this.typeSubscriptions.get(type) || [];
798
- const record = records.find((r) => r.id === handlerId);
799
- if (record) {
800
- try {
801
- handler(event);
802
- } catch (error) {
803
- logger22.error("Event handler error", { eventType: type, error });
804
- }
805
- }
806
- }
807
- /**
808
- * Execute handler respecting priority order for global subscriptions
809
- */
810
- executeGlobalWithPriority(event, handler, handlerId) {
811
- const record = this.globalSubscriptions.find((r) => r.id === handlerId);
812
- if (record) {
813
- try {
814
- handler(event);
815
- } catch (error) {
816
- logger22.error("Global event handler error", { eventType: event.type, error });
817
- }
818
- }
819
- }
820
- };
821
- var AgentErrorClassifier = class {
822
- constructor(agentId) {
823
- this.agentId = agentId;
824
- }
825
- /**
826
- * Classify an unknown error into an AgentError
827
- */
828
- classify(error) {
829
- const err = error instanceof Error ? error : new Error(String(error));
830
- const message = err.message;
831
- if (message.includes("rate limit") || message.includes("429")) {
832
- return this.create("llm", "RATE_LIMITED", message, true, err);
833
- }
834
- if (message.includes("api key") || message.includes("401") || message.includes("unauthorized")) {
835
- return this.create("llm", "INVALID_API_KEY", message, false, err);
836
- }
837
- if (message.includes("context") && message.includes("long")) {
838
- return this.create("llm", "CONTEXT_TOO_LONG", message, true, err);
839
- }
840
- if (message.includes("overloaded") || message.includes("503")) {
841
- return this.create("llm", "OVERLOADED", message, true, err);
842
- }
843
- if (message.includes("timeout") || message.includes("ETIMEDOUT")) {
844
- return this.create("network", "TIMEOUT", message, true, err);
845
- }
846
- if (message.includes("ECONNREFUSED") || message.includes("connection")) {
847
- return this.create("network", "CONNECTION_FAILED", message, true, err);
848
- }
849
- if (message.includes("network") || message.includes("fetch")) {
850
- return this.create("network", "CONNECTION_FAILED", message, true, err);
851
- }
852
- if (message.includes("driver")) {
853
- return this.create("driver", "RECEIVE_FAILED", message, true, err);
854
- }
855
- return this.create("system", "UNKNOWN", message, true, err);
856
- }
857
- /**
858
- * Create an AgentError with the specified category and code
859
- */
860
- create(category, code, message, recoverable, cause) {
861
- return {
862
- category,
863
- code,
864
- message,
865
- severity: recoverable ? "error" : "fatal",
866
- recoverable,
867
- cause
868
- };
869
- }
870
- /**
871
- * Create an ErrorEvent from an AgentError
872
- *
873
- * ErrorEvent is independent from Message layer and transportable via SSE.
874
- */
875
- createEvent(error) {
876
- return {
877
- type: "error",
878
- uuid: `${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
879
- agentId: this.agentId,
880
- timestamp: Date.now(),
881
- data: {
882
- error
883
- }
884
- };
885
- }
886
- };
887
- var MiddlewareChain = class {
888
- constructor() {
889
- __publicField(this, "middlewares", []);
890
- }
891
- /**
892
- * Add middleware to the chain
893
- *
894
- * @param middleware - Middleware function
895
- * @returns Unsubscribe function to remove the middleware
896
- */
897
- use(middleware) {
898
- this.middlewares.push(middleware);
899
- return () => {
900
- const index = this.middlewares.indexOf(middleware);
901
- if (index !== -1) {
902
- this.middlewares.splice(index, 1);
903
- }
904
- };
905
- }
906
- /**
907
- * Execute the middleware chain
908
- *
909
- * @param message - User message to process
910
- * @param finalHandler - Handler called at the end of the chain
911
- */
912
- async execute(message, finalHandler) {
913
- let index = 0;
914
- const next = async (msg) => {
915
- if (index < this.middlewares.length) {
916
- const middleware = this.middlewares[index++];
917
- await middleware(msg, next);
918
- } else {
919
- await finalHandler(msg);
920
- }
921
- };
922
- await next(message);
923
- }
924
- /**
925
- * Clear all middlewares
926
- */
927
- clear() {
928
- this.middlewares.length = 0;
929
- }
930
- /**
931
- * Get the number of middlewares
932
- */
933
- get size() {
934
- return this.middlewares.length;
935
- }
936
- };
937
- var logger32 = common.createLogger("core/InterceptorChain");
938
- var InterceptorChain = class {
939
- constructor(agentId) {
940
- __publicField(this, "interceptors", []);
941
- __publicField(this, "agentId");
942
- this.agentId = agentId;
943
- }
944
- /**
945
- * Add interceptor to the chain
946
- *
947
- * @param interceptor - Interceptor function
948
- * @returns Unsubscribe function to remove the interceptor
949
- */
950
- intercept(interceptor) {
951
- this.interceptors.push(interceptor);
952
- return () => {
953
- const index = this.interceptors.indexOf(interceptor);
954
- if (index !== -1) {
955
- this.interceptors.splice(index, 1);
956
- }
957
- };
958
- }
959
- /**
960
- * Execute the interceptor chain
961
- *
962
- * @param event - Event to process
963
- * @param finalHandler - Handler called at the end of the chain
964
- */
965
- execute(event, finalHandler) {
966
- let index = 0;
967
- const next = (e) => {
968
- if (index < this.interceptors.length) {
969
- const interceptor = this.interceptors[index++];
970
- try {
971
- interceptor(e, next);
972
- } catch (error) {
973
- logger32.error("Interceptor error", {
974
- agentId: this.agentId,
975
- eventType: e.type,
976
- interceptorIndex: index - 1,
977
- error
978
- });
979
- next(e);
980
- }
981
- } else {
982
- finalHandler(e);
983
- }
984
- };
985
- next(event);
986
- }
987
- /**
988
- * Clear all interceptors
989
- */
990
- clear() {
991
- this.interceptors.length = 0;
992
- }
993
- /**
994
- * Get the number of interceptors
995
- */
996
- get size() {
997
- return this.interceptors.length;
998
- }
999
- };
1000
- var REACT_TO_EVENT_MAP = {
1001
- // Stream Layer Events
1002
- onMessageStart: "message_start",
1003
- onMessageDelta: "message_delta",
1004
- onMessageStop: "message_stop",
1005
- onTextContentBlockStart: "text_content_block_start",
1006
- onTextDelta: "text_delta",
1007
- onTextContentBlockStop: "text_content_block_stop",
1008
- onToolUseContentBlockStart: "tool_use_content_block_start",
1009
- onInputJsonDelta: "input_json_delta",
1010
- onToolUseContentBlockStop: "tool_use_content_block_stop",
1011
- onToolCall: "tool_call",
1012
- onToolResult: "tool_result",
1013
- // Message Layer Events
1014
- onUserMessage: "user_message",
1015
- onAssistantMessage: "assistant_message",
1016
- onToolCallMessage: "tool_call_message",
1017
- onToolResultMessage: "tool_result_message",
1018
- // Error Layer Events (independent, transportable via SSE)
1019
- onError: "error",
1020
- // Turn Layer Events
1021
- onTurnRequest: "turn_request",
1022
- onTurnResponse: "turn_response"
1023
- };
1024
- function mapReactHandlers(reactHandlers) {
1025
- const eventHandlerMap = {};
1026
- for (const [reactKey, eventKey] of Object.entries(REACT_TO_EVENT_MAP)) {
1027
- const handler = reactHandlers[reactKey];
1028
- if (handler) {
1029
- eventHandlerMap[eventKey] = handler;
1030
- }
1031
- }
1032
- return eventHandlerMap;
1033
- }
1034
- var logger42 = common.createLogger("core/AgentInstance");
1035
- var AgentInstance = class {
1036
- constructor(definition, context, engine, driver, sandbox) {
1037
- __publicField(this, "agentId");
1038
- __publicField(this, "definition");
1039
- __publicField(this, "context");
1040
- __publicField(this, "createdAt");
1041
- __publicField(this, "sandbox");
1042
- __publicField(this, "_lifecycle", "running");
1043
- __publicField(this, "engine");
1044
- /**
1045
- * Driver instance - created from definition.driver class
1046
- */
1047
- __publicField(this, "driver");
1048
- /**
1049
- * State machine - manages state transitions driven by StateEvents
1050
- */
1051
- __publicField(this, "stateMachine", new AgentStateMachine());
1052
- /**
1053
- * Event bus - centralized event pub/sub
1054
- */
1055
- __publicField(this, "eventBus", new AgentEventBus());
1056
- /**
1057
- * Error classifier - classifies and creates error events
1058
- */
1059
- __publicField(this, "errorClassifier");
1060
- /**
1061
- * Middleware chain for receive() interception
1062
- */
1063
- __publicField(this, "middlewareChain", new MiddlewareChain());
1064
- /**
1065
- * Interceptor chain for event dispatch interception
1066
- */
1067
- __publicField(this, "interceptorChain");
1068
- /**
1069
- * Lifecycle handlers for onReady
1070
- */
1071
- __publicField(this, "readyHandlers", /* @__PURE__ */ new Set());
1072
- /**
1073
- * Lifecycle handlers for onDestroy
1074
- */
1075
- __publicField(this, "destroyHandlers", /* @__PURE__ */ new Set());
1076
- this.agentId = context.agentId;
1077
- this.definition = definition;
1078
- this.context = context;
1079
- this.engine = engine;
1080
- this.createdAt = context.createdAt;
1081
- this.sandbox = sandbox;
1082
- this.driver = driver;
1083
- this.errorClassifier = new AgentErrorClassifier(this.agentId);
1084
- this.interceptorChain = new InterceptorChain(this.agentId);
1085
- logger42.debug("AgentInstance created", {
1086
- agentId: this.agentId,
1087
- definitionName: definition.name,
1088
- driverName: this.driver.name
1089
- });
1090
- }
1091
- /**
1092
- * Current lifecycle state
1093
- */
1094
- get lifecycle() {
1095
- return this._lifecycle;
1096
- }
1097
- /**
1098
- * Current conversation state (delegated to StateMachine)
1099
- */
1100
- get state() {
1101
- return this.stateMachine.state;
1102
- }
1103
- /**
1104
- * Receive a message from user
1105
- *
1106
- * Runs through middleware chain before actual processing.
1107
- *
1108
- * Error Handling:
1109
- * - Errors are caught and converted to ErrorMessageEvent
1110
- * - Handlers receive the error event before re-throwing
1111
- * - This ensures UI can display errors
1112
- */
1113
- async receive(message) {
1114
- if (this._lifecycle === "destroyed") {
1115
- logger42.warn("Receive called on destroyed agent", { agentId: this.agentId });
1116
- const error = this.errorClassifier.create(
1117
- "system",
1118
- "AGENT_DESTROYED",
1119
- "Agent has been destroyed",
1120
- false
1121
- );
1122
- const errorEvent = this.errorClassifier.createEvent(error);
1123
- this.notifyHandlers(errorEvent);
1124
- throw new Error("[Agent] Agent has been destroyed");
1125
- }
1126
- if (this.state !== "idle") {
1127
- logger42.warn("Receive called while agent is busy", {
1128
- agentId: this.agentId,
1129
- currentState: this.state
1130
- });
1131
- const error = this.errorClassifier.create(
1132
- "system",
1133
- "AGENT_BUSY",
1134
- `Agent is busy (state: ${this.state}), please wait for current operation to complete`,
1135
- false
1136
- );
1137
- const errorEvent = this.errorClassifier.createEvent(error);
1138
- this.notifyHandlers(errorEvent);
1139
- throw new Error(`[Agent] Agent is busy (state: ${this.state})`);
1140
- }
1141
- const userMessage = typeof message === "string" ? {
1142
- id: `msg_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
1143
- role: "user",
1144
- subtype: "user",
1145
- content: message,
1146
- timestamp: Date.now()
1147
- } : message;
1148
- logger42.debug("Receiving message", {
1149
- agentId: this.agentId,
1150
- messageId: userMessage.id
1151
- });
1152
- const userMessageEvent = {
1153
- uuid: `evt_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
1154
- type: "user_message",
1155
- agentId: this.agentId,
1156
- timestamp: Date.now(),
1157
- data: userMessage
1158
- };
1159
- this.presentOutput(userMessageEvent);
1160
- this.notifyHandlers(userMessageEvent);
1161
- await this.executeMiddlewareChain(userMessage);
1162
- }
1163
- /**
1164
- * Execute middleware chain and then process the message
1165
- */
1166
- async executeMiddlewareChain(message) {
1167
- await this.middlewareChain.execute(message, (msg) => this.doReceive(msg));
1168
- }
1169
- /**
1170
- * Process a single stream event through the engine
1171
- *
1172
- * Used by:
1173
- * - doReceive() - normal message flow
1174
- * - AgentInterrupter - interrupt event injection
1175
- *
1176
- * @param streamEvent - Stream event to process
1177
- */
1178
- processStreamEvent(streamEvent) {
1179
- const outputs = this.engine.process(this.agentId, streamEvent);
1180
- for (const output of outputs) {
1181
- this.presentOutput(output);
1182
- }
1183
- for (const output of outputs) {
1184
- this.notifyHandlers(output);
1185
- }
1186
- }
1187
- /**
1188
- * Actual message processing logic
1189
- *
1190
- * Coordinates the flow:
1191
- * 1. Driver receives message → produces StreamEvents
1192
- * 2. Engine processes events → produces outputs
1193
- * 3. Presenters handle outputs
1194
- * 4. Handlers receive outputs
1195
- */
1196
- async doReceive(userMessage) {
1197
- try {
1198
- logger42.debug("Processing message through driver", {
1199
- agentId: this.agentId,
1200
- messageId: userMessage.id
1201
- });
1202
- const queuedEvent = {
1203
- type: "conversation_queued",
1204
- uuid: `${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
1205
- agentId: this.agentId,
1206
- timestamp: Date.now(),
1207
- data: {
1208
- userMessage
1209
- }
1210
- };
1211
- this.notifyHandlers(queuedEvent);
1212
- const streamEvents = this.driver.receive(userMessage);
1213
- for await (const streamEvent of streamEvents) {
1214
- this.processStreamEvent(streamEvent);
1215
- }
1216
- logger42.debug("Message processing completed", {
1217
- agentId: this.agentId,
1218
- messageId: userMessage.id
1219
- });
1220
- } catch (error) {
1221
- const agentError = this.errorClassifier.classify(error);
1222
- const errorEvent = this.errorClassifier.createEvent(agentError);
1223
- logger42.error("Message processing failed", {
1224
- agentId: this.agentId,
1225
- messageId: userMessage.id,
1226
- errorCategory: agentError.category,
1227
- errorCode: agentError.code,
1228
- error
1229
- });
1230
- this.notifyHandlers(errorEvent);
1231
- throw error;
1232
- }
1233
- }
1234
- /**
1235
- * Send output to all presenters
1236
- *
1237
- * Note: Presenters are no longer part of AgentDefinition.
1238
- * This is a placeholder for future presenter injection via Runtime or middleware.
1239
- */
1240
- presentOutput(_output) {
1241
- }
1242
- on(typeOrHandlerOrMap, handler) {
1243
- if (typeof typeOrHandlerOrMap === "function") {
1244
- return this.eventBus.onAny(typeOrHandlerOrMap);
1245
- }
1246
- if (this.isEventHandlerMap(typeOrHandlerOrMap)) {
1247
- const unsubscribes = [];
1248
- for (const [eventType, eventHandler] of Object.entries(typeOrHandlerOrMap)) {
1249
- if (eventHandler) {
1250
- unsubscribes.push(this.eventBus.on(eventType, eventHandler));
1251
- }
1252
- }
1253
- return () => {
1254
- for (const unsub of unsubscribes) {
1255
- unsub();
1256
- }
1257
- };
1258
- }
1259
- const types = Array.isArray(typeOrHandlerOrMap) ? typeOrHandlerOrMap : [typeOrHandlerOrMap];
1260
- const h = handler;
1261
- return this.eventBus.on(types, h);
1262
- }
1263
- /**
1264
- * Check if the argument is an EventHandlerMap (object with event type keys)
1265
- */
1266
- isEventHandlerMap(arg) {
1267
- if (typeof arg !== "object" || arg === null || Array.isArray(arg)) {
1268
- return false;
1269
- }
1270
- const keys = Object.keys(arg);
1271
- if (keys.length === 0) {
1272
- return false;
1273
- }
1274
- return keys.every((key) => {
1275
- const value = arg[key];
1276
- return value === void 0 || typeof value === "function";
1277
- });
1278
- }
1279
- /**
1280
- * Subscribe to state changes (delegated to StateMachine)
1281
- *
1282
- * @param handler - Callback receiving { prev, current } state change
1283
- * @returns Unsubscribe function
1284
- */
1285
- onStateChange(handler) {
1286
- return this.stateMachine.onStateChange(handler);
1287
- }
1288
- /**
1289
- * React-style fluent event subscription
1290
- *
1291
- * Converts onXxx handlers to event type keys and delegates to on(handlers)
1292
- */
1293
- react(handlers) {
1294
- const eventHandlerMap = mapReactHandlers(handlers);
1295
- return this.on(eventHandlerMap);
1296
- }
1297
- /**
1298
- * Subscribe to agent ready event
1299
- *
1300
- * If already running, handler is called immediately.
1301
- */
1302
- onReady(handler) {
1303
- if (this._lifecycle === "running") {
1304
- try {
1305
- handler();
1306
- } catch (error) {
1307
- logger42.error("onReady handler error", {
1308
- agentId: this.agentId,
1309
- error
1310
- });
1311
- }
1312
- }
1313
- this.readyHandlers.add(handler);
1314
- return () => {
1315
- this.readyHandlers.delete(handler);
1316
- };
1317
- }
1318
- /**
1319
- * Subscribe to agent destroy event
1320
- */
1321
- onDestroy(handler) {
1322
- this.destroyHandlers.add(handler);
1323
- return () => {
1324
- this.destroyHandlers.delete(handler);
1325
- };
1326
- }
1327
- /**
1328
- * Add middleware to intercept incoming messages
1329
- */
1330
- use(middleware) {
1331
- return this.middlewareChain.use(middleware);
1332
- }
1333
- /**
1334
- * Add interceptor to intercept outgoing events
1335
- */
1336
- intercept(interceptor) {
1337
- return this.interceptorChain.intercept(interceptor);
1338
- }
1339
- /**
1340
- * Interrupt - User-initiated stop
1341
- *
1342
- * Stops the current operation gracefully.
1343
- * Flow:
1344
- * 1. Call driver.interrupt() to abort active requests
1345
- * 2. Driver yields InterruptedStreamEvent
1346
- * 3. Event flows through engine pipeline
1347
- * 4. StateEventProcessor generates conversation_interrupted
1348
- * 5. StateMachine transitions to idle state
1349
- * 6. UI receives state change notification
1350
- */
1351
- interrupt() {
1352
- logger42.debug("User interrupt requested", { agentId: this.agentId, currentState: this.state });
1353
- this.driver.interrupt();
1354
- }
1355
- /**
1356
- * Destroy - Clean up resources
1357
- */
1358
- async destroy() {
1359
- logger42.debug("Destroying agent", { agentId: this.agentId });
1360
- for (const handler of this.destroyHandlers) {
1361
- try {
1362
- handler();
1363
- } catch (error) {
1364
- logger42.error("onDestroy handler error", {
1365
- agentId: this.agentId,
1366
- error
1367
- });
1368
- }
1369
- }
1370
- this._lifecycle = "destroyed";
1371
- this.stateMachine.reset();
1372
- this.eventBus.destroy();
1373
- this.readyHandlers.clear();
1374
- this.destroyHandlers.clear();
1375
- this.middlewareChain.clear();
1376
- this.interceptorChain.clear();
1377
- this.engine.clearState(this.agentId);
1378
- logger42.info("Agent destroyed", { agentId: this.agentId });
1379
- }
1380
- /**
1381
- * Notify all registered handlers
1382
- *
1383
- * Flow:
1384
- * 1. StateMachine processes StateEvents (for state transitions)
1385
- * 2. Interceptor chain can modify/filter events
1386
- * 3. EventBus emits to all subscribers
1387
- */
1388
- notifyHandlers(event) {
1389
- if (types.isStateEvent(event)) {
1390
- this.stateMachine.process(event);
1391
- }
1392
- this.executeInterceptorChain(event);
1393
- }
1394
- /**
1395
- * Execute interceptor chain and then emit to EventBus
1396
- */
1397
- executeInterceptorChain(event) {
1398
- this.interceptorChain.execute(event, (e) => this.eventBus.emit(e));
1399
- }
1400
- /**
1401
- * Get the event consumer for external subscriptions
1402
- *
1403
- * Use this to expose event subscription without emit capability.
1404
- */
1405
- getEventConsumer() {
1406
- return this.eventBus.asConsumer();
1407
- }
1408
- };
1409
- var MemoryStore = class {
1410
- constructor() {
1411
- __publicField(this, "states", /* @__PURE__ */ new Map());
1412
- }
1413
- get(id) {
1414
- return this.states.get(id);
1415
- }
1416
- set(id, state) {
1417
- this.states.set(id, state);
1418
- }
1419
- delete(id) {
1420
- this.states.delete(id);
1421
- }
1422
- has(id) {
1423
- return this.states.has(id);
1424
- }
1425
- /**
1426
- * Clear all stored states
1427
- */
1428
- clear() {
1429
- this.states.clear();
1430
- }
1431
- /**
1432
- * Get the number of stored states
1433
- */
1434
- get size() {
1435
- return this.states.size;
1436
- }
1437
- /**
1438
- * Get all stored IDs
1439
- */
1440
- keys() {
1441
- return this.states.keys();
1442
- }
1443
- };
1444
- common.createLogger("engine/Mealy");
1445
- function combineProcessors(processors) {
1446
- return (state, event) => {
1447
- const newState = {};
1448
- const allOutputs = [];
1449
- for (const key in processors) {
1450
- const processor = processors[key];
1451
- const subState = state[key];
1452
- const [newSubState, outputs] = processor(subState, event);
1453
- newState[key] = newSubState;
1454
- allOutputs.push(...outputs);
1455
- }
1456
- return [newState, allOutputs];
1457
- };
1458
- }
1459
- function combineInitialStates(initialStates) {
1460
- return () => {
1461
- const state = {};
1462
- for (const key in initialStates) {
1463
- state[key] = initialStates[key]();
1464
- }
1465
- return state;
1466
- };
1467
- }
1468
- function createInitialMessageAssemblerState() {
1469
- return {
1470
- currentMessageId: null,
1471
- messageStartTime: null,
1472
- pendingContents: {},
1473
- pendingToolCalls: {}
1474
- };
1475
- }
1476
- function generateId() {
1477
- return `msg_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
1478
- }
1479
- var messageAssemblerProcessor = (state, input) => {
1480
- switch (input.type) {
1481
- case "message_start":
1482
- return handleMessageStart(state, input);
1483
- case "text_delta":
1484
- return handleTextDelta(state, input);
1485
- case "tool_use_content_block_start":
1486
- return handleToolUseContentBlockStart(state, input);
1487
- case "input_json_delta":
1488
- return handleInputJsonDelta(state, input);
1489
- case "tool_use_content_block_stop":
1490
- return handleToolUseContentBlockStop(state, input);
1491
- case "tool_result":
1492
- return handleToolResult(state, input);
1493
- case "message_stop":
1494
- return handleMessageStop(state, input);
1495
- default:
1496
- return [state, []];
1497
- }
1498
- };
1499
- function handleMessageStart(state, event) {
1500
- return [
1501
- {
1502
- ...state,
1503
- currentMessageId: generateId(),
1504
- messageStartTime: event.timestamp,
1505
- pendingContents: {}
1506
- },
1507
- []
1508
- ];
1509
- }
1510
- function handleTextDelta(state, event) {
1511
- const index = 0;
1512
- const existingContent = state.pendingContents[index];
1513
- const pendingContent = existingContent?.type === "text" ? {
1514
- ...existingContent,
1515
- textDeltas: [...existingContent.textDeltas || [], event.data.text]
1516
- } : {
1517
- type: "text",
1518
- index,
1519
- textDeltas: [event.data.text]
1520
- };
1521
- return [
1522
- {
1523
- ...state,
1524
- pendingContents: {
1525
- ...state.pendingContents,
1526
- [index]: pendingContent
1527
- }
1528
- },
1529
- []
1530
- ];
1531
- }
1532
- function handleToolUseContentBlockStart(state, event) {
1533
- const index = 1;
1534
- const pendingContent = {
1535
- type: "tool_use",
1536
- index,
1537
- toolId: event.data.id,
1538
- toolName: event.data.name,
1539
- toolInputJson: ""
1540
- };
1541
- return [
1542
- {
1543
- ...state,
1544
- pendingContents: {
1545
- ...state.pendingContents,
1546
- [index]: pendingContent
1547
- }
1548
- },
1549
- []
1550
- ];
1551
- }
1552
- function handleInputJsonDelta(state, event) {
1553
- const index = 1;
1554
- const existingContent = state.pendingContents[index];
1555
- if (!existingContent || existingContent.type !== "tool_use") {
1556
- return [state, []];
1557
- }
1558
- const pendingContent = {
1559
- ...existingContent,
1560
- toolInputJson: (existingContent.toolInputJson || "") + event.data.partialJson
1561
- };
1562
- return [
1563
- {
1564
- ...state,
1565
- pendingContents: {
1566
- ...state.pendingContents,
1567
- [index]: pendingContent
1568
- }
1569
- },
1570
- []
1571
- ];
1572
- }
1573
- function handleToolUseContentBlockStop(state, event) {
1574
- const index = 1;
1575
- const pendingContent = state.pendingContents[index];
1576
- if (!pendingContent || pendingContent.type !== "tool_use") {
1577
- return [state, []];
1578
- }
1579
- let toolInput = {};
1580
- try {
1581
- toolInput = pendingContent.toolInputJson ? JSON.parse(pendingContent.toolInputJson) : {};
1582
- } catch {
1583
- toolInput = {};
1584
- }
1585
- const outputs = [];
1586
- const toolId = pendingContent.toolId;
1587
- const toolName = pendingContent.toolName;
1588
- const toolCallEvent = {
1589
- type: "tool_call",
1590
- uuid: generateId(),
1591
- agentId: event.agentId,
1592
- timestamp: Date.now(),
1593
- data: {
1594
- id: toolId,
1595
- name: toolName,
1596
- input: toolInput
1597
- }
1598
- };
1599
- outputs.push(toolCallEvent);
1600
- const toolCall = {
1601
- type: "tool-call",
1602
- id: toolId,
1603
- name: toolName,
1604
- input: toolInput
1605
- };
1606
- const toolCallMessage = {
1607
- id: generateId(),
1608
- role: "assistant",
1609
- subtype: "tool-call",
1610
- toolCall,
1611
- timestamp: Date.now()
1612
- };
1613
- const toolCallMessageEvent = {
1614
- type: "tool_call_message",
1615
- uuid: generateId(),
1616
- agentId: event.agentId,
1617
- timestamp: Date.now(),
1618
- data: toolCallMessage
1619
- };
1620
- outputs.push(toolCallMessageEvent);
1621
- const { [index]: _, ...remainingContents } = state.pendingContents;
1622
- return [
1623
- {
1624
- ...state,
1625
- pendingContents: remainingContents,
1626
- pendingToolCalls: {
1627
- ...state.pendingToolCalls,
1628
- [toolId]: { id: toolId, name: toolName }
1629
- }
1630
- },
1631
- outputs
1632
- ];
1633
- }
1634
- function handleToolResult(state, event) {
1635
- const { toolId, content, isError } = event.data;
1636
- const pendingToolCall = state.pendingToolCalls[toolId];
1637
- const toolName = pendingToolCall?.name || "unknown";
1638
- const toolResult = {
1639
- type: "tool-result",
1640
- id: toolId,
1641
- name: toolName,
1642
- output: {
1643
- type: isError ? "error-text" : "text",
1644
- value: typeof content === "string" ? content : JSON.stringify(content)
1645
- }
1646
- };
1647
- const toolResultMessage = {
1648
- id: generateId(),
1649
- role: "tool",
1650
- subtype: "tool-result",
1651
- toolResult,
1652
- toolCallId: toolId,
1653
- timestamp: Date.now()
1654
- };
1655
- const toolResultMessageEvent = {
1656
- type: "tool_result_message",
1657
- uuid: generateId(),
1658
- agentId: event.agentId,
1659
- timestamp: Date.now(),
1660
- data: toolResultMessage
1661
- };
1662
- const { [toolId]: _, ...remainingToolCalls } = state.pendingToolCalls;
1663
- return [
1664
- {
1665
- ...state,
1666
- pendingToolCalls: remainingToolCalls
1667
- },
1668
- [toolResultMessageEvent]
1669
- ];
1670
- }
1671
- function handleMessageStop(state, event) {
1672
- if (!state.currentMessageId) {
1673
- return [state, []];
1674
- }
1675
- const textParts = [];
1676
- const sortedContents = Object.values(state.pendingContents).sort((a, b) => a.index - b.index);
1677
- for (const pending of sortedContents) {
1678
- if (pending.type === "text" && pending.textDeltas) {
1679
- textParts.push(pending.textDeltas.join(""));
1680
- }
1681
- }
1682
- const content = textParts.join("");
1683
- const stopReason = event.data.stopReason;
1684
- if (!content || content.trim().length === 0) {
1685
- const shouldPreserveToolCalls2 = stopReason === "tool_use";
1686
- return [
1687
- {
1688
- ...createInitialMessageAssemblerState(),
1689
- pendingToolCalls: shouldPreserveToolCalls2 ? state.pendingToolCalls : {}
1690
- },
1691
- []
1692
- ];
1693
- }
1694
- const assistantMessage = {
1695
- id: state.currentMessageId,
1696
- role: "assistant",
1697
- subtype: "assistant",
1698
- content,
1699
- timestamp: state.messageStartTime || Date.now(),
1700
- // Usage data is not available in message_stop event
1701
- // It would need to be tracked separately if needed
1702
- usage: void 0
1703
- };
1704
- const assistantEvent = {
1705
- type: "assistant_message",
1706
- uuid: generateId(),
1707
- agentId: event.agentId,
1708
- timestamp: Date.now(),
1709
- data: assistantMessage
1710
- };
1711
- const shouldPreserveToolCalls = stopReason === "tool_use";
1712
- return [
1713
- {
1714
- ...createInitialMessageAssemblerState(),
1715
- pendingToolCalls: shouldPreserveToolCalls ? state.pendingToolCalls : {}
1716
- },
1717
- [assistantEvent]
1718
- ];
1719
- }
1720
- var logger23 = common.createLogger("engine/stateEventProcessor");
1721
- function createInitialStateEventProcessorContext() {
1722
- return {};
1723
- }
1724
- function generateId2() {
1725
- return `state_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
1726
- }
1727
- var stateEventProcessor = (context, input) => {
1728
- logger23.debug(`[Stream Event] ${input.type}`, {
1729
- context,
1730
- eventData: "data" in input ? input.data : void 0
1731
- });
1732
- switch (input.type) {
1733
- case "message_start":
1734
- return handleMessageStart2(context, input);
1735
- case "message_delta":
1736
- return handleMessageDelta(context);
1737
- case "message_stop":
1738
- return handleMessageStop2(context, input);
1739
- case "text_content_block_start":
1740
- return handleTextContentBlockStart(context, input);
1741
- case "tool_use_content_block_start":
1742
- return handleToolUseContentBlockStart2(context, input);
1743
- case "tool_use_content_block_stop":
1744
- return handleToolUseContentBlockStop2(context);
1745
- case "tool_call":
1746
- return handleToolCall(context);
1747
- case "interrupted":
1748
- return handleInterrupted(context, input);
1749
- default:
1750
- logger23.debug(`[Stream Event] ${input.type} (unhandled)`);
1751
- return [context, []];
1752
- }
1753
- };
1754
- function handleMessageStart2(context, event) {
1755
- const conversationStartEvent = {
1756
- type: "conversation_start",
1757
- uuid: generateId2(),
1758
- agentId: event.agentId,
1759
- timestamp: event.timestamp,
1760
- transition: {
1761
- reason: "conversation_started",
1762
- trigger: "message_start"
1763
- },
1764
- data: {
1765
- userMessage: {}
1766
- // Will be populated by higher-level component
1767
- }
1768
- };
1769
- return [context, [conversationStartEvent]];
1770
- }
1771
- function handleMessageDelta(context, _event) {
1772
- return [context, []];
1773
- }
1774
- function handleMessageStop2(context, event) {
1775
- const stopReason = event.data.stopReason;
1776
- logger23.debug("message_stop received", { stopReason });
1777
- if (stopReason === "tool_use") {
1778
- logger23.debug("Skipping conversation_end (tool_use in progress)");
1779
- return [context, []];
1780
- }
1781
- const conversationEndEvent = {
1782
- type: "conversation_end",
1783
- uuid: generateId2(),
1784
- agentId: event.agentId,
1785
- timestamp: event.timestamp,
1786
- transition: {
1787
- reason: "conversation_completed",
1788
- trigger: "message_stop"
1789
- },
1790
- data: {
1791
- assistantMessage: {},
1792
- // Will be populated by higher-level component
1793
- durationMs: 0,
1794
- // Will be calculated by StateMachine or TurnTracker
1795
- durationApiMs: 0,
1796
- numTurns: 0,
1797
- result: "completed",
1798
- totalCostUsd: 0,
1799
- usage: {
1800
- input: 0,
1801
- output: 0
1802
- }
1803
- }
1804
- };
1805
- return [context, [conversationEndEvent]];
1806
- }
1807
- function handleTextContentBlockStart(context, event) {
1808
- const respondingEvent = {
1809
- type: "conversation_responding",
1810
- uuid: generateId2(),
1811
- agentId: event.agentId,
1812
- timestamp: Date.now(),
1813
- transition: {
1814
- reason: "assistant_responding",
1815
- trigger: "text_content_block_start"
1816
- },
1817
- data: {}
1818
- };
1819
- return [context, [respondingEvent]];
1820
- }
1821
- function handleToolUseContentBlockStart2(context, event) {
1822
- const outputs = [];
1823
- const toolPlannedEvent = {
1824
- type: "tool_planned",
1825
- uuid: generateId2(),
1826
- agentId: event.agentId,
1827
- timestamp: event.timestamp,
1828
- data: {
1829
- id: event.data.id,
1830
- name: event.data.name,
1831
- input: {}
1832
- }
1833
- };
1834
- outputs.push(toolPlannedEvent);
1835
- const toolExecutingEvent = {
1836
- type: "tool_executing",
1837
- uuid: generateId2(),
1838
- agentId: event.agentId,
1839
- timestamp: event.timestamp,
1840
- transition: {
1841
- reason: "tool_planning_started",
1842
- trigger: "tool_use_content_block_start"
1843
- },
1844
- data: {}
1845
- };
1846
- outputs.push(toolExecutingEvent);
1847
- return [context, outputs];
1848
- }
1849
- function handleToolUseContentBlockStop2(context, _event) {
1850
- return [context, []];
1851
- }
1852
- function handleToolCall(context, _event) {
1853
- return [context, []];
1854
- }
1855
- function handleInterrupted(context, event) {
1856
- logger23.debug("interrupted event received", { reason: event.data.reason });
1857
- const conversationInterruptedEvent = {
1858
- type: "conversation_interrupted",
1859
- uuid: generateId2(),
1860
- agentId: event.agentId,
1861
- timestamp: event.timestamp,
1862
- transition: {
1863
- reason: event.data.reason,
1864
- trigger: "interrupted"
1865
- },
1866
- data: {
1867
- reason: event.data.reason
1868
- }
1869
- };
1870
- return [context, [conversationInterruptedEvent]];
1871
- }
1872
- function createInitialTurnTrackerState() {
1873
- return {
1874
- pendingTurn: null,
1875
- costPerInputToken: 3e-6,
1876
- // $3 per 1M tokens
1877
- costPerOutputToken: 15e-6
1878
- // $15 per 1M tokens
1879
- };
1880
- }
1881
- function generateId3() {
1882
- return `turn_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
1883
- }
1884
- function calculateCost(usage, costPerInputToken, costPerOutputToken) {
1885
- const inputCost = usage.input * costPerInputToken;
1886
- const outputCost = usage.output * costPerOutputToken;
1887
- return inputCost + outputCost;
1888
- }
1889
- var turnTrackerProcessor = (state, input) => {
1890
- switch (input.type) {
1891
- case "user_message":
1892
- return handleUserMessage(state, input);
1893
- case "message_stop":
1894
- return handleMessageStop3(state, input);
1895
- case "assistant_message":
1896
- return [state, []];
1897
- default:
1898
- return [state, []];
1899
- }
1900
- };
1901
- function handleUserMessage(state, event) {
1902
- const turnId = generateId3();
1903
- const pendingTurn = {
1904
- turnId,
1905
- userMessage: event.data,
1906
- requestedAt: event.timestamp
1907
- };
1908
- const turnRequestEvent = {
1909
- type: "turn_request",
1910
- uuid: generateId3(),
1911
- agentId: event.agentId,
1912
- timestamp: Date.now(),
1913
- turnId,
1914
- data: {
1915
- userMessage: event.data,
1916
- requestedAt: event.timestamp
1917
- }
1918
- };
1919
- return [
1920
- {
1921
- ...state,
1922
- pendingTurn
1923
- },
1924
- [turnRequestEvent]
1925
- ];
1926
- }
1927
- function handleMessageStop3(state, event) {
1928
- if (!state.pendingTurn) {
1929
- return [state, []];
1930
- }
1931
- const stopReason = event.data.stopReason;
1932
- if (stopReason === "end_turn" || stopReason === "max_tokens" || stopReason === "stop_sequence") {
1933
- return completeTurn(state, event.agentId, event.timestamp);
1934
- }
1935
- return [state, []];
1936
- }
1937
- function completeTurn(state, agentId, completedAt) {
1938
- if (!state.pendingTurn) {
1939
- return [state, []];
1940
- }
1941
- const { turnId, requestedAt } = state.pendingTurn;
1942
- const duration = completedAt - requestedAt;
1943
- const usage = { input: 0, output: 0 };
1944
- const cost = calculateCost(usage, state.costPerInputToken, state.costPerOutputToken);
1945
- const turnResponseEvent = {
1946
- type: "turn_response",
1947
- uuid: generateId3(),
1948
- agentId,
1949
- timestamp: Date.now(),
1950
- turnId,
1951
- data: {
1952
- assistantMessage: {
1953
- id: generateId3(),
1954
- role: "assistant",
1955
- subtype: "assistant",
1956
- content: "",
1957
- timestamp: completedAt
1958
- },
1959
- respondedAt: completedAt,
1960
- durationMs: duration,
1961
- usage,
1962
- costUsd: cost
1963
- }
1964
- };
1965
- return [
1966
- {
1967
- ...state,
1968
- pendingTurn: null
1969
- },
1970
- [turnResponseEvent]
1971
- ];
1972
- }
1973
- var agentProcessor = combineProcessors({
1974
- messageAssembler: messageAssemblerProcessor,
1975
- stateEventProcessor,
1976
- turnTracker: turnTrackerProcessor
1977
- });
1978
- var createInitialAgentEngineState = combineInitialStates({
1979
- messageAssembler: createInitialMessageAssemblerState,
1980
- stateEventProcessor: createInitialStateEventProcessorContext,
1981
- turnTracker: createInitialTurnTrackerState
1982
- });
1983
- var logger33 = common.createLogger("engine/AgentEngine");
1984
- var AgentEngine = class {
1985
- constructor() {
1986
- __publicField(this, "store");
1987
- this.store = new MemoryStore();
1988
- logger33.debug("AgentEngine initialized");
1989
- }
1990
- /**
1991
- * Process a single stream event and return output events
1992
- *
1993
- * This is the core Mealy Machine operation:
1994
- * process(agentId, event) → outputs[]
1995
- *
1996
- * @param agentId - The agent identifier (for state isolation)
1997
- * @param event - Stream event to process
1998
- * @returns Array of output events (state, message, turn events)
1999
- */
2000
- process(agentId, event) {
2001
- const eventType = event.type || "unknown";
2002
- logger33.debug("Processing event", { agentId, eventType });
2003
- const isNewState = !this.store.has(agentId);
2004
- let state = this.store.get(agentId) ?? createInitialAgentEngineState();
2005
- if (isNewState) {
2006
- logger33.debug("Created initial state for agent", { agentId });
2007
- }
2008
- const allOutputs = [];
2009
- allOutputs.push(event);
2010
- const [newState, outputs] = agentProcessor(state, event);
2011
- state = newState;
2012
- for (const output of outputs) {
2013
- allOutputs.push(output);
2014
- const [chainedState, chainedOutputs] = this.processChained(state, output);
2015
- state = chainedState;
2016
- allOutputs.push(...chainedOutputs);
2017
- }
2018
- this.store.set(agentId, state);
2019
- if (outputs.length > 0) {
2020
- logger33.debug("Produced outputs", {
2021
- agentId,
2022
- inputEvent: eventType,
2023
- outputCount: allOutputs.length,
2024
- processorOutputs: outputs.length
2025
- });
2026
- }
2027
- return allOutputs;
2028
- }
2029
- /**
2030
- * Process chained events recursively
2031
- *
2032
- * Some processors produce events that trigger other processors:
2033
- * - MessageAssembler produces MessageEvents
2034
- * - TurnTracker consumes MessageEvents to produce TurnEvents
2035
- */
2036
- processChained(state, event) {
2037
- const [newState, outputs] = agentProcessor(state, event);
2038
- if (outputs.length === 0) {
2039
- return [newState, []];
2040
- }
2041
- const allOutputs = [...outputs];
2042
- let currentState = newState;
2043
- for (const output of outputs) {
2044
- const [chainedState, chainedOutputs] = this.processChained(currentState, output);
2045
- currentState = chainedState;
2046
- allOutputs.push(...chainedOutputs);
2047
- }
2048
- return [currentState, allOutputs];
2049
- }
2050
- /**
2051
- * Clear state for an agent
2052
- *
2053
- * Call this when an agent is destroyed to free memory.
2054
- */
2055
- clearState(agentId) {
2056
- logger33.debug("Clearing state", { agentId });
2057
- this.store.delete(agentId);
2058
- }
2059
- /**
2060
- * Check if state exists for an agent
2061
- */
2062
- hasState(agentId) {
2063
- return this.store.has(agentId);
2064
- }
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __esm = (fn, res) => function __init() {
6
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
2065
7
  };
2066
- var logger7 = common.createLogger("agentx/ContainerManager");
2067
- function generateContainerId() {
2068
- const timestamp = Date.now().toString(36);
2069
- const random = Math.random().toString(36).substring(2, 8);
2070
- return `container_${timestamp}_${random}`;
2071
- }
2072
- function generateAgentId() {
2073
- const timestamp = Date.now().toString(36);
2074
- const random = Math.random().toString(36).substring(2, 8);
2075
- return `agent_${timestamp}_${random}`;
2076
- }
2077
- var ContainerManagerImpl = class {
2078
- constructor(runtime, repository) {
2079
- __publicField(this, "agents", /* @__PURE__ */ new Map());
2080
- __publicField(this, "engine");
2081
- __publicField(this, "runtime");
2082
- __publicField(this, "repository");
2083
- this.runtime = runtime;
2084
- this.repository = repository;
2085
- this.engine = new AgentEngine();
2086
- }
2087
- // ==================== Container Lifecycle ====================
2088
- async create(config) {
2089
- const containerId = generateContainerId();
2090
- const now = Date.now();
2091
- const record = {
2092
- containerId,
2093
- createdAt: now,
2094
- updatedAt: now,
2095
- config
2096
- };
2097
- await this.repository.saveContainer(record);
2098
- logger7.info("Container created", { containerId });
2099
- return record;
2100
- }
2101
- async get(containerId) {
2102
- return this.repository.findContainerById(containerId);
2103
- }
2104
- async list() {
2105
- return this.repository.findAllContainers();
2106
- }
2107
- async delete(containerId) {
2108
- const exists = await this.repository.containerExists(containerId);
2109
- if (!exists) {
2110
- return false;
2111
- }
2112
- await this.repository.deleteContainer(containerId);
2113
- logger7.info("Container deleted", { containerId });
2114
- return true;
2115
- }
2116
- async exists(containerId) {
2117
- return this.repository.containerExists(containerId);
2118
- }
2119
- // ==================== Agent Runtime ====================
2120
- async run(image, containerId) {
2121
- logger7.info("Running agent from image", {
2122
- imageId: image.imageId,
2123
- containerId
2124
- });
2125
- const container = await this.repository.findContainerById(containerId);
2126
- if (!container) {
2127
- throw new Error(`Container not found: ${containerId}`);
2128
- }
2129
- let agentId;
2130
- if (this.runtime.agentIdResolver) {
2131
- agentId = await this.runtime.agentIdResolver.resolveForRun(image.imageId, containerId);
2132
- } else {
2133
- agentId = generateAgentId();
2134
- }
2135
- const context = {
2136
- agentId,
2137
- createdAt: Date.now()
2138
- };
2139
- const sandbox = this.runtime.createSandbox(containerId);
2140
- const driver = this.runtime.createDriver(image.definition, context, sandbox);
2141
- const agent = new AgentInstance(image.definition, context, this.engine, driver, sandbox);
2142
- this.agents.set(agentId, agent);
2143
- logger7.info("Agent started", {
2144
- agentId,
2145
- imageId: image.imageId,
2146
- containerId,
2147
- definitionName: image.definition.name
2148
- });
2149
- return agent;
2150
- }
2151
- async resume(session, containerId) {
2152
- logger7.info("Resuming agent from session", {
2153
- sessionId: session.sessionId,
2154
- imageId: session.imageId,
2155
- containerId
2156
- });
2157
- const container = await this.repository.findContainerById(containerId);
2158
- if (!container) {
2159
- throw new Error(`Container not found: ${containerId}`);
2160
- }
2161
- const imageRecord = await this.repository.findImageById(session.imageId);
2162
- if (!imageRecord) {
2163
- throw new Error(`Image not found: ${session.imageId}`);
2164
- }
2165
- let agentId;
2166
- if (this.runtime.agentIdResolver) {
2167
- agentId = await this.runtime.agentIdResolver.resolveForResume(session.sessionId, containerId);
2168
- } else {
2169
- agentId = generateAgentId();
2170
- }
2171
- const context = {
2172
- agentId,
2173
- createdAt: Date.now()
2174
- };
2175
- const sandbox = this.runtime.createSandbox(containerId);
2176
- const definition = imageRecord.definition;
2177
- const driver = this.runtime.createDriver(definition, context, sandbox);
2178
- const agent = new AgentInstance(definition, context, this.engine, driver, sandbox);
2179
- this.agents.set(agentId, agent);
2180
- logger7.info("Agent resumed", {
2181
- agentId,
2182
- sessionId: session.sessionId,
2183
- imageId: session.imageId,
2184
- containerId
2185
- });
2186
- return agent;
2187
- }
2188
- async destroyAgent(agentId) {
2189
- const agent = this.agents.get(agentId);
2190
- if (!agent) {
2191
- logger7.warn("Agent not found for destroy", { agentId });
2192
- return;
2193
- }
2194
- logger7.debug("Destroying agent", { agentId });
2195
- await agent.destroy();
2196
- this.agents.delete(agentId);
2197
- logger7.info("Agent destroyed", { agentId });
2198
- }
2199
- getAgent(agentId) {
2200
- return this.agents.get(agentId);
2201
- }
2202
- hasAgent(agentId) {
2203
- return this.agents.has(agentId);
2204
- }
2205
- listAgents() {
2206
- return Array.from(this.agents.values());
2207
- }
2208
- async destroyAllAgents() {
2209
- const agentIds = Array.from(this.agents.keys());
2210
- logger7.debug("Destroying all agents", { count: agentIds.length });
2211
- await Promise.all(agentIds.map((id) => this.destroyAgent(id)));
2212
- logger7.info("All agents destroyed", { count: agentIds.length });
2213
- }
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
2214
11
  };
2215
12
 
2216
- // src/AgentX.ts
2217
- var logger8 = common.createLogger("agentx/AgentX");
2218
- function createAgentX(runtime, options) {
2219
- logger8.info("Creating AgentX instance", { runtime: runtime.name });
2220
- if (!runtime.repository) {
2221
- throw new Error("Runtime must have a repository for persistence");
2222
- }
2223
- const repository = runtime.repository;
2224
- const containerManager = new ContainerManagerImpl(runtime, repository);
2225
- const errorManager = new ErrorManager();
2226
- const definitionManager = new DefinitionManagerImpl(repository);
2227
- const agentManager = new AgentManager(containerManager);
2228
- const imageManager = new ImageManagerImpl(repository, containerManager, options?.containerId);
2229
- const sessionManager = new SessionManagerImpl(repository, containerManager, options?.containerId);
2230
- logger8.debug("AgentX instance created", { runtime: runtime.name });
2231
- return {
2232
- mode: "local",
2233
- containers: containerManager,
2234
- definitions: definitionManager,
2235
- images: imageManager,
2236
- agents: agentManager,
2237
- sessions: sessionManager,
2238
- errors: errorManager
2239
- };
2240
- }
2241
- var PersistentSSEConnection = class {
2242
- constructor(serverUrl, agentId, sseParams = {}) {
2243
- this.serverUrl = serverUrl;
2244
- this.agentId = agentId;
2245
- this.sseParams = sseParams;
2246
- __publicField(this, "eventSource", null);
2247
- __publicField(this, "messageQueue", []);
2248
- __publicField(this, "activeIterators", /* @__PURE__ */ new Set());
2249
- __publicField(this, "isDone", false);
2250
- }
2251
- /**
2252
- * Initialize SSE connection
2253
- */
2254
- connect() {
2255
- if (this.eventSource) {
2256
- return;
2257
- }
2258
- let sseUrl = `${this.serverUrl}/agents/${this.agentId}/sse`;
2259
- if (Object.keys(this.sseParams).length > 0) {
2260
- const params = new URLSearchParams(this.sseParams);
2261
- sseUrl += `?${params.toString()}`;
2262
- }
2263
- this.eventSource = new EventSource(sseUrl);
2264
- const handleEvent = (event) => {
2265
- try {
2266
- const data = JSON.parse(event.data);
2267
- if (this.activeIterators.size > 0) {
2268
- const iterator = this.activeIterators.values().next().value;
2269
- if (iterator) {
2270
- this.activeIterators.delete(iterator);
2271
- iterator.resolve({ value: data, done: false });
13
+ // ../common/dist/index.js
14
+ var dist_exports = {};
15
+ __export(dist_exports, {
16
+ ConsoleLogger: () => exports.ConsoleLogger,
17
+ LoggerFactoryImpl: () => exports.LoggerFactoryImpl,
18
+ createLogger: () => createLogger,
19
+ setLoggerFactory: () => setLoggerFactory
20
+ });
21
+ function setLoggerFactory(factory) {
22
+ externalFactory = factory;
23
+ exports.LoggerFactoryImpl.reset();
24
+ externalFactory = factory;
25
+ }
26
+ function createLogger(name) {
27
+ return exports.LoggerFactoryImpl.getLogger(name);
28
+ }
29
+ var __defProp2, __defNormalProp, __publicField, _ConsoleLogger; exports.ConsoleLogger = void 0; var externalFactory; exports.LoggerFactoryImpl = void 0;
30
+ var init_dist = __esm({
31
+ "../common/dist/index.js"() {
32
+ __defProp2 = Object.defineProperty;
33
+ __defNormalProp = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
34
+ __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
35
+ _ConsoleLogger = class _ConsoleLogger2 {
36
+ constructor(name, options = {}) {
37
+ __publicField(this, "name");
38
+ __publicField(this, "level");
39
+ __publicField(this, "colors");
40
+ __publicField(this, "timestamps");
41
+ this.name = name;
42
+ this.level = options.level ?? "info";
43
+ this.colors = options.colors ?? this.isNodeEnvironment();
44
+ this.timestamps = options.timestamps ?? true;
45
+ }
46
+ debug(message, context) {
47
+ if (this.isDebugEnabled()) {
48
+ this.log("DEBUG", message, context);
49
+ }
50
+ }
51
+ info(message, context) {
52
+ if (this.isInfoEnabled()) {
53
+ this.log("INFO", message, context);
54
+ }
55
+ }
56
+ warn(message, context) {
57
+ if (this.isWarnEnabled()) {
58
+ this.log("WARN", message, context);
59
+ }
60
+ }
61
+ error(message, context) {
62
+ if (this.isErrorEnabled()) {
63
+ if (message instanceof Error) {
64
+ this.log("ERROR", message.message, { ...context, stack: message.stack });
65
+ } else {
66
+ this.log("ERROR", message, context);
2272
67
  }
68
+ }
69
+ }
70
+ isDebugEnabled() {
71
+ return this.getLevelValue(this.level) <= this.getLevelValue("debug");
72
+ }
73
+ isInfoEnabled() {
74
+ return this.getLevelValue(this.level) <= this.getLevelValue("info");
75
+ }
76
+ isWarnEnabled() {
77
+ return this.getLevelValue(this.level) <= this.getLevelValue("warn");
78
+ }
79
+ isErrorEnabled() {
80
+ return this.getLevelValue(this.level) <= this.getLevelValue("error");
81
+ }
82
+ getLevelValue(level) {
83
+ const levels = {
84
+ debug: 0,
85
+ info: 1,
86
+ warn: 2,
87
+ error: 3,
88
+ silent: 4
89
+ };
90
+ return levels[level];
91
+ }
92
+ log(level, message, context) {
93
+ const parts = [];
94
+ if (this.timestamps) {
95
+ parts.push((/* @__PURE__ */ new Date()).toISOString());
96
+ }
97
+ if (this.colors) {
98
+ const color = _ConsoleLogger2.COLORS[level];
99
+ parts.push(`${color}${level.padEnd(5)}${_ConsoleLogger2.COLORS.RESET}`);
2273
100
  } else {
2274
- this.messageQueue.push(data);
101
+ parts.push(level.padEnd(5));
102
+ }
103
+ parts.push(`[${this.name}]`);
104
+ parts.push(message);
105
+ const logLine = parts.join(" ");
106
+ const consoleMethod = this.getConsoleMethod(level);
107
+ if (context && Object.keys(context).length > 0) {
108
+ consoleMethod(logLine, context);
109
+ } else {
110
+ consoleMethod(logLine);
2275
111
  }
2276
- } catch {
2277
112
  }
2278
- };
2279
- const handleError = () => {
2280
- this.isDone = true;
2281
- this.eventSource?.close();
2282
- this.eventSource = null;
2283
- for (const iterator of this.activeIterators) {
2284
- iterator.reject(new Error("SSE connection error"));
113
+ getConsoleMethod(level) {
114
+ switch (level) {
115
+ case "DEBUG":
116
+ return console.debug.bind(console);
117
+ case "INFO":
118
+ return console.info.bind(console);
119
+ case "WARN":
120
+ return console.warn.bind(console);
121
+ case "ERROR":
122
+ return console.error.bind(console);
123
+ default:
124
+ return console.log.bind(console);
125
+ }
126
+ }
127
+ isNodeEnvironment() {
128
+ return typeof process !== "undefined" && process.versions?.node !== void 0;
2285
129
  }
2286
- this.activeIterators.clear();
2287
130
  };
2288
- for (const eventType of types.STREAM_EVENT_TYPE_NAMES) {
2289
- this.eventSource.addEventListener(eventType, handleEvent);
2290
- }
2291
- this.eventSource.addEventListener("error", handleEvent);
2292
- this.eventSource.onmessage = handleEvent;
2293
- this.eventSource.onerror = handleError;
2294
- }
2295
- /**
2296
- * Create an async iterable for a single receive() call
2297
- *
2298
- * This iterator continues until a final message_stop is received (stopReason !== "tool_use").
2299
- * For tool calls, this means it will span multiple message_start/message_stop cycles.
2300
- * The SSE connection itself remains open for future receive() calls.
2301
- */
2302
- createIterator() {
2303
- const connection = this;
2304
- return {
2305
- [Symbol.asyncIterator]() {
2306
- let turnComplete = false;
2307
- return {
2308
- async next() {
2309
- if (connection.messageQueue.length > 0) {
2310
- const event = connection.messageQueue.shift();
2311
- if (event.type === "message_stop") {
2312
- const stopReason = event.data.stopReason;
2313
- if (stopReason !== "tool_use") {
2314
- turnComplete = true;
2315
- }
2316
- }
2317
- return { value: event, done: false };
2318
- }
2319
- if (turnComplete) {
2320
- return { done: true, value: void 0 };
2321
- }
2322
- if (connection.isDone) {
2323
- return { done: true, value: void 0 };
2324
- }
2325
- return new Promise((resolve, reject) => {
2326
- const wrappedResolve = (result) => {
2327
- if (!result.done) {
2328
- if (result.value.type === "message_stop") {
2329
- const stopReason = result.value.data.stopReason;
2330
- if (stopReason !== "tool_use") {
2331
- turnComplete = true;
2332
- }
2333
- }
2334
- }
2335
- resolve(result);
2336
- };
2337
- const iterator = { resolve: wrappedResolve, reject };
2338
- connection.activeIterators.add(iterator);
2339
- });
2340
- },
2341
- async return() {
2342
- return { done: true, value: void 0 };
131
+ __publicField(_ConsoleLogger, "COLORS", {
132
+ DEBUG: "\x1B[36m",
133
+ INFO: "\x1B[32m",
134
+ WARN: "\x1B[33m",
135
+ ERROR: "\x1B[31m",
136
+ RESET: "\x1B[0m"
137
+ });
138
+ exports.ConsoleLogger = _ConsoleLogger;
139
+ externalFactory = null;
140
+ exports.LoggerFactoryImpl = class {
141
+ static getLogger(nameOrClass) {
142
+ const name = typeof nameOrClass === "string" ? nameOrClass : nameOrClass.name;
143
+ if (this.loggers.has(name)) {
144
+ return this.loggers.get(name);
145
+ }
146
+ const lazyLogger = this.createLazyLogger(name);
147
+ this.loggers.set(name, lazyLogger);
148
+ return lazyLogger;
149
+ }
150
+ static configure(config) {
151
+ this.config = { ...this.config, ...config };
152
+ }
153
+ static reset() {
154
+ this.loggers.clear();
155
+ this.config = { defaultLevel: "info" };
156
+ externalFactory = null;
157
+ }
158
+ static createLazyLogger(name) {
159
+ let realLogger = null;
160
+ const getRealLogger = () => {
161
+ if (!realLogger) {
162
+ realLogger = this.createLogger(name);
2343
163
  }
164
+ return realLogger;
165
+ };
166
+ return {
167
+ name,
168
+ level: this.config.defaultLevel || "info",
169
+ debug: (message, context) => getRealLogger().debug(message, context),
170
+ info: (message, context) => getRealLogger().info(message, context),
171
+ warn: (message, context) => getRealLogger().warn(message, context),
172
+ error: (message, context) => getRealLogger().error(message, context),
173
+ isDebugEnabled: () => getRealLogger().isDebugEnabled(),
174
+ isInfoEnabled: () => getRealLogger().isInfoEnabled(),
175
+ isWarnEnabled: () => getRealLogger().isWarnEnabled(),
176
+ isErrorEnabled: () => getRealLogger().isErrorEnabled()
2344
177
  };
2345
178
  }
179
+ static createLogger(name) {
180
+ if (externalFactory) {
181
+ return externalFactory.getLogger(name);
182
+ }
183
+ if (this.config.defaultImplementation) {
184
+ return this.config.defaultImplementation(name);
185
+ }
186
+ return new exports.ConsoleLogger(name, {
187
+ level: this.config.defaultLevel,
188
+ ...this.config.consoleOptions
189
+ });
190
+ }
2346
191
  };
192
+ __publicField(exports.LoggerFactoryImpl, "loggers", /* @__PURE__ */ new Map());
193
+ __publicField(exports.LoggerFactoryImpl, "config", {
194
+ defaultLevel: "info"
195
+ });
2347
196
  }
2348
- /**
2349
- * Close the connection
2350
- */
2351
- close() {
2352
- this.isDone = true;
2353
- if (this.eventSource) {
2354
- this.eventSource.close();
2355
- this.eventSource = null;
197
+ });
198
+
199
+ // src/createLocalAgentX.ts
200
+ var createLocalAgentX_exports = {};
201
+ __export(createLocalAgentX_exports, {
202
+ createLocalAgentX: () => createLocalAgentX
203
+ });
204
+ function setupConnectionHandler(ws, connections, runtime) {
205
+ connections.add(ws);
206
+ logger.info("Client connected", { totalConnections: connections.size });
207
+ ws.on("message", (data) => {
208
+ try {
209
+ const event = JSON.parse(data.toString());
210
+ logger.info("Received from client", {
211
+ type: event.type,
212
+ requestId: event.data?.requestId
213
+ });
214
+ runtime.emit(event);
215
+ } catch {
216
+ }
217
+ });
218
+ ws.on("close", () => {
219
+ connections.delete(ws);
220
+ logger.info("Client disconnected", { totalConnections: connections.size });
221
+ });
222
+ }
223
+ function setupBroadcasting(connections, runtime) {
224
+ runtime.onAny((event) => {
225
+ if (event.broadcastable === false) {
226
+ return;
227
+ }
228
+ logger.info("Broadcasting to clients", {
229
+ type: event.type,
230
+ category: event.category,
231
+ requestId: event.data?.requestId
232
+ });
233
+ const message = JSON.stringify(event);
234
+ for (const ws of connections) {
235
+ if (ws.readyState === 1) {
236
+ ws.send(message);
237
+ }
2356
238
  }
2357
- for (const iterator of this.activeIterators) {
2358
- iterator.reject(new Error("Connection closed"));
239
+ });
240
+ }
241
+ async function createLocalAgentX(config) {
242
+ if (config.logger) {
243
+ const { LoggerFactoryImpl: LoggerFactoryImpl2, setLoggerFactory: setLoggerFactory2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
244
+ LoggerFactoryImpl2.configure({
245
+ defaultLevel: config.logger.level,
246
+ consoleOptions: config.logger.console
247
+ });
248
+ if (config.logger.factory) {
249
+ setLoggerFactory2(config.logger.factory);
250
+ }
251
+ }
252
+ const { createRuntime, createPersistence } = await import('@agentxjs/runtime');
253
+ const storageConfig = config.storage ?? {};
254
+ const persistence = await createPersistence(
255
+ storageConfig
256
+ );
257
+ const runtime = createRuntime({
258
+ persistence,
259
+ llmProvider: {
260
+ name: "claude",
261
+ provide: () => ({
262
+ apiKey: config.llm?.apiKey ?? "",
263
+ baseUrl: config.llm?.baseUrl,
264
+ model: config.llm?.model
265
+ })
2359
266
  }
2360
- this.activeIterators.clear();
2361
- this.messageQueue = [];
267
+ });
268
+ let peer = null;
269
+ const connections = /* @__PURE__ */ new Set();
270
+ let attachedToServer = false;
271
+ if (config.server) {
272
+ const { WebSocketServer } = await import('ws');
273
+ peer = new WebSocketServer({ noServer: true });
274
+ config.server.on("upgrade", (request, socket, head) => {
275
+ const url = new URL(request.url || "", `http://${request.headers.host}`);
276
+ if (url.pathname === "/ws") {
277
+ peer.handleUpgrade(request, socket, head, (ws) => {
278
+ peer.emit("connection", ws, request);
279
+ });
280
+ } else {
281
+ socket.destroy();
282
+ }
283
+ });
284
+ peer.on("connection", (ws) => {
285
+ setupConnectionHandler(ws, connections, runtime);
286
+ });
287
+ setupBroadcasting(connections, runtime);
288
+ attachedToServer = true;
289
+ logger.info("WebSocket attached to existing HTTP server on /ws path");
2362
290
  }
2363
- };
2364
- function createSSEDriver(config) {
2365
- const { serverUrl, agentId, headers = {}, sseParams = {} } = config;
2366
- let connection = null;
2367
291
  return {
2368
- name: "SSEDriver",
2369
- async *receive(message) {
2370
- if (!connection) {
2371
- connection = new PersistentSSEConnection(serverUrl, agentId, sseParams);
2372
- connection.connect();
292
+ // Core API - delegate to runtime
293
+ request: (type, data, timeout) => runtime.request(type, data, timeout),
294
+ on: (type, handler) => runtime.on(type, handler),
295
+ onCommand: (type, handler) => runtime.onCommand(type, handler),
296
+ emitCommand: (type, data) => runtime.emitCommand(type, data),
297
+ // Server API
298
+ async listen(port, host) {
299
+ if (attachedToServer) {
300
+ throw new Error(
301
+ "Cannot listen when attached to existing server. The server should call listen() instead."
302
+ );
2373
303
  }
2374
- const messageUrl = `${serverUrl}/agents/${agentId}/messages`;
2375
- const response = await fetch(messageUrl, {
2376
- method: "POST",
2377
- headers: {
2378
- "Content-Type": "application/json",
2379
- ...headers
2380
- },
2381
- body: JSON.stringify({
2382
- content: typeof message.content === "string" ? message.content : message.content
2383
- })
304
+ if (peer) {
305
+ throw new Error("Server already listening");
306
+ }
307
+ const { WebSocketServer } = await import('ws');
308
+ peer = new WebSocketServer({ port, host: host ?? "0.0.0.0" });
309
+ peer.on("connection", (ws) => {
310
+ setupConnectionHandler(ws, connections, runtime);
2384
311
  });
2385
- if (!response.ok) {
2386
- const errorBody = await response.json().catch(() => ({}));
2387
- throw new Error(errorBody.error?.message || `HTTP ${response.status}`);
312
+ setupBroadcasting(connections, runtime);
313
+ },
314
+ async close() {
315
+ if (!peer) return;
316
+ for (const ws of connections) {
317
+ ws.close();
318
+ }
319
+ connections.clear();
320
+ if (!attachedToServer) {
321
+ await new Promise((resolve) => {
322
+ peer.close(() => resolve());
323
+ });
2388
324
  }
2389
- yield* connection.createIterator();
325
+ peer = null;
2390
326
  },
2391
- interrupt() {
2392
- const interruptUrl = `${serverUrl}/agents/${agentId}/interrupt`;
2393
- fetch(interruptUrl, {
2394
- method: "POST",
2395
- headers: {
2396
- "Content-Type": "application/json",
2397
- ...headers
327
+ async dispose() {
328
+ if (peer) {
329
+ for (const ws of connections) {
330
+ ws.close();
2398
331
  }
2399
- }).catch(() => {
2400
- });
332
+ connections.clear();
333
+ if (!attachedToServer) {
334
+ await new Promise((resolve) => {
335
+ peer.close(() => resolve());
336
+ });
337
+ }
338
+ peer = null;
339
+ }
340
+ await runtime.dispose();
2401
341
  }
2402
342
  };
2403
343
  }
2404
- var logger9 = common.createLogger("agentx/RemoteRepository");
2405
- var RemoteRepository = class {
2406
- constructor(options) {
2407
- __publicField(this, "client");
2408
- this.client = createHttpClient({
2409
- baseUrl: options.serverUrl,
2410
- headers: options.headers
2411
- });
2412
- logger9.debug("RemoteRepository created", { serverUrl: options.serverUrl });
2413
- }
2414
- // ==================== Definition ====================
2415
- async saveDefinition(record) {
2416
- await this.client.put(`definitions/${record.name}`, { json: record });
2417
- }
2418
- async findDefinitionByName(name) {
2419
- try {
2420
- const result = await this.client.get(`definitions/${name}`).json();
2421
- return this.parseDefinitionRecord(result);
2422
- } catch (error) {
2423
- if (this.isNotFound(error)) return null;
2424
- throw error;
2425
- }
2426
- }
2427
- async findAllDefinitions() {
2428
- const result = await this.client.get("definitions").json();
2429
- return result.map((r) => this.parseDefinitionRecord(r));
2430
- }
2431
- async deleteDefinition(name) {
2432
- await this.client.delete(`definitions/${name}`);
2433
- }
2434
- async definitionExists(name) {
2435
- try {
2436
- await this.client.head(`definitions/${name}`);
2437
- return true;
2438
- } catch {
2439
- return false;
2440
- }
2441
- }
2442
- // ==================== Image ====================
2443
- async saveImage(record) {
2444
- await this.client.put(`images/${record.imageId}`, { json: record });
2445
- }
2446
- async findImageById(imageId) {
2447
- try {
2448
- const result = await this.client.get(`images/${imageId}`).json();
2449
- return this.parseImageRecord(result);
2450
- } catch (error) {
2451
- if (this.isNotFound(error)) return null;
2452
- throw error;
2453
- }
2454
- }
2455
- async findAllImages() {
2456
- const result = await this.client.get("images").json();
2457
- return result.map((r) => this.parseImageRecord(r));
344
+ var logger;
345
+ var init_createLocalAgentX = __esm({
346
+ "src/createLocalAgentX.ts"() {
347
+ init_dist();
348
+ logger = createLogger("agentx/createAgentX");
2458
349
  }
2459
- async deleteImage(imageId) {
2460
- await this.client.delete(`images/${imageId}`);
2461
- }
2462
- async imageExists(imageId) {
2463
- try {
2464
- await this.client.head(`images/${imageId}`);
2465
- return true;
2466
- } catch {
2467
- return false;
2468
- }
2469
- }
2470
- // ==================== Session ====================
2471
- async saveSession(record) {
2472
- await this.client.put(`sessions/${record.sessionId}`, { json: record });
2473
- }
2474
- async findSessionById(sessionId) {
2475
- try {
2476
- const result = await this.client.get(`sessions/${sessionId}`).json();
2477
- return this.parseSessionRecord(result);
2478
- } catch (error) {
2479
- if (this.isNotFound(error)) return null;
2480
- throw error;
350
+ });
351
+
352
+ // ../types/dist/agentx.js
353
+ function isRemoteConfig(config) {
354
+ return "serverUrl" in config && typeof config.serverUrl === "string";
355
+ }
356
+ function isLocalConfig(config) {
357
+ return !isRemoteConfig(config);
358
+ }
359
+
360
+ // src/createAgentX.ts
361
+ init_dist();
362
+ var remoteLogger = createLogger("agentx/RemoteClient");
363
+ async function createAgentX(config) {
364
+ if (config && isRemoteConfig(config)) {
365
+ return createRemoteAgentX(config.serverUrl);
366
+ }
367
+ const { createLocalAgentX: createLocalAgentX2 } = await Promise.resolve().then(() => (init_createLocalAgentX(), createLocalAgentX_exports));
368
+ return createLocalAgentX2(config ?? {});
369
+ }
370
+ var isBrowser = typeof window !== "undefined" && typeof window.WebSocket !== "undefined";
371
+ async function createRemoteAgentX(serverUrl) {
372
+ const WebSocketImpl = isBrowser ? window.WebSocket : (await import('ws')).WebSocket;
373
+ const ws = new WebSocketImpl(serverUrl);
374
+ const handlers = /* @__PURE__ */ new Map();
375
+ const pendingRequests = /* @__PURE__ */ new Map();
376
+ await new Promise((resolve, reject) => {
377
+ if (isBrowser) {
378
+ ws.onopen = () => resolve();
379
+ ws.onerror = () => reject(new Error("WebSocket connection failed"));
380
+ } else {
381
+ ws.on("open", () => resolve());
382
+ ws.on("error", (err) => reject(err));
2481
383
  }
2482
- }
2483
- async findSessionsByImageId(imageId) {
2484
- const result = await this.client.get(`images/${imageId}/sessions`).json();
2485
- return result.map((r) => this.parseSessionRecord(r));
2486
- }
2487
- async findSessionsByUserId(userId) {
2488
- const result = await this.client.get(`users/${userId}/sessions`).json();
2489
- return result.map((r) => this.parseSessionRecord(r));
2490
- }
2491
- async findAllSessions() {
2492
- const result = await this.client.get("sessions").json();
2493
- return result.map((r) => this.parseSessionRecord(r));
2494
- }
2495
- async deleteSession(sessionId) {
2496
- await this.client.delete(`sessions/${sessionId}`);
2497
- }
2498
- async deleteSessionsByImageId(imageId) {
2499
- await this.client.delete(`images/${imageId}/sessions`);
2500
- }
2501
- async sessionExists(sessionId) {
384
+ });
385
+ const handleMessage = (data) => {
2502
386
  try {
2503
- await this.client.head(`sessions/${sessionId}`);
2504
- return true;
387
+ const text = isBrowser ? data.data : data.toString();
388
+ const event = JSON.parse(text);
389
+ remoteLogger.info("Received event", {
390
+ type: event.type,
391
+ category: event.category,
392
+ requestId: event.data?.requestId
393
+ });
394
+ if (event.type === "system_error") {
395
+ const errorData = event.data;
396
+ remoteLogger.error(errorData.message, {
397
+ severity: errorData.severity,
398
+ requestId: event.data?.requestId,
399
+ details: errorData.details
400
+ });
401
+ }
402
+ const requestId = event.data?.requestId;
403
+ if (event.category === "response" && requestId && pendingRequests.has(requestId)) {
404
+ remoteLogger.info("Resolving pending request", { requestId, eventType: event.type });
405
+ const pending = pendingRequests.get(requestId);
406
+ clearTimeout(pending.timer);
407
+ pendingRequests.delete(requestId);
408
+ pending.resolve(event);
409
+ return;
410
+ }
411
+ remoteLogger.info("Dispatching to handlers", { type: event.type });
412
+ const typeHandlers = handlers.get(event.type);
413
+ if (typeHandlers) {
414
+ for (const handler of typeHandlers) {
415
+ handler(event);
416
+ }
417
+ }
418
+ const allHandlers = handlers.get("*");
419
+ if (allHandlers) {
420
+ for (const handler of allHandlers) {
421
+ handler(event);
422
+ }
423
+ }
2505
424
  } catch {
2506
- return false;
2507
- }
2508
- }
2509
- // ==================== Message ====================
2510
- /**
2511
- * Save message - noop in browser
2512
- *
2513
- * Messages are persisted by server-side SessionCollector.
2514
- * Browser-side calls this but it does nothing to avoid duplicate saves.
2515
- */
2516
- async saveMessage(_record) {
2517
- logger9.debug("saveMessage called (noop in browser)");
2518
- }
2519
- async findMessageById(messageId) {
2520
- try {
2521
- const result = await this.client.get(`messages/${messageId}`).json();
2522
- return this.parseMessageRecord(result);
2523
- } catch (error) {
2524
- if (this.isNotFound(error)) return null;
2525
- throw error;
2526
425
  }
426
+ };
427
+ if (isBrowser) {
428
+ ws.onmessage = handleMessage;
429
+ } else {
430
+ ws.on("message", handleMessage);
2527
431
  }
2528
- async findMessagesBySessionId(sessionId) {
2529
- const result = await this.client.get(`sessions/${sessionId}/messages`).json();
2530
- return result.map((r) => this.parseMessageRecord(r));
2531
- }
2532
- async deleteMessage(messageId) {
2533
- await this.client.delete(`messages/${messageId}`);
2534
- }
2535
- async deleteMessagesBySessionId(sessionId) {
2536
- await this.client.delete(`sessions/${sessionId}/messages`);
2537
- }
2538
- async countMessagesBySessionId(sessionId) {
2539
- const result = await this.client.get(`sessions/${sessionId}/messages/count`).json();
2540
- return result.count;
2541
- }
2542
- // ==================== Container ====================
2543
- async saveContainer(record) {
2544
- await this.client.put(`containers/${record.containerId}`, { json: record });
2545
- }
2546
- async findContainerById(containerId) {
2547
- try {
2548
- const result = await this.client.get(`containers/${containerId}`).json();
2549
- return this.parseContainerRecord(result);
2550
- } catch (error) {
2551
- if (this.isNotFound(error)) return null;
2552
- throw error;
2553
- }
2554
- }
2555
- async findAllContainers() {
2556
- const result = await this.client.get("containers").json();
2557
- return result.map((r) => this.parseContainerRecord(r));
2558
- }
2559
- async deleteContainer(containerId) {
2560
- await this.client.delete(`containers/${containerId}`);
2561
- }
2562
- async containerExists(containerId) {
2563
- try {
2564
- await this.client.head(`containers/${containerId}`);
2565
- return true;
2566
- } catch {
2567
- return false;
432
+ function subscribe(type, handler) {
433
+ if (!handlers.has(type)) {
434
+ handlers.set(type, /* @__PURE__ */ new Set());
2568
435
  }
2569
- }
2570
- // ==================== Helpers ====================
2571
- isNotFound(error) {
2572
- return error?.response?.status === 404;
2573
- }
2574
- parseDefinitionRecord(raw) {
2575
- return {
2576
- ...raw,
2577
- createdAt: new Date(raw.createdAt),
2578
- updatedAt: new Date(raw.updatedAt)
2579
- };
2580
- }
2581
- parseImageRecord(raw) {
2582
- return {
2583
- ...raw,
2584
- createdAt: new Date(raw.createdAt)
2585
- };
2586
- }
2587
- parseSessionRecord(raw) {
2588
- return {
2589
- ...raw,
2590
- createdAt: new Date(raw.createdAt),
2591
- updatedAt: new Date(raw.updatedAt)
2592
- };
2593
- }
2594
- parseMessageRecord(raw) {
2595
- return {
2596
- ...raw,
2597
- createdAt: new Date(raw.createdAt)
2598
- };
2599
- }
2600
- parseContainerRecord(raw) {
2601
- return {
2602
- ...raw
2603
- // ContainerRecord uses number timestamps, no conversion needed
436
+ handlers.get(type).add(handler);
437
+ return () => {
438
+ handlers.get(type)?.delete(handler);
2604
439
  };
2605
440
  }
2606
- };
2607
- var _BrowserLogger = class _BrowserLogger {
2608
- constructor(name, options = {}) {
2609
- __publicField(this, "name");
2610
- __publicField(this, "level");
2611
- __publicField(this, "collapsed");
2612
- this.name = name;
2613
- this.level = options.level ?? types.LogLevel.INFO;
2614
- this.collapsed = options.collapsed ?? true;
2615
- }
2616
- debug(message, context) {
2617
- if (this.isDebugEnabled()) {
2618
- this.log("DEBUG", message, context);
2619
- }
2620
- }
2621
- info(message, context) {
2622
- if (this.isInfoEnabled()) {
2623
- this.log("INFO", message, context);
2624
- }
2625
- }
2626
- warn(message, context) {
2627
- if (this.isWarnEnabled()) {
2628
- this.log("WARN", message, context);
2629
- }
2630
- }
2631
- error(message, context) {
2632
- if (this.isErrorEnabled()) {
2633
- if (message instanceof Error) {
2634
- this.log("ERROR", message.message, { ...context, stack: message.stack });
441
+ return {
442
+ request(type, data, timeout = 3e4) {
443
+ return new Promise((resolve, reject) => {
444
+ const requestId = `req_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
445
+ const timer = setTimeout(() => {
446
+ pendingRequests.delete(requestId);
447
+ reject(new Error(`Request timeout: ${type}`));
448
+ }, timeout);
449
+ pendingRequests.set(requestId, {
450
+ resolve,
451
+ reject,
452
+ timer
453
+ });
454
+ const event = {
455
+ type,
456
+ timestamp: Date.now(),
457
+ data: { ...data, requestId },
458
+ source: "command",
459
+ category: "request",
460
+ intent: "request"
461
+ };
462
+ ws.send(JSON.stringify(event));
463
+ });
464
+ },
465
+ on(type, handler) {
466
+ return subscribe(type, handler);
467
+ },
468
+ onCommand(type, handler) {
469
+ return subscribe(type, handler);
470
+ },
471
+ emitCommand(type, data) {
472
+ const event = {
473
+ type,
474
+ timestamp: Date.now(),
475
+ data,
476
+ source: "command",
477
+ category: type.toString().endsWith("_response") ? "response" : "request",
478
+ intent: type.toString().endsWith("_response") ? "result" : "request"
479
+ };
480
+ ws.send(JSON.stringify(event));
481
+ },
482
+ async listen() {
483
+ throw new Error("Cannot listen in remote mode");
484
+ },
485
+ async close() {
486
+ },
487
+ async dispose() {
488
+ for (const pending of pendingRequests.values()) {
489
+ clearTimeout(pending.timer);
490
+ pending.reject(new Error("AgentX disposed"));
491
+ }
492
+ pendingRequests.clear();
493
+ handlers.clear();
494
+ if (isBrowser) {
495
+ ws.close();
2635
496
  } else {
2636
- this.log("ERROR", message, context);
497
+ ws.close();
2637
498
  }
2638
499
  }
2639
- }
2640
- isDebugEnabled() {
2641
- return this.level <= types.LogLevel.DEBUG;
2642
- }
2643
- isInfoEnabled() {
2644
- return this.level <= types.LogLevel.INFO;
2645
- }
2646
- isWarnEnabled() {
2647
- return this.level <= types.LogLevel.WARN;
2648
- }
2649
- isErrorEnabled() {
2650
- return this.level <= types.LogLevel.ERROR;
2651
- }
2652
- log(level, message, context) {
2653
- const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString();
2654
- const consoleMethod = this.getConsoleMethod(level);
2655
- const badgeStyle = _BrowserLogger.BADGE_STYLES[level];
2656
- const format = `%c${timestamp} %c${level}%c %c[${this.name}]%c ${message}`;
2657
- const styles = [
2658
- _BrowserLogger.STYLES.TIMESTAMP,
2659
- badgeStyle,
2660
- "",
2661
- // reset after badge
2662
- _BrowserLogger.STYLES.NAME,
2663
- _BrowserLogger.STYLES.MESSAGE
2664
- ];
2665
- if (context && Object.keys(context).length > 0) {
2666
- const groupMethod = this.collapsed ? console.groupCollapsed : console.group;
2667
- groupMethod.call(console, format, ...styles);
2668
- console.log("Context:", context);
2669
- console.groupEnd();
2670
- } else {
2671
- consoleMethod(format, ...styles);
2672
- }
2673
- }
2674
- getConsoleMethod(level) {
2675
- switch (level) {
2676
- case "DEBUG":
2677
- return console.debug.bind(console);
2678
- case "INFO":
2679
- return console.info.bind(console);
2680
- case "WARN":
2681
- return console.warn.bind(console);
2682
- case "ERROR":
2683
- return console.error.bind(console);
2684
- default:
2685
- return console.log.bind(console);
2686
- }
2687
- }
2688
- };
2689
- // CSS styles for different log levels
2690
- __publicField(_BrowserLogger, "STYLES", {
2691
- DEBUG: "color: #6B7280; font-weight: normal;",
2692
- // gray
2693
- INFO: "color: #10B981; font-weight: normal;",
2694
- // green
2695
- WARN: "color: #F59E0B; font-weight: bold;",
2696
- // amber
2697
- ERROR: "color: #EF4444; font-weight: bold;",
2698
- // red
2699
- TIMESTAMP: "color: #9CA3AF; font-weight: normal;",
2700
- // light gray
2701
- NAME: "color: #8B5CF6; font-weight: normal;",
2702
- // purple
2703
- MESSAGE: "color: inherit; font-weight: normal;"
2704
- });
2705
- // Badge styles for level indicators
2706
- __publicField(_BrowserLogger, "BADGE_STYLES", {
2707
- DEBUG: "background: #E5E7EB; color: #374151; padding: 2px 6px; border-radius: 3px; font-size: 11px;",
2708
- INFO: "background: #D1FAE5; color: #065F46; padding: 2px 6px; border-radius: 3px; font-size: 11px;",
2709
- WARN: "background: #FEF3C7; color: #92400E; padding: 2px 6px; border-radius: 3px; font-size: 11px;",
2710
- ERROR: "background: #FEE2E2; color: #991B1B; padding: 2px 6px; border-radius: 3px; font-size: 11px;"
2711
- });
2712
- var BrowserLogger = _BrowserLogger;
2713
-
2714
- // src/runtime/sse/logger/BrowserLoggerFactory.ts
2715
- var BrowserLoggerFactory = class {
2716
- constructor(options = {}) {
2717
- __publicField(this, "options");
2718
- __publicField(this, "loggers", /* @__PURE__ */ new Map());
2719
- this.options = options;
2720
- }
2721
- getLogger(name) {
2722
- if (this.loggers.has(name)) {
2723
- return this.loggers.get(name);
2724
- }
2725
- const logger11 = new BrowserLogger(name, this.options);
2726
- this.loggers.set(name, logger11);
2727
- return logger11;
2728
- }
2729
- };
2730
- var logger10 = common.createLogger("agentx/RemoteAgentIdResolver");
2731
- var RemoteAgentIdResolver = class {
2732
- constructor(options) {
2733
- __publicField(this, "client");
2734
- this.client = createHttpClient({
2735
- baseUrl: options.serverUrl,
2736
- headers: options.headers
2737
- });
2738
- }
2739
- async resolveForRun(imageId, containerId) {
2740
- logger10.debug("Resolving agent ID for run", { imageId, containerId });
2741
- const response = await this.client.post(`images/${imageId}/run`, {
2742
- json: { containerId }
2743
- }).json();
2744
- logger10.info("Agent ID resolved for run", { imageId, agentId: response.agentId });
2745
- return response.agentId;
2746
- }
2747
- async resolveForResume(sessionId, containerId) {
2748
- logger10.debug("Resolving agent ID for resume", { sessionId, containerId });
2749
- const response = await this.client.post(`sessions/${sessionId}/resume`, {
2750
- json: { containerId }
2751
- }).json();
2752
- logger10.info("Agent ID resolved for resume", { sessionId, agentId: response.agentId });
2753
- return response.agentId;
2754
- }
2755
- };
500
+ };
501
+ }
2756
502
 
2757
- // src/runtime/sse/SSERuntime.ts
2758
- var noopSandbox = {
2759
- name: "browser-noop",
2760
- workspace: {
2761
- id: "noop",
2762
- name: "noop",
2763
- path: ""
2764
- // Browser has no local workspace
2765
- },
2766
- llm: {
2767
- name: "noop",
2768
- provide: () => ({})
2769
- }
2770
- };
2771
- var SSERuntime = class {
2772
- constructor(config) {
2773
- __publicField(this, "name", "sse");
2774
- __publicField(this, "repository");
2775
- __publicField(this, "loggerFactory");
2776
- __publicField(this, "agentIdResolver");
2777
- __publicField(this, "serverUrl");
2778
- __publicField(this, "headers");
2779
- __publicField(this, "sseParams");
2780
- this.serverUrl = config.serverUrl.replace(/\/+$/, "");
2781
- this.headers = config.headers ?? {};
2782
- this.sseParams = config.sseParams ?? {};
2783
- this.loggerFactory = new BrowserLoggerFactory({
2784
- collapsed: true
2785
- });
2786
- common.setLoggerFactory(this.loggerFactory);
2787
- this.repository = new RemoteRepository({
2788
- serverUrl: this.serverUrl,
2789
- headers: this.headers
2790
- });
2791
- this.agentIdResolver = new RemoteAgentIdResolver({
2792
- serverUrl: this.serverUrl,
2793
- headers: this.headers
2794
- });
2795
- }
2796
- createSandbox(_containerId) {
2797
- return noopSandbox;
2798
- }
2799
- createDriver(_definition, context, _sandbox) {
2800
- const driver = createSSEDriver({
2801
- serverUrl: this.serverUrl,
2802
- agentId: context.agentId,
2803
- headers: this.headers,
2804
- sseParams: this.sseParams
2805
- });
2806
- return {
2807
- ...driver,
2808
- sandbox: noopSandbox
2809
- };
2810
- }
2811
- createLogger(name) {
2812
- return this.loggerFactory.getLogger(name);
2813
- }
2814
- };
2815
- function sseRuntime(config) {
2816
- return new SSERuntime(config);
503
+ // ../types/dist/event.js
504
+ function isFromSource(event, source) {
505
+ return event.source === source;
506
+ }
507
+ function hasIntent(event, intent) {
508
+ return event.intent === intent;
509
+ }
510
+ function isRequest(event) {
511
+ return event.intent === "request";
512
+ }
513
+ function isResult(event) {
514
+ return event.intent === "result";
515
+ }
516
+ function isNotification(event) {
517
+ return event.intent === "notification";
518
+ }
519
+ function isCommandEvent(event) {
520
+ return event.source === "command";
2817
521
  }
2818
- var createSSERuntime = sseRuntime;
522
+ function isCommandRequest(event) {
523
+ return event.source === "command" && event.category === "request";
524
+ }
525
+ function isCommandResponse(event) {
526
+ return event.source === "command" && event.category === "response";
527
+ }
528
+ function isAgentStreamEvent(event) {
529
+ return event.source === "agent" && event.category === "stream";
530
+ }
531
+ function isAgentStateEvent(event) {
532
+ return event.source === "agent" && event.category === "state";
533
+ }
534
+ function isAgentMessageEvent(event) {
535
+ return event.source === "agent" && event.category === "message";
536
+ }
537
+ function isAgentTurnEvent(event) {
538
+ return event.source === "agent" && event.category === "turn";
539
+ }
540
+ function isAgentEvent(event) {
541
+ return event.source === "agent";
542
+ }
543
+
544
+ // src/index.ts
545
+ init_dist();
2819
546
 
2820
547
  exports.createAgentX = createAgentX;
2821
- exports.createSSERuntime = createSSERuntime;
2822
- exports.defineAgent = defineAgent;
2823
- exports.sseRuntime = sseRuntime;
548
+ exports.createLogger = createLogger;
549
+ exports.createRemoteAgentX = createRemoteAgentX;
550
+ exports.hasIntent = hasIntent;
551
+ exports.isAgentEvent = isAgentEvent;
552
+ exports.isAgentMessageEvent = isAgentMessageEvent;
553
+ exports.isAgentStateEvent = isAgentStateEvent;
554
+ exports.isAgentStreamEvent = isAgentStreamEvent;
555
+ exports.isAgentTurnEvent = isAgentTurnEvent;
556
+ exports.isCommandEvent = isCommandEvent;
557
+ exports.isCommandRequest = isCommandRequest;
558
+ exports.isCommandResponse = isCommandResponse;
559
+ exports.isFromSource = isFromSource;
560
+ exports.isLocalConfig = isLocalConfig;
561
+ exports.isNotification = isNotification;
562
+ exports.isRemoteConfig = isRemoteConfig;
563
+ exports.isRequest = isRequest;
564
+ exports.isResult = isResult;
565
+ exports.setLoggerFactory = setLoggerFactory;
2824
566
  //# sourceMappingURL=index.cjs.map
2825
567
  //# sourceMappingURL=index.cjs.map