agentxjs 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1886 -174
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1742 -30
- package/dist/index.js.map +1 -1
- package/dist/runtime/sse/index.cjs +167 -4
- package/dist/runtime/sse/index.cjs.map +1 -1
- package/dist/runtime/sse/index.js +164 -1
- package/dist/runtime/sse/index.js.map +1 -1
- package/dist/server/index.cjs +163 -3
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.js +162 -2
- package/dist/server/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LogLevel, isStateEvent, STREAM_EVENT_TYPE_NAMES } from '@agentxjs/types';
|
|
2
2
|
import ky from 'ky';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { LogLevel, STREAM_EVENT_TYPE_NAMES } from '@agentxjs/types';
|
|
3
|
+
import { Subject } from 'rxjs';
|
|
4
|
+
import { filter, take } from 'rxjs/operators';
|
|
6
5
|
|
|
7
6
|
var __defProp = Object.defineProperty;
|
|
8
7
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -17,6 +16,170 @@ function defineAgent(input) {
|
|
|
17
16
|
systemPrompt
|
|
18
17
|
};
|
|
19
18
|
}
|
|
19
|
+
var __defProp2 = Object.defineProperty;
|
|
20
|
+
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
21
|
+
var __publicField2 = (obj, key, value) => __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
22
|
+
var _ConsoleLogger = class _ConsoleLogger2 {
|
|
23
|
+
constructor(name, options = {}) {
|
|
24
|
+
__publicField2(this, "name");
|
|
25
|
+
__publicField2(this, "level");
|
|
26
|
+
__publicField2(this, "colors");
|
|
27
|
+
__publicField2(this, "timestamps");
|
|
28
|
+
this.name = name;
|
|
29
|
+
this.level = options.level ?? LogLevel.INFO;
|
|
30
|
+
this.colors = options.colors ?? this.isNodeEnvironment();
|
|
31
|
+
this.timestamps = options.timestamps ?? true;
|
|
32
|
+
}
|
|
33
|
+
debug(message, context) {
|
|
34
|
+
if (this.isDebugEnabled()) {
|
|
35
|
+
this.log("DEBUG", message, context);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
info(message, context) {
|
|
39
|
+
if (this.isInfoEnabled()) {
|
|
40
|
+
this.log("INFO", message, context);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
warn(message, context) {
|
|
44
|
+
if (this.isWarnEnabled()) {
|
|
45
|
+
this.log("WARN", message, context);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
error(message, context) {
|
|
49
|
+
if (this.isErrorEnabled()) {
|
|
50
|
+
if (message instanceof Error) {
|
|
51
|
+
this.log("ERROR", message.message, { ...context, stack: message.stack });
|
|
52
|
+
} else {
|
|
53
|
+
this.log("ERROR", message, context);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
isDebugEnabled() {
|
|
58
|
+
return this.level <= LogLevel.DEBUG;
|
|
59
|
+
}
|
|
60
|
+
isInfoEnabled() {
|
|
61
|
+
return this.level <= LogLevel.INFO;
|
|
62
|
+
}
|
|
63
|
+
isWarnEnabled() {
|
|
64
|
+
return this.level <= LogLevel.WARN;
|
|
65
|
+
}
|
|
66
|
+
isErrorEnabled() {
|
|
67
|
+
return this.level <= LogLevel.ERROR;
|
|
68
|
+
}
|
|
69
|
+
log(level, message, context) {
|
|
70
|
+
const parts = [];
|
|
71
|
+
if (this.timestamps) {
|
|
72
|
+
parts.push((/* @__PURE__ */ new Date()).toISOString());
|
|
73
|
+
}
|
|
74
|
+
if (this.colors) {
|
|
75
|
+
const color = _ConsoleLogger2.COLORS[level];
|
|
76
|
+
parts.push(`${color}${level.padEnd(5)}${_ConsoleLogger2.COLORS.RESET}`);
|
|
77
|
+
} else {
|
|
78
|
+
parts.push(level.padEnd(5));
|
|
79
|
+
}
|
|
80
|
+
parts.push(`[${this.name}]`);
|
|
81
|
+
parts.push(message);
|
|
82
|
+
const logLine = parts.join(" ");
|
|
83
|
+
const consoleMethod = this.getConsoleMethod(level);
|
|
84
|
+
if (context && Object.keys(context).length > 0) {
|
|
85
|
+
consoleMethod(logLine, context);
|
|
86
|
+
} else {
|
|
87
|
+
consoleMethod(logLine);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
getConsoleMethod(level) {
|
|
91
|
+
switch (level) {
|
|
92
|
+
case "DEBUG":
|
|
93
|
+
return console.debug.bind(console);
|
|
94
|
+
case "INFO":
|
|
95
|
+
return console.info.bind(console);
|
|
96
|
+
case "WARN":
|
|
97
|
+
return console.warn.bind(console);
|
|
98
|
+
case "ERROR":
|
|
99
|
+
return console.error.bind(console);
|
|
100
|
+
default:
|
|
101
|
+
return console.log.bind(console);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
isNodeEnvironment() {
|
|
105
|
+
return typeof process !== "undefined" && process.versions?.node !== void 0;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
__publicField2(_ConsoleLogger, "COLORS", {
|
|
109
|
+
DEBUG: "\x1B[36m",
|
|
110
|
+
INFO: "\x1B[32m",
|
|
111
|
+
WARN: "\x1B[33m",
|
|
112
|
+
ERROR: "\x1B[31m",
|
|
113
|
+
RESET: "\x1B[0m"
|
|
114
|
+
});
|
|
115
|
+
var ConsoleLogger = _ConsoleLogger;
|
|
116
|
+
var externalFactory = null;
|
|
117
|
+
var LoggerFactoryImpl = class {
|
|
118
|
+
static getLogger(nameOrClass) {
|
|
119
|
+
const name = typeof nameOrClass === "string" ? nameOrClass : nameOrClass.name;
|
|
120
|
+
if (this.loggers.has(name)) {
|
|
121
|
+
return this.loggers.get(name);
|
|
122
|
+
}
|
|
123
|
+
const lazyLogger = this.createLazyLogger(name);
|
|
124
|
+
this.loggers.set(name, lazyLogger);
|
|
125
|
+
return lazyLogger;
|
|
126
|
+
}
|
|
127
|
+
static configure(config) {
|
|
128
|
+
this.config = { ...this.config, ...config };
|
|
129
|
+
}
|
|
130
|
+
static reset() {
|
|
131
|
+
this.loggers.clear();
|
|
132
|
+
this.config = { defaultLevel: LogLevel.INFO };
|
|
133
|
+
externalFactory = null;
|
|
134
|
+
}
|
|
135
|
+
static createLazyLogger(name) {
|
|
136
|
+
let realLogger = null;
|
|
137
|
+
const getRealLogger = () => {
|
|
138
|
+
if (!realLogger) {
|
|
139
|
+
realLogger = this.createLogger(name);
|
|
140
|
+
}
|
|
141
|
+
return realLogger;
|
|
142
|
+
};
|
|
143
|
+
return {
|
|
144
|
+
name,
|
|
145
|
+
level: this.config.defaultLevel || LogLevel.INFO,
|
|
146
|
+
debug: (message, context) => getRealLogger().debug(message, context),
|
|
147
|
+
info: (message, context) => getRealLogger().info(message, context),
|
|
148
|
+
warn: (message, context) => getRealLogger().warn(message, context),
|
|
149
|
+
error: (message, context) => getRealLogger().error(message, context),
|
|
150
|
+
isDebugEnabled: () => getRealLogger().isDebugEnabled(),
|
|
151
|
+
isInfoEnabled: () => getRealLogger().isInfoEnabled(),
|
|
152
|
+
isWarnEnabled: () => getRealLogger().isWarnEnabled(),
|
|
153
|
+
isErrorEnabled: () => getRealLogger().isErrorEnabled()
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
static createLogger(name) {
|
|
157
|
+
if (externalFactory) {
|
|
158
|
+
return externalFactory.getLogger(name);
|
|
159
|
+
}
|
|
160
|
+
if (this.config.defaultImplementation) {
|
|
161
|
+
return this.config.defaultImplementation(name);
|
|
162
|
+
}
|
|
163
|
+
return new ConsoleLogger(name, {
|
|
164
|
+
level: this.config.defaultLevel,
|
|
165
|
+
...this.config.consoleOptions
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
__publicField2(LoggerFactoryImpl, "loggers", /* @__PURE__ */ new Map());
|
|
170
|
+
__publicField2(LoggerFactoryImpl, "config", {
|
|
171
|
+
defaultLevel: LogLevel.INFO
|
|
172
|
+
});
|
|
173
|
+
function setLoggerFactory(factory) {
|
|
174
|
+
externalFactory = factory;
|
|
175
|
+
LoggerFactoryImpl.reset();
|
|
176
|
+
externalFactory = factory;
|
|
177
|
+
}
|
|
178
|
+
function createLogger(name) {
|
|
179
|
+
return LoggerFactoryImpl.getLogger(name);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// src/managers/definition/DefinitionManagerImpl.ts
|
|
20
183
|
var logger = createLogger("agentx/DefinitionManager");
|
|
21
184
|
function generateMetaImageId(definitionName) {
|
|
22
185
|
return `meta_${definitionName}`;
|
|
@@ -93,6 +256,8 @@ var DefinitionManagerImpl = class {
|
|
|
93
256
|
return true;
|
|
94
257
|
}
|
|
95
258
|
};
|
|
259
|
+
|
|
260
|
+
// src/managers/image/ImageManagerImpl.ts
|
|
96
261
|
var logger2 = createLogger("agentx/ImageManager");
|
|
97
262
|
function generateMetaImageId2(definitionName) {
|
|
98
263
|
return `meta_${definitionName}`;
|
|
@@ -188,6 +353,8 @@ var ImageManagerImpl = class {
|
|
|
188
353
|
return this.containerManager.run(image, containerId);
|
|
189
354
|
}
|
|
190
355
|
};
|
|
356
|
+
|
|
357
|
+
// src/managers/agent/AgentManager.ts
|
|
191
358
|
var logger3 = createLogger("agentx/AgentManager");
|
|
192
359
|
var AgentManager = class {
|
|
193
360
|
constructor(containerManager) {
|
|
@@ -229,6 +396,8 @@ var AgentManager = class {
|
|
|
229
396
|
logger3.info("All agents destroyed", { count: agents.length });
|
|
230
397
|
}
|
|
231
398
|
};
|
|
399
|
+
|
|
400
|
+
// src/managers/session/SessionManagerImpl.ts
|
|
232
401
|
var logger4 = createLogger("agentx/SessionManager");
|
|
233
402
|
function generateSessionId() {
|
|
234
403
|
const timestamp = Date.now().toString(36);
|
|
@@ -443,6 +612,8 @@ var SessionManagerImpl = class {
|
|
|
443
612
|
logger4.info("All sessions destroyed");
|
|
444
613
|
}
|
|
445
614
|
};
|
|
615
|
+
|
|
616
|
+
// src/managers/error/ErrorManager.ts
|
|
446
617
|
var logger5 = createLogger("agentx/ErrorManager");
|
|
447
618
|
var ErrorManager = class {
|
|
448
619
|
constructor() {
|
|
@@ -524,7 +695,1544 @@ function createHttpClient(options) {
|
|
|
524
695
|
}
|
|
525
696
|
});
|
|
526
697
|
}
|
|
527
|
-
var logger6 = createLogger("
|
|
698
|
+
var logger6 = createLogger("core/AgentStateMachine");
|
|
699
|
+
var AgentStateMachine = class {
|
|
700
|
+
constructor() {
|
|
701
|
+
__publicField(this, "_state", "idle");
|
|
702
|
+
__publicField(this, "handlers", /* @__PURE__ */ new Set());
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* Current agent state
|
|
706
|
+
*/
|
|
707
|
+
get state() {
|
|
708
|
+
return this._state;
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* Process a StateEvent and update internal state
|
|
712
|
+
*
|
|
713
|
+
* @param event - StateEvent from Engine layer
|
|
714
|
+
*/
|
|
715
|
+
process(event) {
|
|
716
|
+
const prev = this._state;
|
|
717
|
+
const next = this.mapEventToState(event);
|
|
718
|
+
if (next !== null && prev !== next) {
|
|
719
|
+
this._state = next;
|
|
720
|
+
logger6.debug("State transition", {
|
|
721
|
+
eventType: event.type,
|
|
722
|
+
from: prev,
|
|
723
|
+
to: next
|
|
724
|
+
});
|
|
725
|
+
this.notifyHandlers({ prev, current: next });
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Subscribe to state changes
|
|
730
|
+
*
|
|
731
|
+
* @param handler - Callback receiving { prev, current } state change
|
|
732
|
+
* @returns Unsubscribe function
|
|
733
|
+
*/
|
|
734
|
+
onStateChange(handler) {
|
|
735
|
+
this.handlers.add(handler);
|
|
736
|
+
return () => {
|
|
737
|
+
this.handlers.delete(handler);
|
|
738
|
+
};
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Reset state machine (used on destroy)
|
|
742
|
+
*/
|
|
743
|
+
reset() {
|
|
744
|
+
this._state;
|
|
745
|
+
this._state = "idle";
|
|
746
|
+
this.handlers.clear();
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Map StateEvent type to AgentState
|
|
750
|
+
*
|
|
751
|
+
* @param event - StateEvent from Engine
|
|
752
|
+
* @returns New AgentState or null if no transition needed
|
|
753
|
+
*/
|
|
754
|
+
mapEventToState(event) {
|
|
755
|
+
switch (event.type) {
|
|
756
|
+
// Agent lifecycle
|
|
757
|
+
case "agent_initializing":
|
|
758
|
+
return "initializing";
|
|
759
|
+
case "agent_ready":
|
|
760
|
+
return "idle";
|
|
761
|
+
case "agent_destroyed":
|
|
762
|
+
return "idle";
|
|
763
|
+
// Conversation lifecycle
|
|
764
|
+
case "conversation_queued":
|
|
765
|
+
return "queued";
|
|
766
|
+
case "conversation_start":
|
|
767
|
+
return "conversation_active";
|
|
768
|
+
case "conversation_thinking":
|
|
769
|
+
return "thinking";
|
|
770
|
+
case "conversation_responding":
|
|
771
|
+
return "responding";
|
|
772
|
+
case "conversation_end":
|
|
773
|
+
return "idle";
|
|
774
|
+
case "conversation_interrupted":
|
|
775
|
+
return "idle";
|
|
776
|
+
// Return to idle on interrupt
|
|
777
|
+
// Tool lifecycle
|
|
778
|
+
case "tool_planned":
|
|
779
|
+
return "planning_tool";
|
|
780
|
+
case "tool_executing":
|
|
781
|
+
return "awaiting_tool_result";
|
|
782
|
+
case "tool_completed":
|
|
783
|
+
return "responding";
|
|
784
|
+
// Back to responding after tool completes
|
|
785
|
+
case "tool_failed":
|
|
786
|
+
return "responding";
|
|
787
|
+
// Continue responding after tool failure
|
|
788
|
+
// Error
|
|
789
|
+
case "error_occurred":
|
|
790
|
+
return "idle";
|
|
791
|
+
// Reset to idle on error
|
|
792
|
+
default:
|
|
793
|
+
return null;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Notify all registered handlers of state change
|
|
798
|
+
*/
|
|
799
|
+
notifyHandlers(change) {
|
|
800
|
+
for (const handler of this.handlers) {
|
|
801
|
+
try {
|
|
802
|
+
handler(change);
|
|
803
|
+
} catch (error) {
|
|
804
|
+
logger6.error("State change handler error", {
|
|
805
|
+
from: change.prev,
|
|
806
|
+
to: change.current,
|
|
807
|
+
error
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
};
|
|
813
|
+
var logger22 = createLogger("core/AgentEventBus");
|
|
814
|
+
var AgentEventBus = class {
|
|
815
|
+
constructor() {
|
|
816
|
+
__publicField(this, "subject", new Subject());
|
|
817
|
+
__publicField(this, "typeSubscriptions", /* @__PURE__ */ new Map());
|
|
818
|
+
__publicField(this, "globalSubscriptions", []);
|
|
819
|
+
__publicField(this, "nextId", 0);
|
|
820
|
+
__publicField(this, "isDestroyed", false);
|
|
821
|
+
// Cached views
|
|
822
|
+
__publicField(this, "producerView", null);
|
|
823
|
+
__publicField(this, "consumerView", null);
|
|
824
|
+
}
|
|
825
|
+
// ===== Producer Methods =====
|
|
826
|
+
emit(event) {
|
|
827
|
+
if (this.isDestroyed) {
|
|
828
|
+
logger22.warn("Emit called on destroyed EventBus", { eventType: event.type });
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
this.subject.next(event);
|
|
832
|
+
}
|
|
833
|
+
emitBatch(events) {
|
|
834
|
+
for (const event of events) {
|
|
835
|
+
this.emit(event);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
on(typeOrTypes, handler, options = {}) {
|
|
839
|
+
if (this.isDestroyed) {
|
|
840
|
+
logger22.warn("Subscribe called on destroyed EventBus");
|
|
841
|
+
return () => {
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
const types = Array.isArray(typeOrTypes) ? typeOrTypes : [typeOrTypes];
|
|
845
|
+
const unsubscribes = [];
|
|
846
|
+
for (const type of types) {
|
|
847
|
+
const unsub = this.subscribeToType(type, handler, options);
|
|
848
|
+
unsubscribes.push(unsub);
|
|
849
|
+
}
|
|
850
|
+
return () => unsubscribes.forEach((u) => u());
|
|
851
|
+
}
|
|
852
|
+
onAny(handler, options = {}) {
|
|
853
|
+
if (this.isDestroyed) {
|
|
854
|
+
logger22.warn("Subscribe called on destroyed EventBus");
|
|
855
|
+
return () => {
|
|
856
|
+
};
|
|
857
|
+
}
|
|
858
|
+
return this.subscribeGlobal(handler, options);
|
|
859
|
+
}
|
|
860
|
+
once(type, handler) {
|
|
861
|
+
return this.on(type, handler, { once: true });
|
|
862
|
+
}
|
|
863
|
+
// ===== View Methods =====
|
|
864
|
+
asConsumer() {
|
|
865
|
+
if (!this.consumerView) {
|
|
866
|
+
this.consumerView = {
|
|
867
|
+
on: this.on.bind(this),
|
|
868
|
+
onAny: this.onAny.bind(this),
|
|
869
|
+
once: this.once.bind(this)
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
return this.consumerView;
|
|
873
|
+
}
|
|
874
|
+
asProducer() {
|
|
875
|
+
if (!this.producerView) {
|
|
876
|
+
this.producerView = {
|
|
877
|
+
emit: this.emit.bind(this),
|
|
878
|
+
emitBatch: this.emitBatch.bind(this)
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
return this.producerView;
|
|
882
|
+
}
|
|
883
|
+
// ===== Lifecycle =====
|
|
884
|
+
destroy() {
|
|
885
|
+
if (this.isDestroyed) return;
|
|
886
|
+
this.isDestroyed = true;
|
|
887
|
+
for (const records of this.typeSubscriptions.values()) {
|
|
888
|
+
for (const record of records) {
|
|
889
|
+
record.unsubscribe();
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
this.typeSubscriptions.clear();
|
|
893
|
+
for (const record of this.globalSubscriptions) {
|
|
894
|
+
record.unsubscribe();
|
|
895
|
+
}
|
|
896
|
+
this.globalSubscriptions.length = 0;
|
|
897
|
+
this.subject.complete();
|
|
898
|
+
logger22.debug("EventBus destroyed");
|
|
899
|
+
}
|
|
900
|
+
// ===== Private Methods =====
|
|
901
|
+
subscribeToType(type, handler, options) {
|
|
902
|
+
const { filter: filter$1, priority = 0, once = false } = options;
|
|
903
|
+
const id = this.nextId++;
|
|
904
|
+
let observable = this.subject.pipe(filter((e) => e.type === type));
|
|
905
|
+
if (filter$1) {
|
|
906
|
+
observable = observable.pipe(filter(filter$1));
|
|
907
|
+
}
|
|
908
|
+
if (once) {
|
|
909
|
+
observable = observable.pipe(take(1));
|
|
910
|
+
}
|
|
911
|
+
const subscription = observable.subscribe({
|
|
912
|
+
next: (event) => {
|
|
913
|
+
this.executeWithPriority(type, event, handler, id);
|
|
914
|
+
}
|
|
915
|
+
});
|
|
916
|
+
const unsubscribe = () => {
|
|
917
|
+
subscription.unsubscribe();
|
|
918
|
+
const records2 = this.typeSubscriptions.get(type);
|
|
919
|
+
if (records2) {
|
|
920
|
+
const idx = records2.findIndex((r) => r.id === id);
|
|
921
|
+
if (idx !== -1) records2.splice(idx, 1);
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
if (!this.typeSubscriptions.has(type)) {
|
|
925
|
+
this.typeSubscriptions.set(type, []);
|
|
926
|
+
}
|
|
927
|
+
const record = { id, priority, handler, unsubscribe };
|
|
928
|
+
const records = this.typeSubscriptions.get(type);
|
|
929
|
+
records.push(record);
|
|
930
|
+
records.sort((a, b) => b.priority - a.priority);
|
|
931
|
+
return unsubscribe;
|
|
932
|
+
}
|
|
933
|
+
subscribeGlobal(handler, options) {
|
|
934
|
+
const { filter: filter$1, priority = 0, once = false } = options;
|
|
935
|
+
const id = this.nextId++;
|
|
936
|
+
let observable = this.subject.asObservable();
|
|
937
|
+
if (filter$1) {
|
|
938
|
+
observable = observable.pipe(filter(filter$1));
|
|
939
|
+
}
|
|
940
|
+
if (once) {
|
|
941
|
+
observable = observable.pipe(take(1));
|
|
942
|
+
}
|
|
943
|
+
const subscription = observable.subscribe({
|
|
944
|
+
next: (event) => {
|
|
945
|
+
this.executeGlobalWithPriority(event, handler, id);
|
|
946
|
+
}
|
|
947
|
+
});
|
|
948
|
+
const unsubscribe = () => {
|
|
949
|
+
subscription.unsubscribe();
|
|
950
|
+
const idx = this.globalSubscriptions.findIndex((r) => r.id === id);
|
|
951
|
+
if (idx !== -1) this.globalSubscriptions.splice(idx, 1);
|
|
952
|
+
};
|
|
953
|
+
const record = { id, priority, handler, unsubscribe };
|
|
954
|
+
this.globalSubscriptions.push(record);
|
|
955
|
+
this.globalSubscriptions.sort((a, b) => b.priority - a.priority);
|
|
956
|
+
return unsubscribe;
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Execute handler respecting priority order for typed subscriptions
|
|
960
|
+
*/
|
|
961
|
+
executeWithPriority(type, event, handler, handlerId) {
|
|
962
|
+
const records = this.typeSubscriptions.get(type) || [];
|
|
963
|
+
const record = records.find((r) => r.id === handlerId);
|
|
964
|
+
if (record) {
|
|
965
|
+
try {
|
|
966
|
+
handler(event);
|
|
967
|
+
} catch (error) {
|
|
968
|
+
logger22.error("Event handler error", { eventType: type, error });
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
/**
|
|
973
|
+
* Execute handler respecting priority order for global subscriptions
|
|
974
|
+
*/
|
|
975
|
+
executeGlobalWithPriority(event, handler, handlerId) {
|
|
976
|
+
const record = this.globalSubscriptions.find((r) => r.id === handlerId);
|
|
977
|
+
if (record) {
|
|
978
|
+
try {
|
|
979
|
+
handler(event);
|
|
980
|
+
} catch (error) {
|
|
981
|
+
logger22.error("Global event handler error", { eventType: event.type, error });
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
};
|
|
986
|
+
var AgentErrorClassifier = class {
|
|
987
|
+
constructor(agentId) {
|
|
988
|
+
this.agentId = agentId;
|
|
989
|
+
}
|
|
990
|
+
/**
|
|
991
|
+
* Classify an unknown error into an AgentError
|
|
992
|
+
*/
|
|
993
|
+
classify(error) {
|
|
994
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
995
|
+
const message = err.message;
|
|
996
|
+
if (message.includes("rate limit") || message.includes("429")) {
|
|
997
|
+
return this.create("llm", "RATE_LIMITED", message, true, err);
|
|
998
|
+
}
|
|
999
|
+
if (message.includes("api key") || message.includes("401") || message.includes("unauthorized")) {
|
|
1000
|
+
return this.create("llm", "INVALID_API_KEY", message, false, err);
|
|
1001
|
+
}
|
|
1002
|
+
if (message.includes("context") && message.includes("long")) {
|
|
1003
|
+
return this.create("llm", "CONTEXT_TOO_LONG", message, true, err);
|
|
1004
|
+
}
|
|
1005
|
+
if (message.includes("overloaded") || message.includes("503")) {
|
|
1006
|
+
return this.create("llm", "OVERLOADED", message, true, err);
|
|
1007
|
+
}
|
|
1008
|
+
if (message.includes("timeout") || message.includes("ETIMEDOUT")) {
|
|
1009
|
+
return this.create("network", "TIMEOUT", message, true, err);
|
|
1010
|
+
}
|
|
1011
|
+
if (message.includes("ECONNREFUSED") || message.includes("connection")) {
|
|
1012
|
+
return this.create("network", "CONNECTION_FAILED", message, true, err);
|
|
1013
|
+
}
|
|
1014
|
+
if (message.includes("network") || message.includes("fetch")) {
|
|
1015
|
+
return this.create("network", "CONNECTION_FAILED", message, true, err);
|
|
1016
|
+
}
|
|
1017
|
+
if (message.includes("driver")) {
|
|
1018
|
+
return this.create("driver", "RECEIVE_FAILED", message, true, err);
|
|
1019
|
+
}
|
|
1020
|
+
return this.create("system", "UNKNOWN", message, true, err);
|
|
1021
|
+
}
|
|
1022
|
+
/**
|
|
1023
|
+
* Create an AgentError with the specified category and code
|
|
1024
|
+
*/
|
|
1025
|
+
create(category, code, message, recoverable, cause) {
|
|
1026
|
+
return {
|
|
1027
|
+
category,
|
|
1028
|
+
code,
|
|
1029
|
+
message,
|
|
1030
|
+
severity: recoverable ? "error" : "fatal",
|
|
1031
|
+
recoverable,
|
|
1032
|
+
cause
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
/**
|
|
1036
|
+
* Create an ErrorEvent from an AgentError
|
|
1037
|
+
*
|
|
1038
|
+
* ErrorEvent is independent from Message layer and transportable via SSE.
|
|
1039
|
+
*/
|
|
1040
|
+
createEvent(error) {
|
|
1041
|
+
return {
|
|
1042
|
+
type: "error",
|
|
1043
|
+
uuid: `${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
|
|
1044
|
+
agentId: this.agentId,
|
|
1045
|
+
timestamp: Date.now(),
|
|
1046
|
+
data: {
|
|
1047
|
+
error
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
1050
|
+
}
|
|
1051
|
+
};
|
|
1052
|
+
var MiddlewareChain = class {
|
|
1053
|
+
constructor() {
|
|
1054
|
+
__publicField(this, "middlewares", []);
|
|
1055
|
+
}
|
|
1056
|
+
/**
|
|
1057
|
+
* Add middleware to the chain
|
|
1058
|
+
*
|
|
1059
|
+
* @param middleware - Middleware function
|
|
1060
|
+
* @returns Unsubscribe function to remove the middleware
|
|
1061
|
+
*/
|
|
1062
|
+
use(middleware) {
|
|
1063
|
+
this.middlewares.push(middleware);
|
|
1064
|
+
return () => {
|
|
1065
|
+
const index = this.middlewares.indexOf(middleware);
|
|
1066
|
+
if (index !== -1) {
|
|
1067
|
+
this.middlewares.splice(index, 1);
|
|
1068
|
+
}
|
|
1069
|
+
};
|
|
1070
|
+
}
|
|
1071
|
+
/**
|
|
1072
|
+
* Execute the middleware chain
|
|
1073
|
+
*
|
|
1074
|
+
* @param message - User message to process
|
|
1075
|
+
* @param finalHandler - Handler called at the end of the chain
|
|
1076
|
+
*/
|
|
1077
|
+
async execute(message, finalHandler) {
|
|
1078
|
+
let index = 0;
|
|
1079
|
+
const next = async (msg) => {
|
|
1080
|
+
if (index < this.middlewares.length) {
|
|
1081
|
+
const middleware = this.middlewares[index++];
|
|
1082
|
+
await middleware(msg, next);
|
|
1083
|
+
} else {
|
|
1084
|
+
await finalHandler(msg);
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
await next(message);
|
|
1088
|
+
}
|
|
1089
|
+
/**
|
|
1090
|
+
* Clear all middlewares
|
|
1091
|
+
*/
|
|
1092
|
+
clear() {
|
|
1093
|
+
this.middlewares.length = 0;
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* Get the number of middlewares
|
|
1097
|
+
*/
|
|
1098
|
+
get size() {
|
|
1099
|
+
return this.middlewares.length;
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
var logger32 = createLogger("core/InterceptorChain");
|
|
1103
|
+
var InterceptorChain = class {
|
|
1104
|
+
constructor(agentId) {
|
|
1105
|
+
__publicField(this, "interceptors", []);
|
|
1106
|
+
__publicField(this, "agentId");
|
|
1107
|
+
this.agentId = agentId;
|
|
1108
|
+
}
|
|
1109
|
+
/**
|
|
1110
|
+
* Add interceptor to the chain
|
|
1111
|
+
*
|
|
1112
|
+
* @param interceptor - Interceptor function
|
|
1113
|
+
* @returns Unsubscribe function to remove the interceptor
|
|
1114
|
+
*/
|
|
1115
|
+
intercept(interceptor) {
|
|
1116
|
+
this.interceptors.push(interceptor);
|
|
1117
|
+
return () => {
|
|
1118
|
+
const index = this.interceptors.indexOf(interceptor);
|
|
1119
|
+
if (index !== -1) {
|
|
1120
|
+
this.interceptors.splice(index, 1);
|
|
1121
|
+
}
|
|
1122
|
+
};
|
|
1123
|
+
}
|
|
1124
|
+
/**
|
|
1125
|
+
* Execute the interceptor chain
|
|
1126
|
+
*
|
|
1127
|
+
* @param event - Event to process
|
|
1128
|
+
* @param finalHandler - Handler called at the end of the chain
|
|
1129
|
+
*/
|
|
1130
|
+
execute(event, finalHandler) {
|
|
1131
|
+
let index = 0;
|
|
1132
|
+
const next = (e) => {
|
|
1133
|
+
if (index < this.interceptors.length) {
|
|
1134
|
+
const interceptor = this.interceptors[index++];
|
|
1135
|
+
try {
|
|
1136
|
+
interceptor(e, next);
|
|
1137
|
+
} catch (error) {
|
|
1138
|
+
logger32.error("Interceptor error", {
|
|
1139
|
+
agentId: this.agentId,
|
|
1140
|
+
eventType: e.type,
|
|
1141
|
+
interceptorIndex: index - 1,
|
|
1142
|
+
error
|
|
1143
|
+
});
|
|
1144
|
+
next(e);
|
|
1145
|
+
}
|
|
1146
|
+
} else {
|
|
1147
|
+
finalHandler(e);
|
|
1148
|
+
}
|
|
1149
|
+
};
|
|
1150
|
+
next(event);
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Clear all interceptors
|
|
1154
|
+
*/
|
|
1155
|
+
clear() {
|
|
1156
|
+
this.interceptors.length = 0;
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1159
|
+
* Get the number of interceptors
|
|
1160
|
+
*/
|
|
1161
|
+
get size() {
|
|
1162
|
+
return this.interceptors.length;
|
|
1163
|
+
}
|
|
1164
|
+
};
|
|
1165
|
+
var REACT_TO_EVENT_MAP = {
|
|
1166
|
+
// Stream Layer Events
|
|
1167
|
+
onMessageStart: "message_start",
|
|
1168
|
+
onMessageDelta: "message_delta",
|
|
1169
|
+
onMessageStop: "message_stop",
|
|
1170
|
+
onTextContentBlockStart: "text_content_block_start",
|
|
1171
|
+
onTextDelta: "text_delta",
|
|
1172
|
+
onTextContentBlockStop: "text_content_block_stop",
|
|
1173
|
+
onToolUseContentBlockStart: "tool_use_content_block_start",
|
|
1174
|
+
onInputJsonDelta: "input_json_delta",
|
|
1175
|
+
onToolUseContentBlockStop: "tool_use_content_block_stop",
|
|
1176
|
+
onToolCall: "tool_call",
|
|
1177
|
+
onToolResult: "tool_result",
|
|
1178
|
+
// Message Layer Events
|
|
1179
|
+
onUserMessage: "user_message",
|
|
1180
|
+
onAssistantMessage: "assistant_message",
|
|
1181
|
+
onToolCallMessage: "tool_call_message",
|
|
1182
|
+
onToolResultMessage: "tool_result_message",
|
|
1183
|
+
// Error Layer Events (independent, transportable via SSE)
|
|
1184
|
+
onError: "error",
|
|
1185
|
+
// Turn Layer Events
|
|
1186
|
+
onTurnRequest: "turn_request",
|
|
1187
|
+
onTurnResponse: "turn_response"
|
|
1188
|
+
};
|
|
1189
|
+
function mapReactHandlers(reactHandlers) {
|
|
1190
|
+
const eventHandlerMap = {};
|
|
1191
|
+
for (const [reactKey, eventKey] of Object.entries(REACT_TO_EVENT_MAP)) {
|
|
1192
|
+
const handler = reactHandlers[reactKey];
|
|
1193
|
+
if (handler) {
|
|
1194
|
+
eventHandlerMap[eventKey] = handler;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
return eventHandlerMap;
|
|
1198
|
+
}
|
|
1199
|
+
var logger42 = createLogger("core/AgentInstance");
|
|
1200
|
+
var AgentInstance = class {
|
|
1201
|
+
constructor(definition, context, engine, driver, sandbox) {
|
|
1202
|
+
__publicField(this, "agentId");
|
|
1203
|
+
__publicField(this, "definition");
|
|
1204
|
+
__publicField(this, "context");
|
|
1205
|
+
__publicField(this, "createdAt");
|
|
1206
|
+
__publicField(this, "sandbox");
|
|
1207
|
+
__publicField(this, "_lifecycle", "running");
|
|
1208
|
+
__publicField(this, "engine");
|
|
1209
|
+
/**
|
|
1210
|
+
* Driver instance - created from definition.driver class
|
|
1211
|
+
*/
|
|
1212
|
+
__publicField(this, "driver");
|
|
1213
|
+
/**
|
|
1214
|
+
* State machine - manages state transitions driven by StateEvents
|
|
1215
|
+
*/
|
|
1216
|
+
__publicField(this, "stateMachine", new AgentStateMachine());
|
|
1217
|
+
/**
|
|
1218
|
+
* Event bus - centralized event pub/sub
|
|
1219
|
+
*/
|
|
1220
|
+
__publicField(this, "eventBus", new AgentEventBus());
|
|
1221
|
+
/**
|
|
1222
|
+
* Error classifier - classifies and creates error events
|
|
1223
|
+
*/
|
|
1224
|
+
__publicField(this, "errorClassifier");
|
|
1225
|
+
/**
|
|
1226
|
+
* Middleware chain for receive() interception
|
|
1227
|
+
*/
|
|
1228
|
+
__publicField(this, "middlewareChain", new MiddlewareChain());
|
|
1229
|
+
/**
|
|
1230
|
+
* Interceptor chain for event dispatch interception
|
|
1231
|
+
*/
|
|
1232
|
+
__publicField(this, "interceptorChain");
|
|
1233
|
+
/**
|
|
1234
|
+
* Lifecycle handlers for onReady
|
|
1235
|
+
*/
|
|
1236
|
+
__publicField(this, "readyHandlers", /* @__PURE__ */ new Set());
|
|
1237
|
+
/**
|
|
1238
|
+
* Lifecycle handlers for onDestroy
|
|
1239
|
+
*/
|
|
1240
|
+
__publicField(this, "destroyHandlers", /* @__PURE__ */ new Set());
|
|
1241
|
+
this.agentId = context.agentId;
|
|
1242
|
+
this.definition = definition;
|
|
1243
|
+
this.context = context;
|
|
1244
|
+
this.engine = engine;
|
|
1245
|
+
this.createdAt = context.createdAt;
|
|
1246
|
+
this.sandbox = sandbox;
|
|
1247
|
+
this.driver = driver;
|
|
1248
|
+
this.errorClassifier = new AgentErrorClassifier(this.agentId);
|
|
1249
|
+
this.interceptorChain = new InterceptorChain(this.agentId);
|
|
1250
|
+
logger42.debug("AgentInstance created", {
|
|
1251
|
+
agentId: this.agentId,
|
|
1252
|
+
definitionName: definition.name,
|
|
1253
|
+
driverName: this.driver.name
|
|
1254
|
+
});
|
|
1255
|
+
}
|
|
1256
|
+
/**
|
|
1257
|
+
* Current lifecycle state
|
|
1258
|
+
*/
|
|
1259
|
+
get lifecycle() {
|
|
1260
|
+
return this._lifecycle;
|
|
1261
|
+
}
|
|
1262
|
+
/**
|
|
1263
|
+
* Current conversation state (delegated to StateMachine)
|
|
1264
|
+
*/
|
|
1265
|
+
get state() {
|
|
1266
|
+
return this.stateMachine.state;
|
|
1267
|
+
}
|
|
1268
|
+
/**
|
|
1269
|
+
* Receive a message from user
|
|
1270
|
+
*
|
|
1271
|
+
* Runs through middleware chain before actual processing.
|
|
1272
|
+
*
|
|
1273
|
+
* Error Handling:
|
|
1274
|
+
* - Errors are caught and converted to ErrorMessageEvent
|
|
1275
|
+
* - Handlers receive the error event before re-throwing
|
|
1276
|
+
* - This ensures UI can display errors
|
|
1277
|
+
*/
|
|
1278
|
+
async receive(message) {
|
|
1279
|
+
if (this._lifecycle === "destroyed") {
|
|
1280
|
+
logger42.warn("Receive called on destroyed agent", { agentId: this.agentId });
|
|
1281
|
+
const error = this.errorClassifier.create(
|
|
1282
|
+
"system",
|
|
1283
|
+
"AGENT_DESTROYED",
|
|
1284
|
+
"Agent has been destroyed",
|
|
1285
|
+
false
|
|
1286
|
+
);
|
|
1287
|
+
const errorEvent = this.errorClassifier.createEvent(error);
|
|
1288
|
+
this.notifyHandlers(errorEvent);
|
|
1289
|
+
throw new Error("[Agent] Agent has been destroyed");
|
|
1290
|
+
}
|
|
1291
|
+
if (this.state !== "idle") {
|
|
1292
|
+
logger42.warn("Receive called while agent is busy", {
|
|
1293
|
+
agentId: this.agentId,
|
|
1294
|
+
currentState: this.state
|
|
1295
|
+
});
|
|
1296
|
+
const error = this.errorClassifier.create(
|
|
1297
|
+
"system",
|
|
1298
|
+
"AGENT_BUSY",
|
|
1299
|
+
`Agent is busy (state: ${this.state}), please wait for current operation to complete`,
|
|
1300
|
+
false
|
|
1301
|
+
);
|
|
1302
|
+
const errorEvent = this.errorClassifier.createEvent(error);
|
|
1303
|
+
this.notifyHandlers(errorEvent);
|
|
1304
|
+
throw new Error(`[Agent] Agent is busy (state: ${this.state})`);
|
|
1305
|
+
}
|
|
1306
|
+
const userMessage = typeof message === "string" ? {
|
|
1307
|
+
id: `msg_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
|
|
1308
|
+
role: "user",
|
|
1309
|
+
subtype: "user",
|
|
1310
|
+
content: message,
|
|
1311
|
+
timestamp: Date.now()
|
|
1312
|
+
} : message;
|
|
1313
|
+
logger42.debug("Receiving message", {
|
|
1314
|
+
agentId: this.agentId,
|
|
1315
|
+
messageId: userMessage.id
|
|
1316
|
+
});
|
|
1317
|
+
const userMessageEvent = {
|
|
1318
|
+
uuid: `evt_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
|
|
1319
|
+
type: "user_message",
|
|
1320
|
+
agentId: this.agentId,
|
|
1321
|
+
timestamp: Date.now(),
|
|
1322
|
+
data: userMessage
|
|
1323
|
+
};
|
|
1324
|
+
this.presentOutput(userMessageEvent);
|
|
1325
|
+
this.notifyHandlers(userMessageEvent);
|
|
1326
|
+
await this.executeMiddlewareChain(userMessage);
|
|
1327
|
+
}
|
|
1328
|
+
/**
|
|
1329
|
+
* Execute middleware chain and then process the message
|
|
1330
|
+
*/
|
|
1331
|
+
async executeMiddlewareChain(message) {
|
|
1332
|
+
await this.middlewareChain.execute(message, (msg) => this.doReceive(msg));
|
|
1333
|
+
}
|
|
1334
|
+
/**
|
|
1335
|
+
* Process a single stream event through the engine
|
|
1336
|
+
*
|
|
1337
|
+
* Used by:
|
|
1338
|
+
* - doReceive() - normal message flow
|
|
1339
|
+
* - AgentInterrupter - interrupt event injection
|
|
1340
|
+
*
|
|
1341
|
+
* @param streamEvent - Stream event to process
|
|
1342
|
+
*/
|
|
1343
|
+
processStreamEvent(streamEvent) {
|
|
1344
|
+
const outputs = this.engine.process(this.agentId, streamEvent);
|
|
1345
|
+
for (const output of outputs) {
|
|
1346
|
+
this.presentOutput(output);
|
|
1347
|
+
}
|
|
1348
|
+
for (const output of outputs) {
|
|
1349
|
+
this.notifyHandlers(output);
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
/**
|
|
1353
|
+
* Actual message processing logic
|
|
1354
|
+
*
|
|
1355
|
+
* Coordinates the flow:
|
|
1356
|
+
* 1. Driver receives message → produces StreamEvents
|
|
1357
|
+
* 2. Engine processes events → produces outputs
|
|
1358
|
+
* 3. Presenters handle outputs
|
|
1359
|
+
* 4. Handlers receive outputs
|
|
1360
|
+
*/
|
|
1361
|
+
async doReceive(userMessage) {
|
|
1362
|
+
try {
|
|
1363
|
+
logger42.debug("Processing message through driver", {
|
|
1364
|
+
agentId: this.agentId,
|
|
1365
|
+
messageId: userMessage.id
|
|
1366
|
+
});
|
|
1367
|
+
const queuedEvent = {
|
|
1368
|
+
type: "conversation_queued",
|
|
1369
|
+
uuid: `${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
|
|
1370
|
+
agentId: this.agentId,
|
|
1371
|
+
timestamp: Date.now(),
|
|
1372
|
+
data: {
|
|
1373
|
+
userMessage
|
|
1374
|
+
}
|
|
1375
|
+
};
|
|
1376
|
+
this.notifyHandlers(queuedEvent);
|
|
1377
|
+
const streamEvents = this.driver.receive(userMessage);
|
|
1378
|
+
for await (const streamEvent of streamEvents) {
|
|
1379
|
+
this.processStreamEvent(streamEvent);
|
|
1380
|
+
}
|
|
1381
|
+
logger42.debug("Message processing completed", {
|
|
1382
|
+
agentId: this.agentId,
|
|
1383
|
+
messageId: userMessage.id
|
|
1384
|
+
});
|
|
1385
|
+
} catch (error) {
|
|
1386
|
+
const agentError = this.errorClassifier.classify(error);
|
|
1387
|
+
const errorEvent = this.errorClassifier.createEvent(agentError);
|
|
1388
|
+
logger42.error("Message processing failed", {
|
|
1389
|
+
agentId: this.agentId,
|
|
1390
|
+
messageId: userMessage.id,
|
|
1391
|
+
errorCategory: agentError.category,
|
|
1392
|
+
errorCode: agentError.code,
|
|
1393
|
+
error
|
|
1394
|
+
});
|
|
1395
|
+
this.notifyHandlers(errorEvent);
|
|
1396
|
+
throw error;
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
/**
|
|
1400
|
+
* Send output to all presenters
|
|
1401
|
+
*
|
|
1402
|
+
* Note: Presenters are no longer part of AgentDefinition.
|
|
1403
|
+
* This is a placeholder for future presenter injection via Runtime or middleware.
|
|
1404
|
+
*/
|
|
1405
|
+
presentOutput(_output) {
|
|
1406
|
+
}
|
|
1407
|
+
on(typeOrHandlerOrMap, handler) {
|
|
1408
|
+
if (typeof typeOrHandlerOrMap === "function") {
|
|
1409
|
+
return this.eventBus.onAny(typeOrHandlerOrMap);
|
|
1410
|
+
}
|
|
1411
|
+
if (this.isEventHandlerMap(typeOrHandlerOrMap)) {
|
|
1412
|
+
const unsubscribes = [];
|
|
1413
|
+
for (const [eventType, eventHandler] of Object.entries(typeOrHandlerOrMap)) {
|
|
1414
|
+
if (eventHandler) {
|
|
1415
|
+
unsubscribes.push(this.eventBus.on(eventType, eventHandler));
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
return () => {
|
|
1419
|
+
for (const unsub of unsubscribes) {
|
|
1420
|
+
unsub();
|
|
1421
|
+
}
|
|
1422
|
+
};
|
|
1423
|
+
}
|
|
1424
|
+
const types = Array.isArray(typeOrHandlerOrMap) ? typeOrHandlerOrMap : [typeOrHandlerOrMap];
|
|
1425
|
+
const h = handler;
|
|
1426
|
+
return this.eventBus.on(types, h);
|
|
1427
|
+
}
|
|
1428
|
+
/**
|
|
1429
|
+
* Check if the argument is an EventHandlerMap (object with event type keys)
|
|
1430
|
+
*/
|
|
1431
|
+
isEventHandlerMap(arg) {
|
|
1432
|
+
if (typeof arg !== "object" || arg === null || Array.isArray(arg)) {
|
|
1433
|
+
return false;
|
|
1434
|
+
}
|
|
1435
|
+
const keys = Object.keys(arg);
|
|
1436
|
+
if (keys.length === 0) {
|
|
1437
|
+
return false;
|
|
1438
|
+
}
|
|
1439
|
+
return keys.every((key) => {
|
|
1440
|
+
const value = arg[key];
|
|
1441
|
+
return value === void 0 || typeof value === "function";
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
/**
|
|
1445
|
+
* Subscribe to state changes (delegated to StateMachine)
|
|
1446
|
+
*
|
|
1447
|
+
* @param handler - Callback receiving { prev, current } state change
|
|
1448
|
+
* @returns Unsubscribe function
|
|
1449
|
+
*/
|
|
1450
|
+
onStateChange(handler) {
|
|
1451
|
+
return this.stateMachine.onStateChange(handler);
|
|
1452
|
+
}
|
|
1453
|
+
/**
|
|
1454
|
+
* React-style fluent event subscription
|
|
1455
|
+
*
|
|
1456
|
+
* Converts onXxx handlers to event type keys and delegates to on(handlers)
|
|
1457
|
+
*/
|
|
1458
|
+
react(handlers) {
|
|
1459
|
+
const eventHandlerMap = mapReactHandlers(handlers);
|
|
1460
|
+
return this.on(eventHandlerMap);
|
|
1461
|
+
}
|
|
1462
|
+
/**
|
|
1463
|
+
* Subscribe to agent ready event
|
|
1464
|
+
*
|
|
1465
|
+
* If already running, handler is called immediately.
|
|
1466
|
+
*/
|
|
1467
|
+
onReady(handler) {
|
|
1468
|
+
if (this._lifecycle === "running") {
|
|
1469
|
+
try {
|
|
1470
|
+
handler();
|
|
1471
|
+
} catch (error) {
|
|
1472
|
+
logger42.error("onReady handler error", {
|
|
1473
|
+
agentId: this.agentId,
|
|
1474
|
+
error
|
|
1475
|
+
});
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
this.readyHandlers.add(handler);
|
|
1479
|
+
return () => {
|
|
1480
|
+
this.readyHandlers.delete(handler);
|
|
1481
|
+
};
|
|
1482
|
+
}
|
|
1483
|
+
/**
|
|
1484
|
+
* Subscribe to agent destroy event
|
|
1485
|
+
*/
|
|
1486
|
+
onDestroy(handler) {
|
|
1487
|
+
this.destroyHandlers.add(handler);
|
|
1488
|
+
return () => {
|
|
1489
|
+
this.destroyHandlers.delete(handler);
|
|
1490
|
+
};
|
|
1491
|
+
}
|
|
1492
|
+
/**
|
|
1493
|
+
* Add middleware to intercept incoming messages
|
|
1494
|
+
*/
|
|
1495
|
+
use(middleware) {
|
|
1496
|
+
return this.middlewareChain.use(middleware);
|
|
1497
|
+
}
|
|
1498
|
+
/**
|
|
1499
|
+
* Add interceptor to intercept outgoing events
|
|
1500
|
+
*/
|
|
1501
|
+
intercept(interceptor) {
|
|
1502
|
+
return this.interceptorChain.intercept(interceptor);
|
|
1503
|
+
}
|
|
1504
|
+
/**
|
|
1505
|
+
* Interrupt - User-initiated stop
|
|
1506
|
+
*
|
|
1507
|
+
* Stops the current operation gracefully.
|
|
1508
|
+
* Flow:
|
|
1509
|
+
* 1. Call driver.interrupt() to abort active requests
|
|
1510
|
+
* 2. Driver yields InterruptedStreamEvent
|
|
1511
|
+
* 3. Event flows through engine pipeline
|
|
1512
|
+
* 4. StateEventProcessor generates conversation_interrupted
|
|
1513
|
+
* 5. StateMachine transitions to idle state
|
|
1514
|
+
* 6. UI receives state change notification
|
|
1515
|
+
*/
|
|
1516
|
+
interrupt() {
|
|
1517
|
+
logger42.debug("User interrupt requested", { agentId: this.agentId, currentState: this.state });
|
|
1518
|
+
this.driver.interrupt();
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* Destroy - Clean up resources
|
|
1522
|
+
*/
|
|
1523
|
+
async destroy() {
|
|
1524
|
+
logger42.debug("Destroying agent", { agentId: this.agentId });
|
|
1525
|
+
for (const handler of this.destroyHandlers) {
|
|
1526
|
+
try {
|
|
1527
|
+
handler();
|
|
1528
|
+
} catch (error) {
|
|
1529
|
+
logger42.error("onDestroy handler error", {
|
|
1530
|
+
agentId: this.agentId,
|
|
1531
|
+
error
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
this._lifecycle = "destroyed";
|
|
1536
|
+
this.stateMachine.reset();
|
|
1537
|
+
this.eventBus.destroy();
|
|
1538
|
+
this.readyHandlers.clear();
|
|
1539
|
+
this.destroyHandlers.clear();
|
|
1540
|
+
this.middlewareChain.clear();
|
|
1541
|
+
this.interceptorChain.clear();
|
|
1542
|
+
this.engine.clearState(this.agentId);
|
|
1543
|
+
logger42.info("Agent destroyed", { agentId: this.agentId });
|
|
1544
|
+
}
|
|
1545
|
+
/**
|
|
1546
|
+
* Notify all registered handlers
|
|
1547
|
+
*
|
|
1548
|
+
* Flow:
|
|
1549
|
+
* 1. StateMachine processes StateEvents (for state transitions)
|
|
1550
|
+
* 2. Interceptor chain can modify/filter events
|
|
1551
|
+
* 3. EventBus emits to all subscribers
|
|
1552
|
+
*/
|
|
1553
|
+
notifyHandlers(event) {
|
|
1554
|
+
if (isStateEvent(event)) {
|
|
1555
|
+
this.stateMachine.process(event);
|
|
1556
|
+
}
|
|
1557
|
+
this.executeInterceptorChain(event);
|
|
1558
|
+
}
|
|
1559
|
+
/**
|
|
1560
|
+
* Execute interceptor chain and then emit to EventBus
|
|
1561
|
+
*/
|
|
1562
|
+
executeInterceptorChain(event) {
|
|
1563
|
+
this.interceptorChain.execute(event, (e) => this.eventBus.emit(e));
|
|
1564
|
+
}
|
|
1565
|
+
/**
|
|
1566
|
+
* Get the event consumer for external subscriptions
|
|
1567
|
+
*
|
|
1568
|
+
* Use this to expose event subscription without emit capability.
|
|
1569
|
+
*/
|
|
1570
|
+
getEventConsumer() {
|
|
1571
|
+
return this.eventBus.asConsumer();
|
|
1572
|
+
}
|
|
1573
|
+
};
|
|
1574
|
+
|
|
1575
|
+
// ../engine/dist/index.js
|
|
1576
|
+
var MemoryStore = class {
|
|
1577
|
+
constructor() {
|
|
1578
|
+
__publicField(this, "states", /* @__PURE__ */ new Map());
|
|
1579
|
+
}
|
|
1580
|
+
get(id) {
|
|
1581
|
+
return this.states.get(id);
|
|
1582
|
+
}
|
|
1583
|
+
set(id, state) {
|
|
1584
|
+
this.states.set(id, state);
|
|
1585
|
+
}
|
|
1586
|
+
delete(id) {
|
|
1587
|
+
this.states.delete(id);
|
|
1588
|
+
}
|
|
1589
|
+
has(id) {
|
|
1590
|
+
return this.states.has(id);
|
|
1591
|
+
}
|
|
1592
|
+
/**
|
|
1593
|
+
* Clear all stored states
|
|
1594
|
+
*/
|
|
1595
|
+
clear() {
|
|
1596
|
+
this.states.clear();
|
|
1597
|
+
}
|
|
1598
|
+
/**
|
|
1599
|
+
* Get the number of stored states
|
|
1600
|
+
*/
|
|
1601
|
+
get size() {
|
|
1602
|
+
return this.states.size;
|
|
1603
|
+
}
|
|
1604
|
+
/**
|
|
1605
|
+
* Get all stored IDs
|
|
1606
|
+
*/
|
|
1607
|
+
keys() {
|
|
1608
|
+
return this.states.keys();
|
|
1609
|
+
}
|
|
1610
|
+
};
|
|
1611
|
+
createLogger("engine/Mealy");
|
|
1612
|
+
function combineProcessors(processors) {
|
|
1613
|
+
return (state, event) => {
|
|
1614
|
+
const newState = {};
|
|
1615
|
+
const allOutputs = [];
|
|
1616
|
+
for (const key in processors) {
|
|
1617
|
+
const processor = processors[key];
|
|
1618
|
+
const subState = state[key];
|
|
1619
|
+
const [newSubState, outputs] = processor(subState, event);
|
|
1620
|
+
newState[key] = newSubState;
|
|
1621
|
+
allOutputs.push(...outputs);
|
|
1622
|
+
}
|
|
1623
|
+
return [newState, allOutputs];
|
|
1624
|
+
};
|
|
1625
|
+
}
|
|
1626
|
+
function combineInitialStates(initialStates) {
|
|
1627
|
+
return () => {
|
|
1628
|
+
const state = {};
|
|
1629
|
+
for (const key in initialStates) {
|
|
1630
|
+
state[key] = initialStates[key]();
|
|
1631
|
+
}
|
|
1632
|
+
return state;
|
|
1633
|
+
};
|
|
1634
|
+
}
|
|
1635
|
+
function createInitialMessageAssemblerState() {
|
|
1636
|
+
return {
|
|
1637
|
+
currentMessageId: null,
|
|
1638
|
+
messageStartTime: null,
|
|
1639
|
+
pendingContents: {},
|
|
1640
|
+
pendingToolCalls: {}
|
|
1641
|
+
};
|
|
1642
|
+
}
|
|
1643
|
+
function generateId() {
|
|
1644
|
+
return `msg_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
1645
|
+
}
|
|
1646
|
+
var messageAssemblerProcessor = (state, input) => {
|
|
1647
|
+
switch (input.type) {
|
|
1648
|
+
case "message_start":
|
|
1649
|
+
return handleMessageStart(state, input);
|
|
1650
|
+
case "text_delta":
|
|
1651
|
+
return handleTextDelta(state, input);
|
|
1652
|
+
case "tool_use_content_block_start":
|
|
1653
|
+
return handleToolUseContentBlockStart(state, input);
|
|
1654
|
+
case "input_json_delta":
|
|
1655
|
+
return handleInputJsonDelta(state, input);
|
|
1656
|
+
case "tool_use_content_block_stop":
|
|
1657
|
+
return handleToolUseContentBlockStop(state, input);
|
|
1658
|
+
case "tool_result":
|
|
1659
|
+
return handleToolResult(state, input);
|
|
1660
|
+
case "message_stop":
|
|
1661
|
+
return handleMessageStop(state, input);
|
|
1662
|
+
default:
|
|
1663
|
+
return [state, []];
|
|
1664
|
+
}
|
|
1665
|
+
};
|
|
1666
|
+
function handleMessageStart(state, event) {
|
|
1667
|
+
return [
|
|
1668
|
+
{
|
|
1669
|
+
...state,
|
|
1670
|
+
currentMessageId: generateId(),
|
|
1671
|
+
messageStartTime: event.timestamp,
|
|
1672
|
+
pendingContents: {}
|
|
1673
|
+
},
|
|
1674
|
+
[]
|
|
1675
|
+
];
|
|
1676
|
+
}
|
|
1677
|
+
function handleTextDelta(state, event) {
|
|
1678
|
+
const index = 0;
|
|
1679
|
+
const existingContent = state.pendingContents[index];
|
|
1680
|
+
const pendingContent = existingContent?.type === "text" ? {
|
|
1681
|
+
...existingContent,
|
|
1682
|
+
textDeltas: [...existingContent.textDeltas || [], event.data.text]
|
|
1683
|
+
} : {
|
|
1684
|
+
type: "text",
|
|
1685
|
+
index,
|
|
1686
|
+
textDeltas: [event.data.text]
|
|
1687
|
+
};
|
|
1688
|
+
return [
|
|
1689
|
+
{
|
|
1690
|
+
...state,
|
|
1691
|
+
pendingContents: {
|
|
1692
|
+
...state.pendingContents,
|
|
1693
|
+
[index]: pendingContent
|
|
1694
|
+
}
|
|
1695
|
+
},
|
|
1696
|
+
[]
|
|
1697
|
+
];
|
|
1698
|
+
}
|
|
1699
|
+
function handleToolUseContentBlockStart(state, event) {
|
|
1700
|
+
const index = 1;
|
|
1701
|
+
const pendingContent = {
|
|
1702
|
+
type: "tool_use",
|
|
1703
|
+
index,
|
|
1704
|
+
toolId: event.data.id,
|
|
1705
|
+
toolName: event.data.name,
|
|
1706
|
+
toolInputJson: ""
|
|
1707
|
+
};
|
|
1708
|
+
return [
|
|
1709
|
+
{
|
|
1710
|
+
...state,
|
|
1711
|
+
pendingContents: {
|
|
1712
|
+
...state.pendingContents,
|
|
1713
|
+
[index]: pendingContent
|
|
1714
|
+
}
|
|
1715
|
+
},
|
|
1716
|
+
[]
|
|
1717
|
+
];
|
|
1718
|
+
}
|
|
1719
|
+
function handleInputJsonDelta(state, event) {
|
|
1720
|
+
const index = 1;
|
|
1721
|
+
const existingContent = state.pendingContents[index];
|
|
1722
|
+
if (!existingContent || existingContent.type !== "tool_use") {
|
|
1723
|
+
return [state, []];
|
|
1724
|
+
}
|
|
1725
|
+
const pendingContent = {
|
|
1726
|
+
...existingContent,
|
|
1727
|
+
toolInputJson: (existingContent.toolInputJson || "") + event.data.partialJson
|
|
1728
|
+
};
|
|
1729
|
+
return [
|
|
1730
|
+
{
|
|
1731
|
+
...state,
|
|
1732
|
+
pendingContents: {
|
|
1733
|
+
...state.pendingContents,
|
|
1734
|
+
[index]: pendingContent
|
|
1735
|
+
}
|
|
1736
|
+
},
|
|
1737
|
+
[]
|
|
1738
|
+
];
|
|
1739
|
+
}
|
|
1740
|
+
function handleToolUseContentBlockStop(state, event) {
|
|
1741
|
+
const index = 1;
|
|
1742
|
+
const pendingContent = state.pendingContents[index];
|
|
1743
|
+
if (!pendingContent || pendingContent.type !== "tool_use") {
|
|
1744
|
+
return [state, []];
|
|
1745
|
+
}
|
|
1746
|
+
let toolInput = {};
|
|
1747
|
+
try {
|
|
1748
|
+
toolInput = pendingContent.toolInputJson ? JSON.parse(pendingContent.toolInputJson) : {};
|
|
1749
|
+
} catch {
|
|
1750
|
+
toolInput = {};
|
|
1751
|
+
}
|
|
1752
|
+
const outputs = [];
|
|
1753
|
+
const toolId = pendingContent.toolId;
|
|
1754
|
+
const toolName = pendingContent.toolName;
|
|
1755
|
+
const toolCallEvent = {
|
|
1756
|
+
type: "tool_call",
|
|
1757
|
+
uuid: generateId(),
|
|
1758
|
+
agentId: event.agentId,
|
|
1759
|
+
timestamp: Date.now(),
|
|
1760
|
+
data: {
|
|
1761
|
+
id: toolId,
|
|
1762
|
+
name: toolName,
|
|
1763
|
+
input: toolInput
|
|
1764
|
+
}
|
|
1765
|
+
};
|
|
1766
|
+
outputs.push(toolCallEvent);
|
|
1767
|
+
const toolCall = {
|
|
1768
|
+
type: "tool-call",
|
|
1769
|
+
id: toolId,
|
|
1770
|
+
name: toolName,
|
|
1771
|
+
input: toolInput
|
|
1772
|
+
};
|
|
1773
|
+
const toolCallMessage = {
|
|
1774
|
+
id: generateId(),
|
|
1775
|
+
role: "assistant",
|
|
1776
|
+
subtype: "tool-call",
|
|
1777
|
+
toolCall,
|
|
1778
|
+
timestamp: Date.now()
|
|
1779
|
+
};
|
|
1780
|
+
const toolCallMessageEvent = {
|
|
1781
|
+
type: "tool_call_message",
|
|
1782
|
+
uuid: generateId(),
|
|
1783
|
+
agentId: event.agentId,
|
|
1784
|
+
timestamp: Date.now(),
|
|
1785
|
+
data: toolCallMessage
|
|
1786
|
+
};
|
|
1787
|
+
outputs.push(toolCallMessageEvent);
|
|
1788
|
+
const { [index]: _, ...remainingContents } = state.pendingContents;
|
|
1789
|
+
return [
|
|
1790
|
+
{
|
|
1791
|
+
...state,
|
|
1792
|
+
pendingContents: remainingContents,
|
|
1793
|
+
pendingToolCalls: {
|
|
1794
|
+
...state.pendingToolCalls,
|
|
1795
|
+
[toolId]: { id: toolId, name: toolName }
|
|
1796
|
+
}
|
|
1797
|
+
},
|
|
1798
|
+
outputs
|
|
1799
|
+
];
|
|
1800
|
+
}
|
|
1801
|
+
function handleToolResult(state, event) {
|
|
1802
|
+
const { toolId, content, isError } = event.data;
|
|
1803
|
+
const pendingToolCall = state.pendingToolCalls[toolId];
|
|
1804
|
+
const toolName = pendingToolCall?.name || "unknown";
|
|
1805
|
+
const toolResult = {
|
|
1806
|
+
type: "tool-result",
|
|
1807
|
+
id: toolId,
|
|
1808
|
+
name: toolName,
|
|
1809
|
+
output: {
|
|
1810
|
+
type: isError ? "error-text" : "text",
|
|
1811
|
+
value: typeof content === "string" ? content : JSON.stringify(content)
|
|
1812
|
+
}
|
|
1813
|
+
};
|
|
1814
|
+
const toolResultMessage = {
|
|
1815
|
+
id: generateId(),
|
|
1816
|
+
role: "tool",
|
|
1817
|
+
subtype: "tool-result",
|
|
1818
|
+
toolResult,
|
|
1819
|
+
toolCallId: toolId,
|
|
1820
|
+
timestamp: Date.now()
|
|
1821
|
+
};
|
|
1822
|
+
const toolResultMessageEvent = {
|
|
1823
|
+
type: "tool_result_message",
|
|
1824
|
+
uuid: generateId(),
|
|
1825
|
+
agentId: event.agentId,
|
|
1826
|
+
timestamp: Date.now(),
|
|
1827
|
+
data: toolResultMessage
|
|
1828
|
+
};
|
|
1829
|
+
const { [toolId]: _, ...remainingToolCalls } = state.pendingToolCalls;
|
|
1830
|
+
return [
|
|
1831
|
+
{
|
|
1832
|
+
...state,
|
|
1833
|
+
pendingToolCalls: remainingToolCalls
|
|
1834
|
+
},
|
|
1835
|
+
[toolResultMessageEvent]
|
|
1836
|
+
];
|
|
1837
|
+
}
|
|
1838
|
+
function handleMessageStop(state, event) {
|
|
1839
|
+
if (!state.currentMessageId) {
|
|
1840
|
+
return [state, []];
|
|
1841
|
+
}
|
|
1842
|
+
const textParts = [];
|
|
1843
|
+
const sortedContents = Object.values(state.pendingContents).sort((a, b) => a.index - b.index);
|
|
1844
|
+
for (const pending of sortedContents) {
|
|
1845
|
+
if (pending.type === "text" && pending.textDeltas) {
|
|
1846
|
+
textParts.push(pending.textDeltas.join(""));
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
const content = textParts.join("");
|
|
1850
|
+
const stopReason = event.data.stopReason;
|
|
1851
|
+
if (!content || content.trim().length === 0) {
|
|
1852
|
+
const shouldPreserveToolCalls2 = stopReason === "tool_use";
|
|
1853
|
+
return [
|
|
1854
|
+
{
|
|
1855
|
+
...createInitialMessageAssemblerState(),
|
|
1856
|
+
pendingToolCalls: shouldPreserveToolCalls2 ? state.pendingToolCalls : {}
|
|
1857
|
+
},
|
|
1858
|
+
[]
|
|
1859
|
+
];
|
|
1860
|
+
}
|
|
1861
|
+
const assistantMessage = {
|
|
1862
|
+
id: state.currentMessageId,
|
|
1863
|
+
role: "assistant",
|
|
1864
|
+
subtype: "assistant",
|
|
1865
|
+
content,
|
|
1866
|
+
timestamp: state.messageStartTime || Date.now(),
|
|
1867
|
+
// Usage data is not available in message_stop event
|
|
1868
|
+
// It would need to be tracked separately if needed
|
|
1869
|
+
usage: void 0
|
|
1870
|
+
};
|
|
1871
|
+
const assistantEvent = {
|
|
1872
|
+
type: "assistant_message",
|
|
1873
|
+
uuid: generateId(),
|
|
1874
|
+
agentId: event.agentId,
|
|
1875
|
+
timestamp: Date.now(),
|
|
1876
|
+
data: assistantMessage
|
|
1877
|
+
};
|
|
1878
|
+
const shouldPreserveToolCalls = stopReason === "tool_use";
|
|
1879
|
+
return [
|
|
1880
|
+
{
|
|
1881
|
+
...createInitialMessageAssemblerState(),
|
|
1882
|
+
pendingToolCalls: shouldPreserveToolCalls ? state.pendingToolCalls : {}
|
|
1883
|
+
},
|
|
1884
|
+
[assistantEvent]
|
|
1885
|
+
];
|
|
1886
|
+
}
|
|
1887
|
+
var logger23 = createLogger("engine/stateEventProcessor");
|
|
1888
|
+
function createInitialStateEventProcessorContext() {
|
|
1889
|
+
return {};
|
|
1890
|
+
}
|
|
1891
|
+
function generateId2() {
|
|
1892
|
+
return `state_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
1893
|
+
}
|
|
1894
|
+
var stateEventProcessor = (context, input) => {
|
|
1895
|
+
logger23.debug(`[Stream Event] ${input.type}`, {
|
|
1896
|
+
context,
|
|
1897
|
+
eventData: "data" in input ? input.data : void 0
|
|
1898
|
+
});
|
|
1899
|
+
switch (input.type) {
|
|
1900
|
+
case "message_start":
|
|
1901
|
+
return handleMessageStart2(context, input);
|
|
1902
|
+
case "message_delta":
|
|
1903
|
+
return handleMessageDelta(context);
|
|
1904
|
+
case "message_stop":
|
|
1905
|
+
return handleMessageStop2(context, input);
|
|
1906
|
+
case "text_content_block_start":
|
|
1907
|
+
return handleTextContentBlockStart(context, input);
|
|
1908
|
+
case "tool_use_content_block_start":
|
|
1909
|
+
return handleToolUseContentBlockStart2(context, input);
|
|
1910
|
+
case "tool_use_content_block_stop":
|
|
1911
|
+
return handleToolUseContentBlockStop2(context);
|
|
1912
|
+
case "tool_call":
|
|
1913
|
+
return handleToolCall(context);
|
|
1914
|
+
case "interrupted":
|
|
1915
|
+
return handleInterrupted(context, input);
|
|
1916
|
+
default:
|
|
1917
|
+
logger23.debug(`[Stream Event] ${input.type} (unhandled)`);
|
|
1918
|
+
return [context, []];
|
|
1919
|
+
}
|
|
1920
|
+
};
|
|
1921
|
+
function handleMessageStart2(context, event) {
|
|
1922
|
+
const conversationStartEvent = {
|
|
1923
|
+
type: "conversation_start",
|
|
1924
|
+
uuid: generateId2(),
|
|
1925
|
+
agentId: event.agentId,
|
|
1926
|
+
timestamp: event.timestamp,
|
|
1927
|
+
transition: {
|
|
1928
|
+
reason: "conversation_started",
|
|
1929
|
+
trigger: "message_start"
|
|
1930
|
+
},
|
|
1931
|
+
data: {
|
|
1932
|
+
userMessage: {}
|
|
1933
|
+
// Will be populated by higher-level component
|
|
1934
|
+
}
|
|
1935
|
+
};
|
|
1936
|
+
return [context, [conversationStartEvent]];
|
|
1937
|
+
}
|
|
1938
|
+
function handleMessageDelta(context, _event) {
|
|
1939
|
+
return [context, []];
|
|
1940
|
+
}
|
|
1941
|
+
function handleMessageStop2(context, event) {
|
|
1942
|
+
const stopReason = event.data.stopReason;
|
|
1943
|
+
logger23.debug("message_stop received", { stopReason });
|
|
1944
|
+
if (stopReason === "tool_use") {
|
|
1945
|
+
logger23.debug("Skipping conversation_end (tool_use in progress)");
|
|
1946
|
+
return [context, []];
|
|
1947
|
+
}
|
|
1948
|
+
const conversationEndEvent = {
|
|
1949
|
+
type: "conversation_end",
|
|
1950
|
+
uuid: generateId2(),
|
|
1951
|
+
agentId: event.agentId,
|
|
1952
|
+
timestamp: event.timestamp,
|
|
1953
|
+
transition: {
|
|
1954
|
+
reason: "conversation_completed",
|
|
1955
|
+
trigger: "message_stop"
|
|
1956
|
+
},
|
|
1957
|
+
data: {
|
|
1958
|
+
assistantMessage: {},
|
|
1959
|
+
// Will be populated by higher-level component
|
|
1960
|
+
durationMs: 0,
|
|
1961
|
+
// Will be calculated by StateMachine or TurnTracker
|
|
1962
|
+
durationApiMs: 0,
|
|
1963
|
+
numTurns: 0,
|
|
1964
|
+
result: "completed",
|
|
1965
|
+
totalCostUsd: 0,
|
|
1966
|
+
usage: {
|
|
1967
|
+
input: 0,
|
|
1968
|
+
output: 0
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
};
|
|
1972
|
+
return [context, [conversationEndEvent]];
|
|
1973
|
+
}
|
|
1974
|
+
function handleTextContentBlockStart(context, event) {
|
|
1975
|
+
const respondingEvent = {
|
|
1976
|
+
type: "conversation_responding",
|
|
1977
|
+
uuid: generateId2(),
|
|
1978
|
+
agentId: event.agentId,
|
|
1979
|
+
timestamp: Date.now(),
|
|
1980
|
+
transition: {
|
|
1981
|
+
reason: "assistant_responding",
|
|
1982
|
+
trigger: "text_content_block_start"
|
|
1983
|
+
},
|
|
1984
|
+
data: {}
|
|
1985
|
+
};
|
|
1986
|
+
return [context, [respondingEvent]];
|
|
1987
|
+
}
|
|
1988
|
+
function handleToolUseContentBlockStart2(context, event) {
|
|
1989
|
+
const outputs = [];
|
|
1990
|
+
const toolPlannedEvent = {
|
|
1991
|
+
type: "tool_planned",
|
|
1992
|
+
uuid: generateId2(),
|
|
1993
|
+
agentId: event.agentId,
|
|
1994
|
+
timestamp: event.timestamp,
|
|
1995
|
+
data: {
|
|
1996
|
+
id: event.data.id,
|
|
1997
|
+
name: event.data.name,
|
|
1998
|
+
input: {}
|
|
1999
|
+
}
|
|
2000
|
+
};
|
|
2001
|
+
outputs.push(toolPlannedEvent);
|
|
2002
|
+
const toolExecutingEvent = {
|
|
2003
|
+
type: "tool_executing",
|
|
2004
|
+
uuid: generateId2(),
|
|
2005
|
+
agentId: event.agentId,
|
|
2006
|
+
timestamp: event.timestamp,
|
|
2007
|
+
transition: {
|
|
2008
|
+
reason: "tool_planning_started",
|
|
2009
|
+
trigger: "tool_use_content_block_start"
|
|
2010
|
+
},
|
|
2011
|
+
data: {}
|
|
2012
|
+
};
|
|
2013
|
+
outputs.push(toolExecutingEvent);
|
|
2014
|
+
return [context, outputs];
|
|
2015
|
+
}
|
|
2016
|
+
function handleToolUseContentBlockStop2(context, _event) {
|
|
2017
|
+
return [context, []];
|
|
2018
|
+
}
|
|
2019
|
+
function handleToolCall(context, _event) {
|
|
2020
|
+
return [context, []];
|
|
2021
|
+
}
|
|
2022
|
+
function handleInterrupted(context, event) {
|
|
2023
|
+
logger23.debug("interrupted event received", { reason: event.data.reason });
|
|
2024
|
+
const conversationInterruptedEvent = {
|
|
2025
|
+
type: "conversation_interrupted",
|
|
2026
|
+
uuid: generateId2(),
|
|
2027
|
+
agentId: event.agentId,
|
|
2028
|
+
timestamp: event.timestamp,
|
|
2029
|
+
transition: {
|
|
2030
|
+
reason: event.data.reason,
|
|
2031
|
+
trigger: "interrupted"
|
|
2032
|
+
},
|
|
2033
|
+
data: {
|
|
2034
|
+
reason: event.data.reason
|
|
2035
|
+
}
|
|
2036
|
+
};
|
|
2037
|
+
return [context, [conversationInterruptedEvent]];
|
|
2038
|
+
}
|
|
2039
|
+
function createInitialTurnTrackerState() {
|
|
2040
|
+
return {
|
|
2041
|
+
pendingTurn: null,
|
|
2042
|
+
costPerInputToken: 3e-6,
|
|
2043
|
+
// $3 per 1M tokens
|
|
2044
|
+
costPerOutputToken: 15e-6
|
|
2045
|
+
// $15 per 1M tokens
|
|
2046
|
+
};
|
|
2047
|
+
}
|
|
2048
|
+
function generateId3() {
|
|
2049
|
+
return `turn_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
2050
|
+
}
|
|
2051
|
+
function calculateCost(usage, costPerInputToken, costPerOutputToken) {
|
|
2052
|
+
const inputCost = usage.input * costPerInputToken;
|
|
2053
|
+
const outputCost = usage.output * costPerOutputToken;
|
|
2054
|
+
return inputCost + outputCost;
|
|
2055
|
+
}
|
|
2056
|
+
var turnTrackerProcessor = (state, input) => {
|
|
2057
|
+
switch (input.type) {
|
|
2058
|
+
case "user_message":
|
|
2059
|
+
return handleUserMessage(state, input);
|
|
2060
|
+
case "message_stop":
|
|
2061
|
+
return handleMessageStop3(state, input);
|
|
2062
|
+
case "assistant_message":
|
|
2063
|
+
return [state, []];
|
|
2064
|
+
default:
|
|
2065
|
+
return [state, []];
|
|
2066
|
+
}
|
|
2067
|
+
};
|
|
2068
|
+
function handleUserMessage(state, event) {
|
|
2069
|
+
const turnId = generateId3();
|
|
2070
|
+
const pendingTurn = {
|
|
2071
|
+
turnId,
|
|
2072
|
+
userMessage: event.data,
|
|
2073
|
+
requestedAt: event.timestamp
|
|
2074
|
+
};
|
|
2075
|
+
const turnRequestEvent = {
|
|
2076
|
+
type: "turn_request",
|
|
2077
|
+
uuid: generateId3(),
|
|
2078
|
+
agentId: event.agentId,
|
|
2079
|
+
timestamp: Date.now(),
|
|
2080
|
+
turnId,
|
|
2081
|
+
data: {
|
|
2082
|
+
userMessage: event.data,
|
|
2083
|
+
requestedAt: event.timestamp
|
|
2084
|
+
}
|
|
2085
|
+
};
|
|
2086
|
+
return [
|
|
2087
|
+
{
|
|
2088
|
+
...state,
|
|
2089
|
+
pendingTurn
|
|
2090
|
+
},
|
|
2091
|
+
[turnRequestEvent]
|
|
2092
|
+
];
|
|
2093
|
+
}
|
|
2094
|
+
function handleMessageStop3(state, event) {
|
|
2095
|
+
if (!state.pendingTurn) {
|
|
2096
|
+
return [state, []];
|
|
2097
|
+
}
|
|
2098
|
+
const stopReason = event.data.stopReason;
|
|
2099
|
+
if (stopReason === "end_turn" || stopReason === "max_tokens" || stopReason === "stop_sequence") {
|
|
2100
|
+
return completeTurn(state, event.agentId, event.timestamp);
|
|
2101
|
+
}
|
|
2102
|
+
return [state, []];
|
|
2103
|
+
}
|
|
2104
|
+
function completeTurn(state, agentId, completedAt) {
|
|
2105
|
+
if (!state.pendingTurn) {
|
|
2106
|
+
return [state, []];
|
|
2107
|
+
}
|
|
2108
|
+
const { turnId, requestedAt } = state.pendingTurn;
|
|
2109
|
+
const duration = completedAt - requestedAt;
|
|
2110
|
+
const usage = { input: 0, output: 0 };
|
|
2111
|
+
const cost = calculateCost(usage, state.costPerInputToken, state.costPerOutputToken);
|
|
2112
|
+
const turnResponseEvent = {
|
|
2113
|
+
type: "turn_response",
|
|
2114
|
+
uuid: generateId3(),
|
|
2115
|
+
agentId,
|
|
2116
|
+
timestamp: Date.now(),
|
|
2117
|
+
turnId,
|
|
2118
|
+
data: {
|
|
2119
|
+
assistantMessage: {
|
|
2120
|
+
id: generateId3(),
|
|
2121
|
+
role: "assistant",
|
|
2122
|
+
subtype: "assistant",
|
|
2123
|
+
content: "",
|
|
2124
|
+
timestamp: completedAt
|
|
2125
|
+
},
|
|
2126
|
+
respondedAt: completedAt,
|
|
2127
|
+
durationMs: duration,
|
|
2128
|
+
usage,
|
|
2129
|
+
costUsd: cost
|
|
2130
|
+
}
|
|
2131
|
+
};
|
|
2132
|
+
return [
|
|
2133
|
+
{
|
|
2134
|
+
...state,
|
|
2135
|
+
pendingTurn: null
|
|
2136
|
+
},
|
|
2137
|
+
[turnResponseEvent]
|
|
2138
|
+
];
|
|
2139
|
+
}
|
|
2140
|
+
var agentProcessor = combineProcessors({
|
|
2141
|
+
messageAssembler: messageAssemblerProcessor,
|
|
2142
|
+
stateEventProcessor,
|
|
2143
|
+
turnTracker: turnTrackerProcessor
|
|
2144
|
+
});
|
|
2145
|
+
var createInitialAgentEngineState = combineInitialStates({
|
|
2146
|
+
messageAssembler: createInitialMessageAssemblerState,
|
|
2147
|
+
stateEventProcessor: createInitialStateEventProcessorContext,
|
|
2148
|
+
turnTracker: createInitialTurnTrackerState
|
|
2149
|
+
});
|
|
2150
|
+
var logger33 = createLogger("engine/AgentEngine");
|
|
2151
|
+
var AgentEngine = class {
|
|
2152
|
+
constructor() {
|
|
2153
|
+
__publicField(this, "store");
|
|
2154
|
+
this.store = new MemoryStore();
|
|
2155
|
+
logger33.debug("AgentEngine initialized");
|
|
2156
|
+
}
|
|
2157
|
+
/**
|
|
2158
|
+
* Process a single stream event and return output events
|
|
2159
|
+
*
|
|
2160
|
+
* This is the core Mealy Machine operation:
|
|
2161
|
+
* process(agentId, event) → outputs[]
|
|
2162
|
+
*
|
|
2163
|
+
* @param agentId - The agent identifier (for state isolation)
|
|
2164
|
+
* @param event - Stream event to process
|
|
2165
|
+
* @returns Array of output events (state, message, turn events)
|
|
2166
|
+
*/
|
|
2167
|
+
process(agentId, event) {
|
|
2168
|
+
const eventType = event.type || "unknown";
|
|
2169
|
+
logger33.debug("Processing event", { agentId, eventType });
|
|
2170
|
+
const isNewState = !this.store.has(agentId);
|
|
2171
|
+
let state = this.store.get(agentId) ?? createInitialAgentEngineState();
|
|
2172
|
+
if (isNewState) {
|
|
2173
|
+
logger33.debug("Created initial state for agent", { agentId });
|
|
2174
|
+
}
|
|
2175
|
+
const allOutputs = [];
|
|
2176
|
+
allOutputs.push(event);
|
|
2177
|
+
const [newState, outputs] = agentProcessor(state, event);
|
|
2178
|
+
state = newState;
|
|
2179
|
+
for (const output of outputs) {
|
|
2180
|
+
allOutputs.push(output);
|
|
2181
|
+
const [chainedState, chainedOutputs] = this.processChained(state, output);
|
|
2182
|
+
state = chainedState;
|
|
2183
|
+
allOutputs.push(...chainedOutputs);
|
|
2184
|
+
}
|
|
2185
|
+
this.store.set(agentId, state);
|
|
2186
|
+
if (outputs.length > 0) {
|
|
2187
|
+
logger33.debug("Produced outputs", {
|
|
2188
|
+
agentId,
|
|
2189
|
+
inputEvent: eventType,
|
|
2190
|
+
outputCount: allOutputs.length,
|
|
2191
|
+
processorOutputs: outputs.length
|
|
2192
|
+
});
|
|
2193
|
+
}
|
|
2194
|
+
return allOutputs;
|
|
2195
|
+
}
|
|
2196
|
+
/**
|
|
2197
|
+
* Process chained events recursively
|
|
2198
|
+
*
|
|
2199
|
+
* Some processors produce events that trigger other processors:
|
|
2200
|
+
* - MessageAssembler produces MessageEvents
|
|
2201
|
+
* - TurnTracker consumes MessageEvents to produce TurnEvents
|
|
2202
|
+
*/
|
|
2203
|
+
processChained(state, event) {
|
|
2204
|
+
const [newState, outputs] = agentProcessor(state, event);
|
|
2205
|
+
if (outputs.length === 0) {
|
|
2206
|
+
return [newState, []];
|
|
2207
|
+
}
|
|
2208
|
+
const allOutputs = [...outputs];
|
|
2209
|
+
let currentState = newState;
|
|
2210
|
+
for (const output of outputs) {
|
|
2211
|
+
const [chainedState, chainedOutputs] = this.processChained(currentState, output);
|
|
2212
|
+
currentState = chainedState;
|
|
2213
|
+
allOutputs.push(...chainedOutputs);
|
|
2214
|
+
}
|
|
2215
|
+
return [currentState, allOutputs];
|
|
2216
|
+
}
|
|
2217
|
+
/**
|
|
2218
|
+
* Clear state for an agent
|
|
2219
|
+
*
|
|
2220
|
+
* Call this when an agent is destroyed to free memory.
|
|
2221
|
+
*/
|
|
2222
|
+
clearState(agentId) {
|
|
2223
|
+
logger33.debug("Clearing state", { agentId });
|
|
2224
|
+
this.store.delete(agentId);
|
|
2225
|
+
}
|
|
2226
|
+
/**
|
|
2227
|
+
* Check if state exists for an agent
|
|
2228
|
+
*/
|
|
2229
|
+
hasState(agentId) {
|
|
2230
|
+
return this.store.has(agentId);
|
|
2231
|
+
}
|
|
2232
|
+
};
|
|
2233
|
+
|
|
2234
|
+
// src/container/ContainerManagerImpl.ts
|
|
2235
|
+
var logger7 = createLogger("agentx/ContainerManager");
|
|
528
2236
|
function generateContainerId() {
|
|
529
2237
|
const timestamp = Date.now().toString(36);
|
|
530
2238
|
const random = Math.random().toString(36).substring(2, 8);
|
|
@@ -556,7 +2264,7 @@ var ContainerManagerImpl = class {
|
|
|
556
2264
|
config
|
|
557
2265
|
};
|
|
558
2266
|
await this.repository.saveContainer(record);
|
|
559
|
-
|
|
2267
|
+
logger7.info("Container created", { containerId });
|
|
560
2268
|
return record;
|
|
561
2269
|
}
|
|
562
2270
|
async get(containerId) {
|
|
@@ -571,7 +2279,7 @@ var ContainerManagerImpl = class {
|
|
|
571
2279
|
return false;
|
|
572
2280
|
}
|
|
573
2281
|
await this.repository.deleteContainer(containerId);
|
|
574
|
-
|
|
2282
|
+
logger7.info("Container deleted", { containerId });
|
|
575
2283
|
return true;
|
|
576
2284
|
}
|
|
577
2285
|
async exists(containerId) {
|
|
@@ -579,7 +2287,7 @@ var ContainerManagerImpl = class {
|
|
|
579
2287
|
}
|
|
580
2288
|
// ==================== Agent Runtime ====================
|
|
581
2289
|
async run(image, containerId) {
|
|
582
|
-
|
|
2290
|
+
logger7.info("Running agent from image", {
|
|
583
2291
|
imageId: image.imageId,
|
|
584
2292
|
containerId
|
|
585
2293
|
});
|
|
@@ -601,7 +2309,7 @@ var ContainerManagerImpl = class {
|
|
|
601
2309
|
const driver = this.runtime.createDriver(image.definition, context, sandbox);
|
|
602
2310
|
const agent = new AgentInstance(image.definition, context, this.engine, driver, sandbox);
|
|
603
2311
|
this.agents.set(agentId, agent);
|
|
604
|
-
|
|
2312
|
+
logger7.info("Agent started", {
|
|
605
2313
|
agentId,
|
|
606
2314
|
imageId: image.imageId,
|
|
607
2315
|
containerId,
|
|
@@ -610,7 +2318,7 @@ var ContainerManagerImpl = class {
|
|
|
610
2318
|
return agent;
|
|
611
2319
|
}
|
|
612
2320
|
async resume(session, containerId) {
|
|
613
|
-
|
|
2321
|
+
logger7.info("Resuming agent from session", {
|
|
614
2322
|
sessionId: session.sessionId,
|
|
615
2323
|
imageId: session.imageId,
|
|
616
2324
|
containerId
|
|
@@ -638,7 +2346,7 @@ var ContainerManagerImpl = class {
|
|
|
638
2346
|
const driver = this.runtime.createDriver(definition, context, sandbox);
|
|
639
2347
|
const agent = new AgentInstance(definition, context, this.engine, driver, sandbox);
|
|
640
2348
|
this.agents.set(agentId, agent);
|
|
641
|
-
|
|
2349
|
+
logger7.info("Agent resumed", {
|
|
642
2350
|
agentId,
|
|
643
2351
|
sessionId: session.sessionId,
|
|
644
2352
|
imageId: session.imageId,
|
|
@@ -649,13 +2357,13 @@ var ContainerManagerImpl = class {
|
|
|
649
2357
|
async destroyAgent(agentId) {
|
|
650
2358
|
const agent = this.agents.get(agentId);
|
|
651
2359
|
if (!agent) {
|
|
652
|
-
|
|
2360
|
+
logger7.warn("Agent not found for destroy", { agentId });
|
|
653
2361
|
return;
|
|
654
2362
|
}
|
|
655
|
-
|
|
2363
|
+
logger7.debug("Destroying agent", { agentId });
|
|
656
2364
|
await agent.destroy();
|
|
657
2365
|
this.agents.delete(agentId);
|
|
658
|
-
|
|
2366
|
+
logger7.info("Agent destroyed", { agentId });
|
|
659
2367
|
}
|
|
660
2368
|
getAgent(agentId) {
|
|
661
2369
|
return this.agents.get(agentId);
|
|
@@ -668,16 +2376,16 @@ var ContainerManagerImpl = class {
|
|
|
668
2376
|
}
|
|
669
2377
|
async destroyAllAgents() {
|
|
670
2378
|
const agentIds = Array.from(this.agents.keys());
|
|
671
|
-
|
|
2379
|
+
logger7.debug("Destroying all agents", { count: agentIds.length });
|
|
672
2380
|
await Promise.all(agentIds.map((id) => this.destroyAgent(id)));
|
|
673
|
-
|
|
2381
|
+
logger7.info("All agents destroyed", { count: agentIds.length });
|
|
674
2382
|
}
|
|
675
2383
|
};
|
|
676
2384
|
|
|
677
2385
|
// src/AgentX.ts
|
|
678
|
-
var
|
|
2386
|
+
var logger8 = createLogger("agentx/AgentX");
|
|
679
2387
|
function createAgentX(runtime, options) {
|
|
680
|
-
|
|
2388
|
+
logger8.info("Creating AgentX instance", { runtime: runtime.name });
|
|
681
2389
|
if (!runtime.repository) {
|
|
682
2390
|
throw new Error("Runtime must have a repository for persistence");
|
|
683
2391
|
}
|
|
@@ -688,7 +2396,7 @@ function createAgentX(runtime, options) {
|
|
|
688
2396
|
const agentManager = new AgentManager(containerManager);
|
|
689
2397
|
const imageManager = new ImageManagerImpl(repository, containerManager, options?.containerId);
|
|
690
2398
|
const sessionManager = new SessionManagerImpl(repository, containerManager, options?.containerId);
|
|
691
|
-
|
|
2399
|
+
logger8.debug("AgentX instance created", { runtime: runtime.name });
|
|
692
2400
|
return {
|
|
693
2401
|
mode: "local",
|
|
694
2402
|
containers: containerManager,
|
|
@@ -862,7 +2570,9 @@ function createSSEDriver(config) {
|
|
|
862
2570
|
}
|
|
863
2571
|
};
|
|
864
2572
|
}
|
|
865
|
-
|
|
2573
|
+
|
|
2574
|
+
// src/runtime/sse/repository/RemoteRepository.ts
|
|
2575
|
+
var logger9 = createLogger("agentx/RemoteRepository");
|
|
866
2576
|
var RemoteRepository = class {
|
|
867
2577
|
constructor(options) {
|
|
868
2578
|
__publicField(this, "client");
|
|
@@ -870,7 +2580,7 @@ var RemoteRepository = class {
|
|
|
870
2580
|
baseUrl: options.serverUrl,
|
|
871
2581
|
headers: options.headers
|
|
872
2582
|
});
|
|
873
|
-
|
|
2583
|
+
logger9.debug("RemoteRepository created", { serverUrl: options.serverUrl });
|
|
874
2584
|
}
|
|
875
2585
|
// ==================== Definition ====================
|
|
876
2586
|
async saveDefinition(record) {
|
|
@@ -975,7 +2685,7 @@ var RemoteRepository = class {
|
|
|
975
2685
|
* Browser-side calls this but it does nothing to avoid duplicate saves.
|
|
976
2686
|
*/
|
|
977
2687
|
async saveMessage(_record) {
|
|
978
|
-
|
|
2688
|
+
logger9.debug("saveMessage called (noop in browser)");
|
|
979
2689
|
}
|
|
980
2690
|
async findMessageById(messageId) {
|
|
981
2691
|
try {
|
|
@@ -1183,12 +2893,14 @@ var BrowserLoggerFactory = class {
|
|
|
1183
2893
|
if (this.loggers.has(name)) {
|
|
1184
2894
|
return this.loggers.get(name);
|
|
1185
2895
|
}
|
|
1186
|
-
const
|
|
1187
|
-
this.loggers.set(name,
|
|
1188
|
-
return
|
|
2896
|
+
const logger11 = new BrowserLogger(name, this.options);
|
|
2897
|
+
this.loggers.set(name, logger11);
|
|
2898
|
+
return logger11;
|
|
1189
2899
|
}
|
|
1190
2900
|
};
|
|
1191
|
-
|
|
2901
|
+
|
|
2902
|
+
// src/runtime/sse/RemoteAgentIdResolver.ts
|
|
2903
|
+
var logger10 = createLogger("agentx/RemoteAgentIdResolver");
|
|
1192
2904
|
var RemoteAgentIdResolver = class {
|
|
1193
2905
|
constructor(options) {
|
|
1194
2906
|
__publicField(this, "client");
|
|
@@ -1198,19 +2910,19 @@ var RemoteAgentIdResolver = class {
|
|
|
1198
2910
|
});
|
|
1199
2911
|
}
|
|
1200
2912
|
async resolveForRun(imageId, containerId) {
|
|
1201
|
-
|
|
2913
|
+
logger10.debug("Resolving agent ID for run", { imageId, containerId });
|
|
1202
2914
|
const response = await this.client.post(`images/${imageId}/run`, {
|
|
1203
2915
|
json: { containerId }
|
|
1204
2916
|
}).json();
|
|
1205
|
-
|
|
2917
|
+
logger10.info("Agent ID resolved for run", { imageId, agentId: response.agentId });
|
|
1206
2918
|
return response.agentId;
|
|
1207
2919
|
}
|
|
1208
2920
|
async resolveForResume(sessionId, containerId) {
|
|
1209
|
-
|
|
2921
|
+
logger10.debug("Resolving agent ID for resume", { sessionId, containerId });
|
|
1210
2922
|
const response = await this.client.post(`sessions/${sessionId}/resume`, {
|
|
1211
2923
|
json: { containerId }
|
|
1212
2924
|
}).json();
|
|
1213
|
-
|
|
2925
|
+
logger10.info("Agent ID resolved for resume", { sessionId, agentId: response.agentId });
|
|
1214
2926
|
return response.agentId;
|
|
1215
2927
|
}
|
|
1216
2928
|
};
|