agentxjs 2.6.1 → 2.8.0
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 +44 -1
- package/dist/chunk-JUZULVWQ.js +388 -0
- package/dist/chunk-JUZULVWQ.js.map +1 -0
- package/dist/index.d.ts +59 -289
- package/dist/index.js +124 -304
- package/dist/index.js.map +1 -1
- package/dist/server-MVOHQ5ZM.js +184 -0
- package/dist/server-MVOHQ5ZM.js.map +1 -0
- package/package.json +3 -3
- package/src/AgentHandle.ts +16 -14
- package/src/CommandHandler.ts +89 -204
- package/src/LocalClient.ts +21 -51
- package/src/RemoteClient.ts +20 -45
- package/src/index.ts +12 -26
- package/src/namespaces/agents.ts +34 -28
- package/src/namespaces/images.ts +21 -29
- package/src/namespaces/llm.ts +16 -10
- package/src/namespaces/presentations.ts +7 -7
- package/src/namespaces/sessions.ts +16 -14
- package/src/presentation/Presentation.ts +11 -11
- package/src/types.ts +64 -206
- package/dist/chunk-JTHR3AK6.js +0 -652
- package/dist/chunk-JTHR3AK6.js.map +0 -1
- package/dist/server-UCQISBKH.js +0 -7
- package/dist/server-UCQISBKH.js.map +0 -1
- package/src/namespaces/containers.ts +0 -68
- package/src/namespaces/prototypes.ts +0 -136
package/dist/chunk-JTHR3AK6.js
DELETED
|
@@ -1,652 +0,0 @@
|
|
|
1
|
-
// src/server.ts
|
|
2
|
-
import {
|
|
3
|
-
createErrorResponse,
|
|
4
|
-
createStreamEvent,
|
|
5
|
-
createSuccessResponse,
|
|
6
|
-
isNotification,
|
|
7
|
-
isRequest,
|
|
8
|
-
parseMessage,
|
|
9
|
-
RpcErrorCodes
|
|
10
|
-
} from "@agentxjs/core/network";
|
|
11
|
-
import { createAgentXRuntime } from "@agentxjs/core/runtime";
|
|
12
|
-
import { createLogger as createLogger2 } from "@deepracticex/logger";
|
|
13
|
-
|
|
14
|
-
// src/CommandHandler.ts
|
|
15
|
-
import { createLogger } from "@deepracticex/logger";
|
|
16
|
-
var logger = createLogger("server/CommandHandler");
|
|
17
|
-
function ok(data) {
|
|
18
|
-
return { success: true, data };
|
|
19
|
-
}
|
|
20
|
-
function err(code, message) {
|
|
21
|
-
return { success: false, code, message };
|
|
22
|
-
}
|
|
23
|
-
var CommandHandler = class {
|
|
24
|
-
runtime;
|
|
25
|
-
constructor(runtime) {
|
|
26
|
-
this.runtime = runtime;
|
|
27
|
-
logger.debug("CommandHandler created");
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Handle an RPC request and return response
|
|
31
|
-
*/
|
|
32
|
-
async handle(method, params) {
|
|
33
|
-
logger.debug("Handling RPC request", { method });
|
|
34
|
-
try {
|
|
35
|
-
switch (method) {
|
|
36
|
-
// Container
|
|
37
|
-
case "container.create":
|
|
38
|
-
return await this.handleContainerCreate(params);
|
|
39
|
-
case "container.get":
|
|
40
|
-
return await this.handleContainerGet(params);
|
|
41
|
-
case "container.list":
|
|
42
|
-
return await this.handleContainerList(params);
|
|
43
|
-
// Image
|
|
44
|
-
case "image.create":
|
|
45
|
-
return await this.handleImageCreate(params);
|
|
46
|
-
case "image.get":
|
|
47
|
-
return await this.handleImageGet(params);
|
|
48
|
-
case "image.list":
|
|
49
|
-
return await this.handleImageList(params);
|
|
50
|
-
case "image.delete":
|
|
51
|
-
return await this.handleImageDelete(params);
|
|
52
|
-
case "image.run":
|
|
53
|
-
return await this.handleImageRun(params);
|
|
54
|
-
case "image.stop":
|
|
55
|
-
return await this.handleImageStop(params);
|
|
56
|
-
case "image.update":
|
|
57
|
-
return await this.handleImageUpdate(params);
|
|
58
|
-
case "image.messages":
|
|
59
|
-
return await this.handleImageMessages(params);
|
|
60
|
-
// Agent
|
|
61
|
-
case "agent.get":
|
|
62
|
-
return await this.handleAgentGet(params);
|
|
63
|
-
case "agent.list":
|
|
64
|
-
return await this.handleAgentList(params);
|
|
65
|
-
case "agent.destroy":
|
|
66
|
-
return await this.handleAgentDestroy(params);
|
|
67
|
-
case "agent.destroyAll":
|
|
68
|
-
return await this.handleAgentDestroyAll(params);
|
|
69
|
-
case "agent.interrupt":
|
|
70
|
-
return await this.handleAgentInterrupt(params);
|
|
71
|
-
// Message
|
|
72
|
-
case "message.send":
|
|
73
|
-
return await this.handleMessageSend(params);
|
|
74
|
-
// Prototype
|
|
75
|
-
case "prototype.create":
|
|
76
|
-
return await this.handlePrototypeCreate(params);
|
|
77
|
-
case "prototype.get":
|
|
78
|
-
return await this.handlePrototypeGet(params);
|
|
79
|
-
case "prototype.list":
|
|
80
|
-
return await this.handlePrototypeList(params);
|
|
81
|
-
case "prototype.update":
|
|
82
|
-
return await this.handlePrototypeUpdate(params);
|
|
83
|
-
case "prototype.delete":
|
|
84
|
-
return await this.handlePrototypeDelete(params);
|
|
85
|
-
// LLM Provider
|
|
86
|
-
case "llm.create":
|
|
87
|
-
return await this.handleLLMCreate(params);
|
|
88
|
-
case "llm.get":
|
|
89
|
-
return await this.handleLLMGet(params);
|
|
90
|
-
case "llm.list":
|
|
91
|
-
return await this.handleLLMList(params);
|
|
92
|
-
case "llm.update":
|
|
93
|
-
return await this.handleLLMUpdate(params);
|
|
94
|
-
case "llm.delete":
|
|
95
|
-
return await this.handleLLMDelete(params);
|
|
96
|
-
case "llm.default":
|
|
97
|
-
return await this.handleLLMDefault(params);
|
|
98
|
-
default:
|
|
99
|
-
return err(-32601, `Method not found: ${method}`);
|
|
100
|
-
}
|
|
101
|
-
} catch (error) {
|
|
102
|
-
logger.error("RPC handler error", { method, error });
|
|
103
|
-
return err(-32e3, error instanceof Error ? error.message : String(error));
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
// ==================== Container Commands ====================
|
|
107
|
-
async handleContainerCreate(params) {
|
|
108
|
-
const { containerId } = params;
|
|
109
|
-
const { getOrCreateContainer } = await import("@agentxjs/core/container");
|
|
110
|
-
const { containerRepository, imageRepository, sessionRepository } = this.runtime.platform;
|
|
111
|
-
const container = await getOrCreateContainer(containerId, {
|
|
112
|
-
containerRepository,
|
|
113
|
-
imageRepository,
|
|
114
|
-
sessionRepository
|
|
115
|
-
});
|
|
116
|
-
return ok({ containerId: container.containerId });
|
|
117
|
-
}
|
|
118
|
-
async handleContainerGet(params) {
|
|
119
|
-
const { containerId } = params;
|
|
120
|
-
const exists = await this.runtime.platform.containerRepository.containerExists(containerId);
|
|
121
|
-
return ok({ containerId, exists });
|
|
122
|
-
}
|
|
123
|
-
async handleContainerList(_params) {
|
|
124
|
-
const containers = await this.runtime.platform.containerRepository.findAllContainers();
|
|
125
|
-
return ok({ containerIds: containers.map((c) => c.containerId) });
|
|
126
|
-
}
|
|
127
|
-
// ==================== Image Commands ====================
|
|
128
|
-
async handleImageCreate(params) {
|
|
129
|
-
const { containerId, name, description, contextId, embody, customData } = params;
|
|
130
|
-
const { imageRepository, sessionRepository } = this.runtime.platform;
|
|
131
|
-
const { createImage } = await import("@agentxjs/core/image");
|
|
132
|
-
const image = await createImage(
|
|
133
|
-
{ containerId, name, description, contextId, embody, customData },
|
|
134
|
-
{ imageRepository, sessionRepository }
|
|
135
|
-
);
|
|
136
|
-
return ok({
|
|
137
|
-
record: image.toRecord(),
|
|
138
|
-
__subscriptions: [image.sessionId]
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
async handleImageGet(params) {
|
|
142
|
-
const { imageId } = params;
|
|
143
|
-
const record = await this.runtime.platform.imageRepository.findImageById(imageId);
|
|
144
|
-
return ok({
|
|
145
|
-
record,
|
|
146
|
-
__subscriptions: record?.sessionId ? [record.sessionId] : void 0
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
async handleImageList(params) {
|
|
150
|
-
const { containerId } = params;
|
|
151
|
-
const records = containerId ? await this.runtime.platform.imageRepository.findImagesByContainerId(containerId) : await this.runtime.platform.imageRepository.findAllImages();
|
|
152
|
-
return ok({
|
|
153
|
-
records,
|
|
154
|
-
__subscriptions: records.map((r) => r.sessionId)
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
async handleImageDelete(params) {
|
|
158
|
-
const { imageId } = params;
|
|
159
|
-
const { loadImage } = await import("@agentxjs/core/image");
|
|
160
|
-
const { imageRepository, sessionRepository } = this.runtime.platform;
|
|
161
|
-
const image = await loadImage(imageId, { imageRepository, sessionRepository });
|
|
162
|
-
if (image) {
|
|
163
|
-
await image.delete();
|
|
164
|
-
}
|
|
165
|
-
return ok({ imageId });
|
|
166
|
-
}
|
|
167
|
-
async handleImageRun(params) {
|
|
168
|
-
const { imageId, agentId: requestedAgentId } = params;
|
|
169
|
-
const existingAgent = this.runtime.getAgents().find((a) => a.imageId === imageId && a.lifecycle === "running");
|
|
170
|
-
if (existingAgent) {
|
|
171
|
-
logger.debug("Reusing existing agent for image", {
|
|
172
|
-
imageId,
|
|
173
|
-
agentId: existingAgent.agentId
|
|
174
|
-
});
|
|
175
|
-
return ok({
|
|
176
|
-
imageId,
|
|
177
|
-
agentId: existingAgent.agentId,
|
|
178
|
-
sessionId: existingAgent.sessionId,
|
|
179
|
-
containerId: existingAgent.containerId,
|
|
180
|
-
reused: true
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
const agent = await this.runtime.createAgent({
|
|
184
|
-
imageId,
|
|
185
|
-
agentId: requestedAgentId
|
|
186
|
-
});
|
|
187
|
-
logger.info("Created new agent for image", {
|
|
188
|
-
imageId,
|
|
189
|
-
agentId: agent.agentId
|
|
190
|
-
});
|
|
191
|
-
return ok({
|
|
192
|
-
imageId,
|
|
193
|
-
agentId: agent.agentId,
|
|
194
|
-
sessionId: agent.sessionId,
|
|
195
|
-
containerId: agent.containerId,
|
|
196
|
-
reused: false
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
async handleImageStop(params) {
|
|
200
|
-
const { imageId } = params;
|
|
201
|
-
const agent = this.runtime.getAgents().find((a) => a.imageId === imageId && a.lifecycle === "running");
|
|
202
|
-
if (agent) {
|
|
203
|
-
await this.runtime.stopAgent(agent.agentId);
|
|
204
|
-
logger.info("Stopped agent for image", { imageId, agentId: agent.agentId });
|
|
205
|
-
} else {
|
|
206
|
-
logger.debug("No running agent found for image", { imageId });
|
|
207
|
-
}
|
|
208
|
-
return ok({ imageId });
|
|
209
|
-
}
|
|
210
|
-
async handleImageUpdate(params) {
|
|
211
|
-
const { imageId, updates } = params;
|
|
212
|
-
const imageRecord = await this.runtime.platform.imageRepository.findImageById(imageId);
|
|
213
|
-
if (!imageRecord) {
|
|
214
|
-
return err(404, `Image not found: ${imageId}`);
|
|
215
|
-
}
|
|
216
|
-
const { embody: embodyUpdates, ...otherUpdates } = updates;
|
|
217
|
-
const updatedRecord = {
|
|
218
|
-
...imageRecord,
|
|
219
|
-
...otherUpdates,
|
|
220
|
-
embody: embodyUpdates ? { ...imageRecord.embody, ...embodyUpdates } : imageRecord.embody,
|
|
221
|
-
updatedAt: Date.now()
|
|
222
|
-
};
|
|
223
|
-
await this.runtime.platform.imageRepository.saveImage(updatedRecord);
|
|
224
|
-
logger.info("Updated image", { imageId, updates });
|
|
225
|
-
return ok({ record: updatedRecord });
|
|
226
|
-
}
|
|
227
|
-
async handleImageMessages(params) {
|
|
228
|
-
const { imageId } = params;
|
|
229
|
-
const imageRecord = await this.runtime.platform.imageRepository.findImageById(imageId);
|
|
230
|
-
if (!imageRecord) {
|
|
231
|
-
return err(404, `Image not found: ${imageId}`);
|
|
232
|
-
}
|
|
233
|
-
const messages = await this.runtime.platform.sessionRepository.getMessages(
|
|
234
|
-
imageRecord.sessionId
|
|
235
|
-
);
|
|
236
|
-
logger.debug("Got messages for image", { imageId, count: messages.length });
|
|
237
|
-
return ok({ imageId, messages });
|
|
238
|
-
}
|
|
239
|
-
// ==================== Agent Commands ====================
|
|
240
|
-
async handleAgentGet(params) {
|
|
241
|
-
const { agentId } = params;
|
|
242
|
-
const agent = this.runtime.getAgent(agentId);
|
|
243
|
-
return ok({
|
|
244
|
-
agent: agent ? {
|
|
245
|
-
agentId: agent.agentId,
|
|
246
|
-
imageId: agent.imageId,
|
|
247
|
-
containerId: agent.containerId,
|
|
248
|
-
sessionId: agent.sessionId,
|
|
249
|
-
lifecycle: agent.lifecycle
|
|
250
|
-
} : null,
|
|
251
|
-
exists: !!agent
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
async handleAgentList(params) {
|
|
255
|
-
const { containerId } = params;
|
|
256
|
-
const agents = containerId ? this.runtime.getAgentsByContainer(containerId) : this.runtime.getAgents();
|
|
257
|
-
return ok({
|
|
258
|
-
agents: agents.map((a) => ({
|
|
259
|
-
agentId: a.agentId,
|
|
260
|
-
imageId: a.imageId,
|
|
261
|
-
containerId: a.containerId,
|
|
262
|
-
sessionId: a.sessionId,
|
|
263
|
-
lifecycle: a.lifecycle
|
|
264
|
-
}))
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
async handleAgentDestroy(params) {
|
|
268
|
-
const { agentId } = params;
|
|
269
|
-
const agent = this.runtime.getAgent(agentId);
|
|
270
|
-
if (!agent) {
|
|
271
|
-
return ok({ agentId, success: false });
|
|
272
|
-
}
|
|
273
|
-
await this.runtime.destroyAgent(agentId);
|
|
274
|
-
return ok({ agentId, success: true });
|
|
275
|
-
}
|
|
276
|
-
async handleAgentDestroyAll(params) {
|
|
277
|
-
const { containerId } = params;
|
|
278
|
-
const agents = this.runtime.getAgentsByContainer(containerId);
|
|
279
|
-
for (const agent of agents) {
|
|
280
|
-
await this.runtime.destroyAgent(agent.agentId);
|
|
281
|
-
}
|
|
282
|
-
return ok({ containerId });
|
|
283
|
-
}
|
|
284
|
-
async handleAgentInterrupt(params) {
|
|
285
|
-
const { agentId } = params;
|
|
286
|
-
this.runtime.interrupt(agentId);
|
|
287
|
-
return ok({ agentId });
|
|
288
|
-
}
|
|
289
|
-
// ==================== Message Commands ====================
|
|
290
|
-
async handleMessageSend(params) {
|
|
291
|
-
const { agentId, imageId, content } = params;
|
|
292
|
-
let targetAgentId;
|
|
293
|
-
if (agentId) {
|
|
294
|
-
targetAgentId = agentId;
|
|
295
|
-
} else if (imageId) {
|
|
296
|
-
const existingAgent = this.runtime.getAgents().find((a) => a.imageId === imageId && a.lifecycle === "running");
|
|
297
|
-
if (existingAgent) {
|
|
298
|
-
targetAgentId = existingAgent.agentId;
|
|
299
|
-
logger.debug("Using existing agent for message", {
|
|
300
|
-
imageId,
|
|
301
|
-
agentId: targetAgentId
|
|
302
|
-
});
|
|
303
|
-
} else {
|
|
304
|
-
const agent = await this.runtime.createAgent({ imageId });
|
|
305
|
-
targetAgentId = agent.agentId;
|
|
306
|
-
logger.info("Auto-created agent for message", {
|
|
307
|
-
imageId,
|
|
308
|
-
agentId: targetAgentId
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
} else {
|
|
312
|
-
return err(-32602, "Either agentId or imageId is required");
|
|
313
|
-
}
|
|
314
|
-
await this.runtime.receive(targetAgentId, content);
|
|
315
|
-
return ok({ agentId: targetAgentId, imageId });
|
|
316
|
-
}
|
|
317
|
-
// ==================== Prototype Commands ====================
|
|
318
|
-
async handlePrototypeCreate(params) {
|
|
319
|
-
const { containerId, name, description, contextId, embody, customData } = params;
|
|
320
|
-
const repo = this.runtime.platform.prototypeRepository;
|
|
321
|
-
if (!repo) {
|
|
322
|
-
return err(-32e3, "Prototype repository not available");
|
|
323
|
-
}
|
|
324
|
-
const now = Date.now();
|
|
325
|
-
const random = Math.random().toString(36).slice(2, 8);
|
|
326
|
-
const record = {
|
|
327
|
-
prototypeId: `proto_${now}_${random}`,
|
|
328
|
-
containerId,
|
|
329
|
-
name,
|
|
330
|
-
description,
|
|
331
|
-
contextId,
|
|
332
|
-
embody,
|
|
333
|
-
customData,
|
|
334
|
-
createdAt: now,
|
|
335
|
-
updatedAt: now
|
|
336
|
-
};
|
|
337
|
-
await repo.savePrototype(record);
|
|
338
|
-
return ok({ record });
|
|
339
|
-
}
|
|
340
|
-
async handlePrototypeGet(params) {
|
|
341
|
-
const { prototypeId } = params;
|
|
342
|
-
const repo = this.runtime.platform.prototypeRepository;
|
|
343
|
-
if (!repo) {
|
|
344
|
-
return err(-32e3, "Prototype repository not available");
|
|
345
|
-
}
|
|
346
|
-
const record = await repo.findPrototypeById(prototypeId);
|
|
347
|
-
return ok({ record });
|
|
348
|
-
}
|
|
349
|
-
async handlePrototypeList(params) {
|
|
350
|
-
const { containerId } = params;
|
|
351
|
-
const repo = this.runtime.platform.prototypeRepository;
|
|
352
|
-
if (!repo) {
|
|
353
|
-
return err(-32e3, "Prototype repository not available");
|
|
354
|
-
}
|
|
355
|
-
const records = containerId ? await repo.findPrototypesByContainerId(containerId) : await repo.findAllPrototypes();
|
|
356
|
-
return ok({ records });
|
|
357
|
-
}
|
|
358
|
-
async handlePrototypeUpdate(params) {
|
|
359
|
-
const { prototypeId, updates } = params;
|
|
360
|
-
const repo = this.runtime.platform.prototypeRepository;
|
|
361
|
-
if (!repo) {
|
|
362
|
-
return err(-32e3, "Prototype repository not available");
|
|
363
|
-
}
|
|
364
|
-
const existing = await repo.findPrototypeById(prototypeId);
|
|
365
|
-
if (!existing) {
|
|
366
|
-
return err(404, `Prototype not found: ${prototypeId}`);
|
|
367
|
-
}
|
|
368
|
-
const { embody: embodyUpdates, ...otherUpdates } = updates;
|
|
369
|
-
const updated = {
|
|
370
|
-
...existing,
|
|
371
|
-
...otherUpdates,
|
|
372
|
-
embody: embodyUpdates ? { ...existing.embody, ...embodyUpdates } : existing.embody,
|
|
373
|
-
updatedAt: Date.now()
|
|
374
|
-
};
|
|
375
|
-
await repo.savePrototype(updated);
|
|
376
|
-
return ok({ record: updated });
|
|
377
|
-
}
|
|
378
|
-
async handlePrototypeDelete(params) {
|
|
379
|
-
const { prototypeId } = params;
|
|
380
|
-
const repo = this.runtime.platform.prototypeRepository;
|
|
381
|
-
if (!repo) {
|
|
382
|
-
return err(-32e3, "Prototype repository not available");
|
|
383
|
-
}
|
|
384
|
-
await repo.deletePrototype(prototypeId);
|
|
385
|
-
return ok({ prototypeId });
|
|
386
|
-
}
|
|
387
|
-
// ==================== LLM Provider Commands ====================
|
|
388
|
-
async handleLLMCreate(params) {
|
|
389
|
-
const { containerId, name, vendor, protocol, apiKey, baseUrl, model } = params;
|
|
390
|
-
const repo = this.runtime.platform.llmProviderRepository;
|
|
391
|
-
if (!repo) {
|
|
392
|
-
return err(-32e3, "LLM provider repository not available");
|
|
393
|
-
}
|
|
394
|
-
const { generateId } = await import("@deepracticex/id");
|
|
395
|
-
const now = Date.now();
|
|
396
|
-
const record = {
|
|
397
|
-
id: generateId("llm"),
|
|
398
|
-
containerId,
|
|
399
|
-
name,
|
|
400
|
-
vendor,
|
|
401
|
-
protocol,
|
|
402
|
-
apiKey,
|
|
403
|
-
baseUrl,
|
|
404
|
-
model,
|
|
405
|
-
isDefault: false,
|
|
406
|
-
createdAt: now,
|
|
407
|
-
updatedAt: now
|
|
408
|
-
};
|
|
409
|
-
await repo.saveLLMProvider(record);
|
|
410
|
-
return ok({ record });
|
|
411
|
-
}
|
|
412
|
-
async handleLLMGet(params) {
|
|
413
|
-
const { id } = params;
|
|
414
|
-
const repo = this.runtime.platform.llmProviderRepository;
|
|
415
|
-
if (!repo) {
|
|
416
|
-
return err(-32e3, "LLM provider repository not available");
|
|
417
|
-
}
|
|
418
|
-
const record = await repo.findLLMProviderById(id);
|
|
419
|
-
return ok({ record });
|
|
420
|
-
}
|
|
421
|
-
async handleLLMList(params) {
|
|
422
|
-
const { containerId } = params;
|
|
423
|
-
const repo = this.runtime.platform.llmProviderRepository;
|
|
424
|
-
if (!repo) {
|
|
425
|
-
return err(-32e3, "LLM provider repository not available");
|
|
426
|
-
}
|
|
427
|
-
const records = await repo.findLLMProvidersByContainerId(containerId);
|
|
428
|
-
return ok({ records });
|
|
429
|
-
}
|
|
430
|
-
async handleLLMUpdate(params) {
|
|
431
|
-
const { id, updates } = params;
|
|
432
|
-
const repo = this.runtime.platform.llmProviderRepository;
|
|
433
|
-
if (!repo) {
|
|
434
|
-
return err(-32e3, "LLM provider repository not available");
|
|
435
|
-
}
|
|
436
|
-
const existing = await repo.findLLMProviderById(id);
|
|
437
|
-
if (!existing) {
|
|
438
|
-
return err(404, `LLM provider not found: ${id}`);
|
|
439
|
-
}
|
|
440
|
-
const updated = {
|
|
441
|
-
...existing,
|
|
442
|
-
...updates,
|
|
443
|
-
id: existing.id,
|
|
444
|
-
containerId: existing.containerId,
|
|
445
|
-
createdAt: existing.createdAt,
|
|
446
|
-
updatedAt: Date.now()
|
|
447
|
-
};
|
|
448
|
-
await repo.saveLLMProvider(updated);
|
|
449
|
-
return ok({ record: updated });
|
|
450
|
-
}
|
|
451
|
-
async handleLLMDelete(params) {
|
|
452
|
-
const { id } = params;
|
|
453
|
-
const repo = this.runtime.platform.llmProviderRepository;
|
|
454
|
-
if (!repo) {
|
|
455
|
-
return err(-32e3, "LLM provider repository not available");
|
|
456
|
-
}
|
|
457
|
-
await repo.deleteLLMProvider(id);
|
|
458
|
-
return ok({ id });
|
|
459
|
-
}
|
|
460
|
-
async handleLLMDefault(params) {
|
|
461
|
-
const { id, containerId } = params;
|
|
462
|
-
const repo = this.runtime.platform.llmProviderRepository;
|
|
463
|
-
if (!repo) {
|
|
464
|
-
return err(-32e3, "LLM provider repository not available");
|
|
465
|
-
}
|
|
466
|
-
if (id) {
|
|
467
|
-
await repo.setDefaultLLMProvider(id);
|
|
468
|
-
return ok({ id });
|
|
469
|
-
}
|
|
470
|
-
if (containerId) {
|
|
471
|
-
const record = await repo.findDefaultLLMProvider(containerId);
|
|
472
|
-
return ok({ record });
|
|
473
|
-
}
|
|
474
|
-
return err(-32602, "Either id or containerId is required");
|
|
475
|
-
}
|
|
476
|
-
// ==================== Lifecycle ====================
|
|
477
|
-
dispose() {
|
|
478
|
-
logger.debug("CommandHandler disposed");
|
|
479
|
-
}
|
|
480
|
-
};
|
|
481
|
-
|
|
482
|
-
// src/server.ts
|
|
483
|
-
var logger2 = createLogger2("server/Server");
|
|
484
|
-
async function createServer(config) {
|
|
485
|
-
const { wsPath = "/ws" } = config;
|
|
486
|
-
const platform = config.platform;
|
|
487
|
-
const runtime = createAgentXRuntime(platform, config.createDriver);
|
|
488
|
-
const wsServer = platform.channelServer;
|
|
489
|
-
if (!wsServer) {
|
|
490
|
-
throw new Error("Platform must provide channelServer for server mode");
|
|
491
|
-
}
|
|
492
|
-
const commandHandler = new CommandHandler(runtime);
|
|
493
|
-
const connections = /* @__PURE__ */ new Map();
|
|
494
|
-
function subscribeToTopic(connectionId, topic) {
|
|
495
|
-
const state = connections.get(connectionId);
|
|
496
|
-
if (!state || state.subscribedTopics.has(topic)) return;
|
|
497
|
-
state.subscribedTopics.add(topic);
|
|
498
|
-
logger2.debug("Connection subscribed to topic", { connectionId, topic });
|
|
499
|
-
}
|
|
500
|
-
function shouldSendToConnection(state, event) {
|
|
501
|
-
if (event.source === "driver" && event.intent !== "notification") {
|
|
502
|
-
return false;
|
|
503
|
-
}
|
|
504
|
-
if (event.source === "command") {
|
|
505
|
-
return false;
|
|
506
|
-
}
|
|
507
|
-
const eventWithContext = event;
|
|
508
|
-
const sessionId = eventWithContext.context?.sessionId;
|
|
509
|
-
if (sessionId && state.subscribedTopics.has(sessionId)) {
|
|
510
|
-
return true;
|
|
511
|
-
}
|
|
512
|
-
return state.subscribedTopics.has("global");
|
|
513
|
-
}
|
|
514
|
-
function sendResponse(connection, id, result) {
|
|
515
|
-
const response = createSuccessResponse(id, result);
|
|
516
|
-
connection.send(JSON.stringify(response));
|
|
517
|
-
}
|
|
518
|
-
function sendError(connection, id, code, message) {
|
|
519
|
-
const response = createErrorResponse(id, code, message);
|
|
520
|
-
connection.send(JSON.stringify(response));
|
|
521
|
-
}
|
|
522
|
-
wsServer.onConnection((connection) => {
|
|
523
|
-
const state = {
|
|
524
|
-
connection,
|
|
525
|
-
subscribedTopics: /* @__PURE__ */ new Set(["global"])
|
|
526
|
-
};
|
|
527
|
-
connections.set(connection.id, state);
|
|
528
|
-
logger2.info("Client connected", {
|
|
529
|
-
connectionId: connection.id,
|
|
530
|
-
totalConnections: connections.size
|
|
531
|
-
});
|
|
532
|
-
connection.onMessage(async (message) => {
|
|
533
|
-
try {
|
|
534
|
-
const parsed = parseMessage(message);
|
|
535
|
-
if (!Array.isArray(parsed)) {
|
|
536
|
-
await handleParsedMessage(connection, state, parsed);
|
|
537
|
-
} else {
|
|
538
|
-
for (const item of parsed) {
|
|
539
|
-
await handleParsedMessage(connection, state, item);
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
} catch (err2) {
|
|
543
|
-
logger2.error("Failed to parse message", { error: err2.message });
|
|
544
|
-
sendError(connection, null, RpcErrorCodes.PARSE_ERROR, "Parse error");
|
|
545
|
-
}
|
|
546
|
-
});
|
|
547
|
-
connection.onClose(() => {
|
|
548
|
-
connections.delete(connection.id);
|
|
549
|
-
logger2.info("Client disconnected", {
|
|
550
|
-
connectionId: connection.id,
|
|
551
|
-
totalConnections: connections.size
|
|
552
|
-
});
|
|
553
|
-
});
|
|
554
|
-
});
|
|
555
|
-
async function handleParsedMessage(connection, state, parsed) {
|
|
556
|
-
if (isRequest(parsed)) {
|
|
557
|
-
const payload = parsed.payload;
|
|
558
|
-
const { id, method, params } = payload;
|
|
559
|
-
logger2.debug("Received RPC request", { id, method });
|
|
560
|
-
const result = await commandHandler.handle(method, params);
|
|
561
|
-
if (result.success) {
|
|
562
|
-
sendResponse(connection, id, result.data);
|
|
563
|
-
} else {
|
|
564
|
-
sendError(connection, id, result.code, result.message);
|
|
565
|
-
}
|
|
566
|
-
} else if (isNotification(parsed)) {
|
|
567
|
-
const payload = parsed.payload;
|
|
568
|
-
const { method, params } = payload;
|
|
569
|
-
logger2.debug("Received notification", { method });
|
|
570
|
-
if (method === "subscribe") {
|
|
571
|
-
const { topic } = params;
|
|
572
|
-
subscribeToTopic(connection.id, topic);
|
|
573
|
-
} else if (method === "unsubscribe") {
|
|
574
|
-
const { topic } = params;
|
|
575
|
-
state.subscribedTopics.delete(topic);
|
|
576
|
-
logger2.debug("Connection unsubscribed from topic", { connectionId: connection.id, topic });
|
|
577
|
-
} else if (method === "control.ack") {
|
|
578
|
-
logger2.debug("Received ACK notification");
|
|
579
|
-
}
|
|
580
|
-
} else {
|
|
581
|
-
logger2.warn("Received invalid JSON-RPC message");
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
platform.eventBus.onAny((event) => {
|
|
585
|
-
if (!shouldBroadcastEvent(event)) {
|
|
586
|
-
return;
|
|
587
|
-
}
|
|
588
|
-
const eventWithContext = event;
|
|
589
|
-
const topic = eventWithContext.context?.sessionId || "global";
|
|
590
|
-
const notification = createStreamEvent(topic, event);
|
|
591
|
-
const message = JSON.stringify(notification);
|
|
592
|
-
for (const [connectionId, state] of connections) {
|
|
593
|
-
if (shouldSendToConnection(state, event)) {
|
|
594
|
-
state.connection.sendReliable(message, {
|
|
595
|
-
timeout: 1e4,
|
|
596
|
-
onTimeout: () => {
|
|
597
|
-
logger2.warn("Event ACK timeout", {
|
|
598
|
-
connectionId,
|
|
599
|
-
eventType: event.type
|
|
600
|
-
});
|
|
601
|
-
}
|
|
602
|
-
});
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
});
|
|
606
|
-
function shouldBroadcastEvent(event) {
|
|
607
|
-
if (event.source === "driver" && event.intent !== "notification") {
|
|
608
|
-
return false;
|
|
609
|
-
}
|
|
610
|
-
if (event.source === "command") {
|
|
611
|
-
return false;
|
|
612
|
-
}
|
|
613
|
-
const systemEvent = event;
|
|
614
|
-
if (systemEvent.broadcastable === false) {
|
|
615
|
-
return false;
|
|
616
|
-
}
|
|
617
|
-
return true;
|
|
618
|
-
}
|
|
619
|
-
if (config.server) {
|
|
620
|
-
wsServer.attach(config.server, wsPath);
|
|
621
|
-
logger2.info("WebSocket attached to existing server", { path: wsPath });
|
|
622
|
-
}
|
|
623
|
-
return {
|
|
624
|
-
async listen(port, host) {
|
|
625
|
-
if (config.server) {
|
|
626
|
-
throw new Error(
|
|
627
|
-
"Cannot listen when attached to existing server. The server should call listen() instead."
|
|
628
|
-
);
|
|
629
|
-
}
|
|
630
|
-
const listenPort = port ?? config.port ?? 5200;
|
|
631
|
-
const listenHost = host ?? config.host ?? "0.0.0.0";
|
|
632
|
-
await wsServer.listen(listenPort, listenHost);
|
|
633
|
-
logger2.info("Server listening", { port: listenPort, host: listenHost });
|
|
634
|
-
},
|
|
635
|
-
async close() {
|
|
636
|
-
await wsServer.close();
|
|
637
|
-
logger2.info("Server closed");
|
|
638
|
-
},
|
|
639
|
-
async dispose() {
|
|
640
|
-
await wsServer.dispose();
|
|
641
|
-
commandHandler.dispose();
|
|
642
|
-
await runtime.shutdown();
|
|
643
|
-
logger2.info("Server disposed");
|
|
644
|
-
}
|
|
645
|
-
};
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
export {
|
|
649
|
-
CommandHandler,
|
|
650
|
-
createServer
|
|
651
|
-
};
|
|
652
|
-
//# sourceMappingURL=chunk-JTHR3AK6.js.map
|