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.js CHANGED
@@ -1,8 +1,7 @@
1
- import { createLogger, setLoggerFactory } from '@agentxjs/common';
1
+ import { LogLevel, isStateEvent, STREAM_EVENT_TYPE_NAMES } from '@agentxjs/types';
2
2
  import ky from 'ky';
3
- import { AgentInstance } from '@agentxjs/agent';
4
- import { AgentEngine } from '@agentxjs/engine';
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("agentx/ContainerManager");
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
- logger6.info("Container created", { containerId });
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
- logger6.info("Container deleted", { containerId });
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
- logger6.info("Running agent from image", {
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
- logger6.info("Agent started", {
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
- logger6.info("Resuming agent from session", {
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
- logger6.info("Agent resumed", {
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
- logger6.warn("Agent not found for destroy", { agentId });
2360
+ logger7.warn("Agent not found for destroy", { agentId });
653
2361
  return;
654
2362
  }
655
- logger6.debug("Destroying agent", { agentId });
2363
+ logger7.debug("Destroying agent", { agentId });
656
2364
  await agent.destroy();
657
2365
  this.agents.delete(agentId);
658
- logger6.info("Agent destroyed", { agentId });
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
- logger6.debug("Destroying all agents", { count: agentIds.length });
2379
+ logger7.debug("Destroying all agents", { count: agentIds.length });
672
2380
  await Promise.all(agentIds.map((id) => this.destroyAgent(id)));
673
- logger6.info("All agents destroyed", { count: agentIds.length });
2381
+ logger7.info("All agents destroyed", { count: agentIds.length });
674
2382
  }
675
2383
  };
676
2384
 
677
2385
  // src/AgentX.ts
678
- var logger7 = createLogger("agentx/AgentX");
2386
+ var logger8 = createLogger("agentx/AgentX");
679
2387
  function createAgentX(runtime, options) {
680
- logger7.info("Creating AgentX instance", { runtime: runtime.name });
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
- logger7.debug("AgentX instance created", { runtime: runtime.name });
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
- var logger8 = createLogger("agentx/RemoteRepository");
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
- logger8.debug("RemoteRepository created", { serverUrl: options.serverUrl });
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
- logger8.debug("saveMessage called (noop in browser)");
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 logger10 = new BrowserLogger(name, this.options);
1187
- this.loggers.set(name, logger10);
1188
- return logger10;
2896
+ const logger11 = new BrowserLogger(name, this.options);
2897
+ this.loggers.set(name, logger11);
2898
+ return logger11;
1189
2899
  }
1190
2900
  };
1191
- var logger9 = createLogger("agentx/RemoteAgentIdResolver");
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
- logger9.debug("Resolving agent ID for run", { imageId, containerId });
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
- logger9.info("Agent ID resolved for run", { imageId, agentId: response.agentId });
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
- logger9.debug("Resolving agent ID for resume", { sessionId, containerId });
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
- logger9.info("Agent ID resolved for resume", { sessionId, agentId: response.agentId });
2925
+ logger10.info("Agent ID resolved for resume", { sessionId, agentId: response.agentId });
1214
2926
  return response.agentId;
1215
2927
  }
1216
2928
  };