@xalia/agent 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/src/agent/agent.js +109 -57
- package/dist/agent/src/agent/agentUtils.js +24 -26
- package/dist/agent/src/agent/compressingContextManager.js +3 -2
- package/dist/agent/src/agent/dummyLLM.js +1 -3
- package/dist/agent/src/agent/imageGenLLM.js +67 -0
- package/dist/agent/src/agent/imageGenerator.js +43 -0
- package/dist/agent/src/agent/llm.js +27 -0
- package/dist/agent/src/agent/mcpServerManager.js +18 -6
- package/dist/agent/src/agent/nullAgentEventHandler.js +6 -0
- package/dist/agent/src/agent/openAILLM.js +3 -3
- package/dist/agent/src/agent/openAILLMStreaming.js +41 -6
- package/dist/agent/src/chat/client/chatClient.js +154 -235
- package/dist/agent/src/chat/client/constants.js +1 -2
- package/dist/agent/src/chat/client/sessionClient.js +47 -15
- package/dist/agent/src/chat/client/sessionFiles.js +102 -0
- package/dist/agent/src/chat/data/apiKeyManager.js +38 -7
- package/dist/agent/src/chat/data/database.js +83 -70
- package/dist/agent/src/chat/data/dbSessionFileModels.js +49 -0
- package/dist/agent/src/chat/data/dbSessionFiles.js +76 -0
- package/dist/agent/src/chat/data/dbSessionMessages.js +57 -0
- package/dist/agent/src/chat/data/mimeTypes.js +44 -0
- package/dist/agent/src/chat/protocol/messages.js +21 -1
- package/dist/agent/src/chat/server/chatContextManager.js +19 -16
- package/dist/agent/src/chat/server/connectionManager.js +14 -36
- package/dist/agent/src/chat/server/connectionManager.test.js +3 -16
- package/dist/agent/src/chat/server/conversation.js +73 -44
- package/dist/agent/src/chat/server/imageGeneratorTools.js +111 -0
- package/dist/agent/src/chat/server/openSession.js +398 -233
- package/dist/agent/src/chat/server/openSessionMessageSender.js +2 -0
- package/dist/agent/src/chat/server/server.js +5 -8
- package/dist/agent/src/chat/server/sessionFileManager.js +171 -38
- package/dist/agent/src/chat/server/sessionRegistry.js +214 -42
- package/dist/agent/src/chat/server/test-utils/mockFactories.js +12 -11
- package/dist/agent/src/chat/server/tools.js +27 -6
- package/dist/agent/src/chat/utils/approvalManager.js +82 -64
- package/dist/agent/src/chat/utils/multiAsyncQueue.js +9 -1
- package/dist/agent/src/chat/{client/responseHandler.js → utils/responseAwaiter.js} +41 -18
- package/dist/agent/src/test/agent.test.js +104 -63
- package/dist/agent/src/test/approvalManager.test.js +79 -35
- package/dist/agent/src/test/chatContextManager.test.js +16 -17
- package/dist/agent/src/test/clientServerConnection.test.js +2 -2
- package/dist/agent/src/test/db.test.js +33 -70
- package/dist/agent/src/test/dbSessionFiles.test.js +179 -0
- package/dist/agent/src/test/dbSessionMessages.test.js +67 -0
- package/dist/agent/src/test/dbTestTools.js +6 -5
- package/dist/agent/src/test/imageLoad.test.js +1 -1
- package/dist/agent/src/test/mcpServerManager.test.js +1 -1
- package/dist/agent/src/test/multiAsyncQueue.test.js +50 -0
- package/dist/agent/src/test/responseAwaiter.test.js +74 -0
- package/dist/agent/src/test/testTools.js +12 -0
- package/dist/agent/src/tool/agentChat.js +25 -6
- package/dist/agent/src/tool/agentMain.js +1 -1
- package/dist/agent/src/tool/chatMain.js +115 -6
- package/dist/agent/src/tool/commandPrompt.js +7 -3
- package/dist/agent/src/tool/files.js +23 -15
- package/dist/agent/src/tool/options.js +2 -2
- package/package.json +1 -1
- package/scripts/setup_chat +2 -2
- package/scripts/test_chat +95 -36
- package/src/agent/agent.ts +152 -41
- package/src/agent/agentUtils.ts +34 -41
- package/src/agent/compressingContextManager.ts +5 -4
- package/src/agent/context.ts +1 -1
- package/src/agent/dummyLLM.ts +1 -3
- package/src/agent/iAgentEventHandler.ts +15 -2
- package/src/agent/imageGenLLM.ts +99 -0
- package/src/agent/imageGenerator.ts +60 -0
- package/src/agent/llm.ts +128 -4
- package/src/agent/mcpServerManager.ts +26 -7
- package/src/agent/nullAgentEventHandler.ts +6 -0
- package/src/agent/openAILLM.ts +3 -8
- package/src/agent/openAILLMStreaming.ts +60 -14
- package/src/chat/client/chatClient.ts +262 -286
- package/src/chat/client/constants.ts +0 -2
- package/src/chat/client/sessionClient.ts +82 -20
- package/src/chat/client/sessionFiles.ts +142 -0
- package/src/chat/data/apiKeyManager.ts +55 -7
- package/src/chat/data/dataModels.ts +17 -7
- package/src/chat/data/database.ts +107 -92
- package/src/chat/data/dbSessionFileModels.ts +91 -0
- package/src/chat/data/dbSessionFiles.ts +99 -0
- package/src/chat/data/dbSessionMessages.ts +68 -0
- package/src/chat/data/mimeTypes.ts +58 -0
- package/src/chat/protocol/messages.ts +136 -25
- package/src/chat/server/chatContextManager.ts +42 -24
- package/src/chat/server/connectionManager.test.ts +2 -22
- package/src/chat/server/connectionManager.ts +18 -53
- package/src/chat/server/conversation.ts +106 -59
- package/src/chat/server/imageGeneratorTools.ts +138 -0
- package/src/chat/server/openSession.ts +606 -325
- package/src/chat/server/openSessionMessageSender.ts +4 -0
- package/src/chat/server/server.ts +5 -11
- package/src/chat/server/sessionFileManager.ts +223 -63
- package/src/chat/server/sessionRegistry.ts +317 -52
- package/src/chat/server/test-utils/mockFactories.ts +13 -13
- package/src/chat/server/tools.ts +43 -8
- package/src/chat/utils/agentSessionMap.ts +2 -2
- package/src/chat/utils/approvalManager.ts +153 -81
- package/src/chat/utils/multiAsyncQueue.ts +11 -1
- package/src/chat/{client/responseHandler.ts → utils/responseAwaiter.ts} +73 -23
- package/src/test/agent.test.ts +152 -75
- package/src/test/approvalManager.test.ts +108 -40
- package/src/test/chatContextManager.test.ts +26 -22
- package/src/test/clientServerConnection.test.ts +3 -3
- package/src/test/compressingContextManager.test.ts +1 -1
- package/src/test/context.test.ts +2 -1
- package/src/test/conversation.test.ts +1 -1
- package/src/test/db.test.ts +41 -83
- package/src/test/dbSessionFiles.test.ts +258 -0
- package/src/test/dbSessionMessages.test.ts +85 -0
- package/src/test/dbTestTools.ts +9 -5
- package/src/test/imageLoad.test.ts +2 -2
- package/src/test/mcpServerManager.test.ts +3 -1
- package/src/test/multiAsyncQueue.test.ts +58 -0
- package/src/test/responseAwaiter.test.ts +103 -0
- package/src/test/testTools.ts +15 -1
- package/src/tool/agentChat.ts +36 -8
- package/src/tool/agentMain.ts +7 -7
- package/src/tool/chatMain.ts +128 -7
- package/src/tool/commandPrompt.ts +10 -5
- package/src/tool/files.ts +30 -13
- package/src/tool/options.ts +1 -1
- package/test_data/dummyllm_script_image_gen.json +19 -0
- package/test_data/dummyllm_script_invoke_image_gen_tool.json +30 -0
- package/test_data/image_gen_test_profile.json +5 -0
- package/dist/agent/src/test/responseHandler.test.js +0 -61
- package/src/test/responseHandler.test.ts +0 -78
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ChatCompletionMessageParam,
|
|
3
|
-
ChatCompletionAssistantMessageParam,
|
|
4
|
-
ChatCompletionToolMessageParam,
|
|
5
|
-
ChatCompletionMessageToolCall,
|
|
6
|
-
} from "openai/resources.mjs";
|
|
7
1
|
import { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
8
2
|
|
|
9
3
|
import {
|
|
@@ -12,21 +6,29 @@ import {
|
|
|
12
6
|
McpServerConfiguration,
|
|
13
7
|
SavedAgentProfile,
|
|
14
8
|
} from "@xalia/xmcp/sdk";
|
|
9
|
+
|
|
15
10
|
import {
|
|
16
11
|
TeamRole,
|
|
17
|
-
SessionData,
|
|
18
12
|
TeamInfo,
|
|
19
13
|
TeamParticipant,
|
|
20
14
|
UserMessageData,
|
|
15
|
+
SessionDescriptor,
|
|
21
16
|
} from "../data/dataModels";
|
|
17
|
+
import { SessionFileDescriptor } from "../data/dbSessionFileModels";
|
|
18
|
+
import {
|
|
19
|
+
ChatCompletionAssistantMessageParam,
|
|
20
|
+
ChatCompletionMessageParam,
|
|
21
|
+
ChatCompletionMessageToolCall,
|
|
22
|
+
ChatCompletionToolMessageParam,
|
|
23
|
+
} from "../../agent/llm";
|
|
22
24
|
|
|
23
|
-
interface ClientToServerBase {
|
|
25
|
+
export interface ClientToServerBase {
|
|
24
26
|
type: string;
|
|
25
27
|
client_message_id: string; // TODO: hide by putting on ClientToServer?
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
// Session-level messages all have a `session_id`
|
|
29
|
-
interface ClientSessionMessageBase extends ClientToServerBase {
|
|
31
|
+
export interface ClientSessionMessageBase extends ClientToServerBase {
|
|
30
32
|
session_id: string;
|
|
31
33
|
}
|
|
32
34
|
|
|
@@ -127,6 +129,7 @@ export type ClientControlMessage =
|
|
|
127
129
|
|
|
128
130
|
export type ClientUserMessage = {
|
|
129
131
|
type: "msg";
|
|
132
|
+
race_mode?: boolean;
|
|
130
133
|
} & UserMessageData;
|
|
131
134
|
|
|
132
135
|
export type ClientSetWorkspace = {
|
|
@@ -173,6 +176,23 @@ export type ClientToolCallApprovalResult = {
|
|
|
173
176
|
auto_approve: boolean;
|
|
174
177
|
};
|
|
175
178
|
|
|
179
|
+
export type ClientSessionFileGetContent = {
|
|
180
|
+
type: "session_file_get_content";
|
|
181
|
+
name: string;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
export type ClientSessionFileDelete = {
|
|
185
|
+
type: "session_file_delete";
|
|
186
|
+
name: string;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export type ClientSessionFilePutContent = {
|
|
190
|
+
type: "session_file_put_content";
|
|
191
|
+
name?: string;
|
|
192
|
+
summary?: string;
|
|
193
|
+
data_url: string;
|
|
194
|
+
};
|
|
195
|
+
|
|
176
196
|
export type ClientSetAutoApproval = {
|
|
177
197
|
type: "set_auto_approval";
|
|
178
198
|
server_name: string;
|
|
@@ -190,12 +210,27 @@ export type ClientSetModel = {
|
|
|
190
210
|
model: string;
|
|
191
211
|
};
|
|
192
212
|
|
|
213
|
+
export type ClientSetAgentPaused = {
|
|
214
|
+
type: "set_agent_paused";
|
|
215
|
+
paused: boolean;
|
|
216
|
+
};
|
|
217
|
+
|
|
193
218
|
export type ClientSetMcpServerConfig = {
|
|
194
219
|
type: "set_mcp_server_config";
|
|
195
220
|
server_name: string;
|
|
196
221
|
config?: McpServerConfiguration;
|
|
197
222
|
};
|
|
198
223
|
|
|
224
|
+
export type ClientShareSession = {
|
|
225
|
+
type: "share_session";
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
export type ClientRaceModeResult = {
|
|
229
|
+
type: "race_mode_result";
|
|
230
|
+
message_id: string;
|
|
231
|
+
result: string;
|
|
232
|
+
} & UserMessageData;
|
|
233
|
+
|
|
199
234
|
export type ClientSessionMessageData =
|
|
200
235
|
| ClientUserMessage
|
|
201
236
|
| ClientSetWorkspace
|
|
@@ -206,10 +241,15 @@ export type ClientSessionMessageData =
|
|
|
206
241
|
| ClientEnableAllMcpServerTools
|
|
207
242
|
| ClientDisableAllMcpServerTools
|
|
208
243
|
| ClientToolCallApprovalResult
|
|
244
|
+
| ClientSessionFileGetContent
|
|
245
|
+
| ClientSessionFileDelete
|
|
246
|
+
| ClientSessionFilePutContent
|
|
209
247
|
| ClientSetAutoApproval
|
|
210
248
|
| ClientSetSystemPrompt
|
|
211
249
|
| ClientSetModel
|
|
212
|
-
|
|
|
250
|
+
| ClientSetAgentPaused
|
|
251
|
+
| ClientSetMcpServerConfig
|
|
252
|
+
| ClientShareSession;
|
|
213
253
|
|
|
214
254
|
export type ClientSessionMessage = ClientSessionMessageBase &
|
|
215
255
|
ClientSessionMessageData;
|
|
@@ -288,6 +328,7 @@ export type ServerSessionInfo = {
|
|
|
288
328
|
agent_preferences: AgentPreferences;
|
|
289
329
|
client_message_id: string;
|
|
290
330
|
team_uuid: string | undefined;
|
|
331
|
+
agent_paused: boolean;
|
|
291
332
|
} & ServerSessionMessage;
|
|
292
333
|
|
|
293
334
|
/**
|
|
@@ -307,6 +348,7 @@ export type ServerHistory = {
|
|
|
307
348
|
export type ServerUserMessage = {
|
|
308
349
|
type: "user_msg";
|
|
309
350
|
user_uuid: string;
|
|
351
|
+
user_nickname: string;
|
|
310
352
|
message_idx: number;
|
|
311
353
|
} & UserMessageData &
|
|
312
354
|
ServerSessionMessage;
|
|
@@ -321,9 +363,15 @@ export type ServerAgentMessageChunk = {
|
|
|
321
363
|
type: "agent_msg_chunk";
|
|
322
364
|
message: string;
|
|
323
365
|
message_idx: number;
|
|
366
|
+
alternative?: string;
|
|
324
367
|
end: boolean;
|
|
325
368
|
} & ServerSessionMessage;
|
|
326
369
|
|
|
370
|
+
export type ServerReasoningChunk = {
|
|
371
|
+
type: "agent_reasoning_chunk";
|
|
372
|
+
reasoning: string;
|
|
373
|
+
} & ServerSessionMessage;
|
|
374
|
+
|
|
327
375
|
//
|
|
328
376
|
// Notifications
|
|
329
377
|
///
|
|
@@ -339,11 +387,6 @@ export type ServerUserLeft = {
|
|
|
339
387
|
user_uuid: string;
|
|
340
388
|
} & ServerSessionMessage;
|
|
341
389
|
|
|
342
|
-
export type ServerSessionUpdate = {
|
|
343
|
-
type: "session_update";
|
|
344
|
-
title?: string;
|
|
345
|
-
participants?: TeamParticipant[];
|
|
346
|
-
} & ServerSessionMessage;
|
|
347
390
|
|
|
348
391
|
// Note: ChatCompletionMessageToolCall contains the tool call id so we don't
|
|
349
392
|
// need an extra id field.
|
|
@@ -394,7 +437,6 @@ export type ServerUserTyping = {
|
|
|
394
437
|
export type ServerToClientNotifications =
|
|
395
438
|
| ServerUserJoined
|
|
396
439
|
| ServerUserLeft
|
|
397
|
-
| ServerSessionUpdate
|
|
398
440
|
| ServerToolAutoApprovalSet
|
|
399
441
|
| ServerToolCall
|
|
400
442
|
| ServerToolCallApprovalResult
|
|
@@ -404,14 +446,35 @@ export type ServerToClientNotifications =
|
|
|
404
446
|
| ServerUserTyping;
|
|
405
447
|
|
|
406
448
|
//
|
|
407
|
-
//
|
|
449
|
+
// session-file related messages
|
|
408
450
|
//
|
|
409
451
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
452
|
+
export type ServerSessionFileChanged = {
|
|
453
|
+
type: "session_file_changed";
|
|
454
|
+
descriptor: SessionFileDescriptor;
|
|
455
|
+
new_file: boolean;
|
|
456
|
+
} & ServerSessionMessage;
|
|
457
|
+
|
|
458
|
+
export type ServerSessionFileDeleted = {
|
|
459
|
+
type: "session_file_deleted";
|
|
460
|
+
name: string;
|
|
461
|
+
} & ServerSessionMessage;
|
|
462
|
+
|
|
463
|
+
export type ServerSessionFileContent = {
|
|
464
|
+
type: "session_file_content";
|
|
465
|
+
name: string;
|
|
466
|
+
data_url: string;
|
|
467
|
+
client_message_id: string;
|
|
468
|
+
} & ServerSessionMessage;
|
|
469
|
+
|
|
470
|
+
export type ServerSessionFileMessage =
|
|
471
|
+
| ServerSessionFileChanged
|
|
472
|
+
| ServerSessionFileDeleted
|
|
473
|
+
| ServerSessionFileContent;
|
|
474
|
+
|
|
475
|
+
//
|
|
476
|
+
// state updates
|
|
477
|
+
//
|
|
415
478
|
export type ServerMcpServerAdded = {
|
|
416
479
|
type: "mcp_server_added";
|
|
417
480
|
server_name: string;
|
|
@@ -446,6 +509,11 @@ export type ServerModelUpdated = {
|
|
|
446
509
|
model: string;
|
|
447
510
|
} & ServerSessionMessage;
|
|
448
511
|
|
|
512
|
+
export type ServerAgentPaused = {
|
|
513
|
+
type: "agent_paused";
|
|
514
|
+
paused: boolean;
|
|
515
|
+
} & ServerSessionMessage;
|
|
516
|
+
|
|
449
517
|
export type ServerUserAdded = {
|
|
450
518
|
type: "user_added";
|
|
451
519
|
user_uuid: string;
|
|
@@ -459,6 +527,12 @@ export type ServerUserRemoved = {
|
|
|
459
527
|
user_uuid: string;
|
|
460
528
|
} & ServerSessionMessage;
|
|
461
529
|
|
|
530
|
+
export type ServerSessionShared = {
|
|
531
|
+
type: "session_shared";
|
|
532
|
+
access_token: string;
|
|
533
|
+
client_message_id: string;
|
|
534
|
+
} & ServerSessionMessage;
|
|
535
|
+
|
|
462
536
|
export type ServerToClientStateUpdate =
|
|
463
537
|
| ServerMcpServerAdded
|
|
464
538
|
| ServerMcpServerRemoved
|
|
@@ -466,8 +540,10 @@ export type ServerToClientStateUpdate =
|
|
|
466
540
|
| ServerMcpServerToolDisabled
|
|
467
541
|
| ServerSystemPromptUpdated
|
|
468
542
|
| ServerModelUpdated
|
|
543
|
+
| ServerAgentPaused
|
|
469
544
|
| ServerUserAdded
|
|
470
|
-
| ServerUserRemoved
|
|
545
|
+
| ServerUserRemoved
|
|
546
|
+
| ServerSessionShared;
|
|
471
547
|
|
|
472
548
|
//
|
|
473
549
|
// actions
|
|
@@ -523,12 +599,21 @@ export type ServerControlTeamCreated = {
|
|
|
523
599
|
failed_lookups: Array<string>;
|
|
524
600
|
};
|
|
525
601
|
|
|
602
|
+
/**
|
|
603
|
+
* Team members have been updated (added or removed).
|
|
604
|
+
*/
|
|
605
|
+
export type ServerControlTeamMembersUpdated = {
|
|
606
|
+
type: "control_team_members_updated";
|
|
607
|
+
team_uuid: string;
|
|
608
|
+
members: Array<TeamParticipant>;
|
|
609
|
+
};
|
|
610
|
+
|
|
526
611
|
/**
|
|
527
612
|
* List of available sessions for user
|
|
528
613
|
*/
|
|
529
614
|
export type ServerControlSessionList = {
|
|
530
615
|
type: "control_session_list";
|
|
531
|
-
user_sessions: Array<
|
|
616
|
+
user_sessions: Array<SessionDescriptor>;
|
|
532
617
|
user_agents: Array<SavedAgentProfile>;
|
|
533
618
|
team_sessions: Array<TeamInfo>;
|
|
534
619
|
} & ControlResponseMessage;
|
|
@@ -570,6 +655,7 @@ export type ServerControlMessage =
|
|
|
570
655
|
| ServerControlAgentProfileCreated
|
|
571
656
|
| ServerControlAgentProfileDeleted
|
|
572
657
|
| ServerControlTeamCreated
|
|
658
|
+
| ServerControlTeamMembersUpdated
|
|
573
659
|
| ServerControlError;
|
|
574
660
|
|
|
575
661
|
export type ServerSessionScopedMessage =
|
|
@@ -578,7 +664,9 @@ export type ServerSessionScopedMessage =
|
|
|
578
664
|
| ServerUserMessage
|
|
579
665
|
| ServerAgentMessage
|
|
580
666
|
| ServerAgentMessageChunk
|
|
667
|
+
| ServerReasoningChunk
|
|
581
668
|
| ServerToClientNotifications
|
|
669
|
+
| ServerSessionFileMessage
|
|
582
670
|
| ServerToClientStateUpdate
|
|
583
671
|
| ServerToClientActions;
|
|
584
672
|
|
|
@@ -599,6 +687,7 @@ export function isServerControlMessage(
|
|
|
599
687
|
case "control_session_left":
|
|
600
688
|
case "control_session_deleted":
|
|
601
689
|
case "control_team_created":
|
|
690
|
+
case "control_team_members_updated":
|
|
602
691
|
case "control_error":
|
|
603
692
|
return true;
|
|
604
693
|
default: {
|
|
@@ -608,6 +697,22 @@ export function isServerControlMessage(
|
|
|
608
697
|
}
|
|
609
698
|
}
|
|
610
699
|
|
|
700
|
+
export function isServerSessionFileMessage(
|
|
701
|
+
message: ServerToClient
|
|
702
|
+
): message is ServerSessionFileMessage {
|
|
703
|
+
const msg = message as ServerSessionFileMessage;
|
|
704
|
+
switch (msg.type) {
|
|
705
|
+
case "session_file_changed":
|
|
706
|
+
case "session_file_deleted":
|
|
707
|
+
case "session_file_content":
|
|
708
|
+
return true;
|
|
709
|
+
default: {
|
|
710
|
+
const _: never = msg;
|
|
711
|
+
return false;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
611
716
|
/**
|
|
612
717
|
* Type guard to check if a ServerToClient message is a session-scoped message
|
|
613
718
|
*/
|
|
@@ -621,9 +726,9 @@ export function isServerSessionScopedMessage(
|
|
|
621
726
|
case "user_msg":
|
|
622
727
|
case "agent_msg":
|
|
623
728
|
case "agent_msg_chunk":
|
|
729
|
+
case "agent_reasoning_chunk":
|
|
624
730
|
case "user_joined":
|
|
625
731
|
case "user_left":
|
|
626
|
-
case "session_update":
|
|
627
732
|
case "tool_auto_approval_set":
|
|
628
733
|
case "tool_call":
|
|
629
734
|
case "tool_call_approval_result":
|
|
@@ -631,18 +736,24 @@ export function isServerSessionScopedMessage(
|
|
|
631
736
|
case "authentication_started":
|
|
632
737
|
case "authentication_finished":
|
|
633
738
|
case "user_typing":
|
|
739
|
+
case "session_file_changed":
|
|
740
|
+
case "session_file_deleted":
|
|
741
|
+
case "session_file_content":
|
|
634
742
|
case "mcp_server_added":
|
|
635
743
|
case "mcp_server_removed":
|
|
636
744
|
case "mcp_server_tool_enabled":
|
|
637
745
|
case "mcp_server_tool_disabled":
|
|
638
746
|
case "system_prompt_updated":
|
|
639
747
|
case "model_updated":
|
|
748
|
+
case "agent_paused":
|
|
640
749
|
case "user_added":
|
|
641
750
|
case "user_removed":
|
|
642
751
|
case "authenticate":
|
|
643
752
|
case "approve_tool_call":
|
|
644
753
|
case "render_html":
|
|
754
|
+
case "session_shared":
|
|
645
755
|
return true;
|
|
756
|
+
|
|
646
757
|
default: {
|
|
647
758
|
const _: never = msg;
|
|
648
759
|
return false;
|
|
@@ -2,13 +2,13 @@ import { strict as assert } from "assert";
|
|
|
2
2
|
|
|
3
3
|
import { getLogger } from "@xalia/xmcp/sdk";
|
|
4
4
|
|
|
5
|
+
import { createUserMessage } from "../../agent/agent";
|
|
5
6
|
import {
|
|
6
7
|
ChatCompletionAssistantMessageParam,
|
|
7
8
|
ChatCompletionMessageParam,
|
|
8
9
|
ChatCompletionToolMessageParam,
|
|
9
10
|
ChatCompletionUserMessageParam,
|
|
10
|
-
|
|
11
|
-
} from "../../agent/agent";
|
|
11
|
+
} from "../../agent/llm";
|
|
12
12
|
import { IContextManager } from "../../agent/context";
|
|
13
13
|
import {
|
|
14
14
|
CompressingContextManager,
|
|
@@ -19,7 +19,6 @@ import {
|
|
|
19
19
|
ClientUserMessage,
|
|
20
20
|
ServerAgentMessage,
|
|
21
21
|
ServerAgentMessageChunk,
|
|
22
|
-
ServerSessionError,
|
|
23
22
|
ServerToolCallResult,
|
|
24
23
|
ServerUserMessage,
|
|
25
24
|
} from "../protocol/messages";
|
|
@@ -28,16 +27,18 @@ import {
|
|
|
28
27
|
MESSAGE_INDEX_FULL_INCREMENT,
|
|
29
28
|
MESSAGE_INDEX_SUB_INCREMENT,
|
|
30
29
|
chatMessagesToSessionMessages,
|
|
31
|
-
|
|
30
|
+
sessionMessagesToConversationMessages,
|
|
32
31
|
sessionMessagesToNextIndex,
|
|
33
32
|
} from "./conversation";
|
|
34
33
|
import {
|
|
35
34
|
ISessionFileManager,
|
|
36
35
|
ISessionFileManagerEventHandler,
|
|
37
|
-
SessionFileDescriptor,
|
|
38
|
-
SessionFileEntry,
|
|
39
36
|
listFilesForLLM,
|
|
40
37
|
} from "./sessionFileManager";
|
|
38
|
+
import {
|
|
39
|
+
SessionFileDescriptor,
|
|
40
|
+
SessionFileEntry,
|
|
41
|
+
} from "../data/dbSessionFileModels";
|
|
41
42
|
|
|
42
43
|
const logger = getLogger();
|
|
43
44
|
|
|
@@ -115,7 +116,7 @@ export class ChatContextManager
|
|
|
115
116
|
// Insert a system message placeholder into the context
|
|
116
117
|
|
|
117
118
|
this.sessionUUID = sessionUUID;
|
|
118
|
-
this.conversationMessages =
|
|
119
|
+
this.conversationMessages = sessionMessagesToConversationMessages(
|
|
119
120
|
sessionMessages,
|
|
120
121
|
defaultUserName,
|
|
121
122
|
sessionUUID
|
|
@@ -135,7 +136,7 @@ export class ChatContextManager
|
|
|
135
136
|
this.pendingCompression = false;
|
|
136
137
|
this.checkpointWriter = checkpointWriter;
|
|
137
138
|
this.fileManager = fileManager;
|
|
138
|
-
fileManager.
|
|
139
|
+
fileManager.addEventHandler(this);
|
|
139
140
|
this.fileManagerDescriptionsDirty = true;
|
|
140
141
|
}
|
|
141
142
|
|
|
@@ -188,7 +189,11 @@ export class ChatContextManager
|
|
|
188
189
|
}
|
|
189
190
|
|
|
190
191
|
// ISessionFileManagerEventHandler.onFileChange
|
|
191
|
-
|
|
192
|
+
onFileChanged(_entry: SessionFileEntry): void {
|
|
193
|
+
this.fileManagerDescriptionsDirty = true;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
onFileDeleted(_name: string): void {
|
|
192
197
|
this.fileManagerDescriptionsDirty = true;
|
|
193
198
|
}
|
|
194
199
|
|
|
@@ -205,17 +210,27 @@ export class ChatContextManager
|
|
|
205
210
|
return this.conversationMessages.concat(this.pendingUserMessages);
|
|
206
211
|
}
|
|
207
212
|
|
|
208
|
-
processUserMessage(
|
|
213
|
+
processUserMessage(
|
|
214
|
+
msg: ClientUserMessage,
|
|
215
|
+
from_uuid: string,
|
|
216
|
+
from_nickname: string
|
|
217
|
+
): ServerUserMessage | undefined {
|
|
209
218
|
// TODO: maintain a queue internally instead of relying on the caller to
|
|
210
219
|
// pass in our generated messages back into `startAgentResponse`.
|
|
211
220
|
|
|
221
|
+
// Filter out null messages immediately.
|
|
222
|
+
if (!msg.imageB64 && !msg.message) {
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
|
|
212
226
|
const message_idx = this.getNextMessageIdx();
|
|
213
227
|
const userMessage: ServerUserMessage = {
|
|
214
228
|
type: "user_msg",
|
|
215
229
|
session_id: this.sessionUUID,
|
|
216
230
|
message_idx,
|
|
217
231
|
message: msg.message,
|
|
218
|
-
user_uuid:
|
|
232
|
+
user_uuid: from_uuid,
|
|
233
|
+
user_nickname: from_nickname,
|
|
219
234
|
};
|
|
220
235
|
if (msg.imageB64) {
|
|
221
236
|
userMessage.imageB64 = msg.imageB64;
|
|
@@ -274,7 +289,7 @@ export class ChatContextManager
|
|
|
274
289
|
const userMsg = createUserMessage(
|
|
275
290
|
msg.message,
|
|
276
291
|
msg.imageB64,
|
|
277
|
-
msg.
|
|
292
|
+
msg.user_nickname
|
|
278
293
|
);
|
|
279
294
|
if (userMsg) {
|
|
280
295
|
llmUserMessages.push(userMsg);
|
|
@@ -294,12 +309,21 @@ export class ChatContextManager
|
|
|
294
309
|
}
|
|
295
310
|
|
|
296
311
|
endAgentResponse(): SessionMessage[] {
|
|
297
|
-
assert(
|
|
298
|
-
|
|
299
|
-
|
|
312
|
+
assert(
|
|
313
|
+
typeof this.startingLLMContextLength !== "undefined",
|
|
314
|
+
"agent response not started (startingLLMContextLength)"
|
|
315
|
+
);
|
|
316
|
+
assert(
|
|
317
|
+
typeof this.pendingMessages !== "undefined",
|
|
318
|
+
"agent response not started (pendingMessages)"
|
|
319
|
+
);
|
|
320
|
+
assert(
|
|
321
|
+
typeof this.curAgentMsgIdx !== "undefined",
|
|
322
|
+
"agent response not started (curAgentMsgIdx)"
|
|
323
|
+
);
|
|
300
324
|
|
|
301
325
|
const numPending = this.pendingMessages.length;
|
|
302
|
-
assert(numPending >
|
|
326
|
+
assert(numPending > 0, "no pending"); // at least 1 user message
|
|
303
327
|
|
|
304
328
|
// Compute DB messages
|
|
305
329
|
|
|
@@ -343,7 +367,7 @@ export class ChatContextManager
|
|
|
343
367
|
if (JSON.stringify(sMsg.content) !== JSON.stringify(lMsg)) {
|
|
344
368
|
messageListError(
|
|
345
369
|
`newSessionMessages[${String(i)}].content !== ` +
|
|
346
|
-
`newLLMMessages[${String(i)}]
|
|
370
|
+
`newLLMMessages[${String(i)}]`
|
|
347
371
|
);
|
|
348
372
|
}
|
|
349
373
|
if (sMsg.message_idx !== pMsg.message_idx) {
|
|
@@ -376,7 +400,7 @@ export class ChatContextManager
|
|
|
376
400
|
* This function checks that nothing has been entered into the LLM context,
|
|
377
401
|
* and drops any new user messages or responses before the error.
|
|
378
402
|
*/
|
|
379
|
-
revertAgentResponse(errMsg: string):
|
|
403
|
+
revertAgentResponse(errMsg: string): void {
|
|
380
404
|
logger.warn(`[ChatContextManager.revertAgentResponse] error: ${errMsg}`);
|
|
381
405
|
|
|
382
406
|
assert(typeof this.startingLLMContextLength !== "undefined");
|
|
@@ -402,12 +426,6 @@ export class ChatContextManager
|
|
|
402
426
|
this.startingLLMContextLength = undefined;
|
|
403
427
|
this.pendingMessages = undefined;
|
|
404
428
|
this.curAgentMsgIdx = undefined;
|
|
405
|
-
|
|
406
|
-
return {
|
|
407
|
-
type: "session_error",
|
|
408
|
-
session_id: this.sessionUUID,
|
|
409
|
-
message: errMsg,
|
|
410
|
-
};
|
|
411
429
|
}
|
|
412
430
|
|
|
413
431
|
processAgentMessage(msg: string, end: boolean): ServerAgentMessageChunk {
|
|
@@ -43,7 +43,6 @@ describe("ConnectionManager", () => {
|
|
|
43
43
|
// we need to use type assertion
|
|
44
44
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
45
|
connectionManager = new (ConnectionManager as any)(
|
|
46
|
-
mockApiKeyManager.mock,
|
|
47
46
|
mockSessionRegistry.mock
|
|
48
47
|
);
|
|
49
48
|
});
|
|
@@ -63,7 +62,7 @@ describe("ConnectionManager", () => {
|
|
|
63
62
|
// Wait for deferred send
|
|
64
63
|
await new Promise((resolve) => setImmediate(resolve));
|
|
65
64
|
|
|
66
|
-
expect(
|
|
65
|
+
expect(mockSessionRegistry.spies.authenticate).toHaveBeenCalledWith(
|
|
67
66
|
"valid-api-key"
|
|
68
67
|
);
|
|
69
68
|
expect(mockWebSocket.spies.send).toHaveBeenCalledWith(
|
|
@@ -118,6 +117,7 @@ describe("ConnectionManager", () => {
|
|
|
118
117
|
d: {
|
|
119
118
|
type: "user_msg",
|
|
120
119
|
user_uuid: "user_1",
|
|
120
|
+
user_nickname: "User 1",
|
|
121
121
|
session_id: "session_1",
|
|
122
122
|
message: "message text",
|
|
123
123
|
message_idx: 12,
|
|
@@ -136,18 +136,6 @@ describe("ConnectionManager", () => {
|
|
|
136
136
|
JSON.stringify(testMessage)
|
|
137
137
|
);
|
|
138
138
|
});
|
|
139
|
-
|
|
140
|
-
it("should return API key for connected user", () => {
|
|
141
|
-
const apiKey = connectionManager.getLiveUserApiKey(MOCK_USERS.owner.uuid);
|
|
142
|
-
expect(apiKey).toBe("valid-api-key");
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it("should return undefined for non-existent user", () => {
|
|
146
|
-
const apiKey = connectionManager.getLiveUserApiKey(
|
|
147
|
-
MOCK_USERS.nonExistent.uuid
|
|
148
|
-
);
|
|
149
|
-
expect(apiKey).toBeUndefined();
|
|
150
|
-
});
|
|
151
139
|
});
|
|
152
140
|
|
|
153
141
|
describe("connection cleanup", () => {
|
|
@@ -169,10 +157,6 @@ describe("ConnectionManager", () => {
|
|
|
169
157
|
const closeHandler = closeHandlerCall[1];
|
|
170
158
|
closeHandler();
|
|
171
159
|
}
|
|
172
|
-
|
|
173
|
-
// After cleanup, API key should no longer be available
|
|
174
|
-
const apiKey = connectionManager.getLiveUserApiKey(MOCK_USERS.owner.uuid);
|
|
175
|
-
expect(apiKey).toBeUndefined();
|
|
176
160
|
});
|
|
177
161
|
|
|
178
162
|
it("should clean up connection state on error", () => {
|
|
@@ -186,10 +170,6 @@ describe("ConnectionManager", () => {
|
|
|
186
170
|
const errorHandler = errorHandlerCall[1];
|
|
187
171
|
errorHandler(new Error("WebSocket error"));
|
|
188
172
|
}
|
|
189
|
-
|
|
190
|
-
// After cleanup, API key should no longer be available
|
|
191
|
-
const apiKey = connectionManager.getLiveUserApiKey(MOCK_USERS.owner.uuid);
|
|
192
|
-
expect(apiKey).toBeUndefined();
|
|
193
173
|
});
|
|
194
174
|
});
|
|
195
175
|
|