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