@xalia/agent 0.6.10 → 0.6.11

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.
Files changed (161) hide show
  1. package/package.json +5 -2
  2. package/.env.development +0 -6
  3. package/.env.test +0 -7
  4. package/.prettierrc.json +0 -11
  5. package/context_system.md +0 -498
  6. package/eslint.config.mjs +0 -38
  7. package/scripts/chat_server +0 -8
  8. package/scripts/git_message +0 -31
  9. package/scripts/git_wip +0 -21
  10. package/scripts/pr_message +0 -18
  11. package/scripts/pr_review +0 -16
  12. package/scripts/setup_chat +0 -90
  13. package/scripts/shutdown_chat_server +0 -42
  14. package/scripts/start_chat_server +0 -24
  15. package/scripts/sudomcp_import +0 -23
  16. package/scripts/test_chat +0 -327
  17. package/src/agent/agent.ts +0 -699
  18. package/src/agent/agentUtils.ts +0 -286
  19. package/src/agent/compressingContextManager.ts +0 -129
  20. package/src/agent/context.ts +0 -265
  21. package/src/agent/contextWithWorkspace.ts +0 -162
  22. package/src/agent/documentSummarizer.ts +0 -157
  23. package/src/agent/dummyLLM.ts +0 -130
  24. package/src/agent/iAgentEventHandler.ts +0 -64
  25. package/src/agent/imageGenLLM.ts +0 -101
  26. package/src/agent/imageGenerator.ts +0 -45
  27. package/src/agent/iplatform.ts +0 -18
  28. package/src/agent/llm.ts +0 -74
  29. package/src/agent/mcpServerManager.ts +0 -541
  30. package/src/agent/nullAgentEventHandler.ts +0 -26
  31. package/src/agent/nullPlatform.ts +0 -13
  32. package/src/agent/openAI.ts +0 -123
  33. package/src/agent/openAILLM.ts +0 -99
  34. package/src/agent/openAILLMStreaming.ts +0 -648
  35. package/src/agent/promptProvider.ts +0 -87
  36. package/src/agent/repeatLLM.ts +0 -62
  37. package/src/agent/sudoMcpServerManager.ts +0 -361
  38. package/src/agent/test_data/harrypotter.txt +0 -6065
  39. package/src/agent/tokenAuth.ts +0 -50
  40. package/src/agent/tokenCounter.test.ts +0 -243
  41. package/src/agent/tokenCounter.ts +0 -483
  42. package/src/agent/toolSettings.ts +0 -24
  43. package/src/agent/tools/calculatorTool.ts +0 -50
  44. package/src/agent/tools/contentExtractors/htmlToText.ts +0 -61
  45. package/src/agent/tools/contentExtractors/pdfToText.ts +0 -60
  46. package/src/agent/tools/datetimeTool.ts +0 -41
  47. package/src/agent/tools/fileManager/fileManagerTool.ts +0 -199
  48. package/src/agent/tools/fileManager/index.ts +0 -50
  49. package/src/agent/tools/fileManager/memoryFileManager.ts +0 -120
  50. package/src/agent/tools/fileManager/mimeTypes.ts +0 -60
  51. package/src/agent/tools/fileManager/prompt.ts +0 -38
  52. package/src/agent/tools/fileManager/types.ts +0 -189
  53. package/src/agent/tools/index.ts +0 -49
  54. package/src/agent/tools/openUrlTool.ts +0 -62
  55. package/src/agent/tools/renderTool.ts +0 -92
  56. package/src/agent/tools/utils.ts +0 -74
  57. package/src/agent/tools/webSearch.ts +0 -138
  58. package/src/agent/tools/webSearchTool.ts +0 -44
  59. package/src/chat/client/chatClient.ts +0 -967
  60. package/src/chat/client/connection.test.ts +0 -241
  61. package/src/chat/client/connection.ts +0 -286
  62. package/src/chat/client/constants.ts +0 -1
  63. package/src/chat/client/index.ts +0 -21
  64. package/src/chat/client/interfaces.ts +0 -34
  65. package/src/chat/client/sessionClient.ts +0 -574
  66. package/src/chat/client/sessionFiles.ts +0 -142
  67. package/src/chat/client/teamManager.ts +0 -29
  68. package/src/chat/constants.ts +0 -6
  69. package/src/chat/data/apiKeyManager.ts +0 -76
  70. package/src/chat/data/dataModels.ts +0 -107
  71. package/src/chat/data/database.ts +0 -997
  72. package/src/chat/data/dbMcpServerConfigs.ts +0 -59
  73. package/src/chat/data/dbSessionFiles.ts +0 -107
  74. package/src/chat/data/dbSessionMessages.ts +0 -102
  75. package/src/chat/protocol/connectionMessages.ts +0 -49
  76. package/src/chat/protocol/constants.ts +0 -55
  77. package/src/chat/protocol/errors.ts +0 -16
  78. package/src/chat/protocol/messages.ts +0 -899
  79. package/src/chat/server/README.md +0 -127
  80. package/src/chat/server/chatContextManager.ts +0 -660
  81. package/src/chat/server/connectionManager.test.ts +0 -246
  82. package/src/chat/server/connectionManager.ts +0 -506
  83. package/src/chat/server/conversation.ts +0 -319
  84. package/src/chat/server/errorUtils.ts +0 -28
  85. package/src/chat/server/imageGeneratorTools.ts +0 -179
  86. package/src/chat/server/openAIRouterLLM.ts +0 -168
  87. package/src/chat/server/openSession.ts +0 -1945
  88. package/src/chat/server/openSessionMessageSender.ts +0 -4
  89. package/src/chat/server/promptRefiner.ts +0 -106
  90. package/src/chat/server/server.ts +0 -178
  91. package/src/chat/server/sessionFileManager.ts +0 -151
  92. package/src/chat/server/sessionRegistry.test.ts +0 -137
  93. package/src/chat/server/sessionRegistry.ts +0 -1553
  94. package/src/chat/server/test-utils/mockFactories.ts +0 -422
  95. package/src/chat/server/titleGenerator.test.ts +0 -103
  96. package/src/chat/server/titleGenerator.ts +0 -143
  97. package/src/chat/server/tools.ts +0 -170
  98. package/src/chat/utils/agentSessionMap.ts +0 -76
  99. package/src/chat/utils/approvalManager.ts +0 -189
  100. package/src/chat/utils/asyncLock.ts +0 -43
  101. package/src/chat/utils/asyncQueue.ts +0 -62
  102. package/src/chat/utils/multiAsyncQueue.ts +0 -66
  103. package/src/chat/utils/responseAwaiter.ts +0 -181
  104. package/src/chat/utils/userResolver.ts +0 -48
  105. package/src/chat/utils/websocket.ts +0 -16
  106. package/src/index.ts +0 -0
  107. package/src/test/agent.test.ts +0 -584
  108. package/src/test/approvalManager.test.ts +0 -141
  109. package/src/test/chatContextManager.test.ts +0 -552
  110. package/src/test/clientServerConnection.test.ts +0 -205
  111. package/src/test/compressingContextManager.test.ts +0 -77
  112. package/src/test/context.test.ts +0 -150
  113. package/src/test/contextTestTools.ts +0 -95
  114. package/src/test/conversation.test.ts +0 -109
  115. package/src/test/db.test.ts +0 -363
  116. package/src/test/dbMcpServerConfigs.test.ts +0 -112
  117. package/src/test/dbSessionFiles.test.ts +0 -258
  118. package/src/test/dbSessionMessages.test.ts +0 -85
  119. package/src/test/dbTestTools.ts +0 -157
  120. package/src/test/imageLoad.test.ts +0 -15
  121. package/src/test/mcpServerManager.test.ts +0 -114
  122. package/src/test/multiAsyncQueue.test.ts +0 -183
  123. package/src/test/openaiStreaming.test.ts +0 -177
  124. package/src/test/prompt.test.ts +0 -27
  125. package/src/test/promptProvider.test.ts +0 -33
  126. package/src/test/responseAwaiter.test.ts +0 -103
  127. package/src/test/sudoMcpServerManager.test.ts +0 -63
  128. package/src/test/testTools.ts +0 -176
  129. package/src/test/tools.test.ts +0 -64
  130. package/src/tool/agentChat.ts +0 -203
  131. package/src/tool/agentMain.ts +0 -180
  132. package/src/tool/chatMain.ts +0 -621
  133. package/src/tool/commandPrompt.ts +0 -264
  134. package/src/tool/files.ts +0 -82
  135. package/src/tool/main.ts +0 -25
  136. package/src/tool/nodePlatform.ts +0 -73
  137. package/src/tool/options.ts +0 -144
  138. package/src/tool/prompt.ts +0 -101
  139. package/test_data/background_test_profile.json +0 -6
  140. package/test_data/background_test_script.json +0 -11
  141. package/test_data/dummyllm_script_crash.json +0 -32
  142. package/test_data/dummyllm_script_image_gen.json +0 -19
  143. package/test_data/dummyllm_script_image_gen_fe.json +0 -29
  144. package/test_data/dummyllm_script_invoke_image_gen_tool.json +0 -37
  145. package/test_data/dummyllm_script_render_tool.json +0 -29
  146. package/test_data/dummyllm_script_simplecalc.json +0 -28
  147. package/test_data/dummyllm_script_test_auto_approve.json +0 -81
  148. package/test_data/dummyllm_script_test_simplecalc_addition.json +0 -29
  149. package/test_data/frog.png +0 -0
  150. package/test_data/frog.png.b64 +0 -1
  151. package/test_data/git_message_profile.json +0 -4
  152. package/test_data/git_wip_system.txt +0 -5
  153. package/test_data/image_gen_test_profile.json +0 -5
  154. package/test_data/pr_message_profile.json +0 -4
  155. package/test_data/pr_review_profile.json +0 -4
  156. package/test_data/prompt_simplecalc.txt +0 -1
  157. package/test_data/simplecalc_profile.json +0 -4
  158. package/test_data/sudomcp_import_profile.json +0 -4
  159. package/test_data/test_script_profile.json +0 -8
  160. package/tsconfig.json +0 -13
  161. package/vitest.config.ts +0 -39
@@ -1,205 +0,0 @@
1
- import { describe, it, expect, beforeAll, afterAll, vi } from "vitest";
2
- import { Server } from "ws";
3
- import { Connection } from "../chat/client/connection";
4
- import { runServer } from "../chat/server/server";
5
- import { Database } from "../chat/data/database";
6
- import { getLogger } from "@xalia/xmcp/sdk";
7
- import { SUPABASE_LOCAL_KEY, SUPABASE_LOCAL_URL } from "../chat/data/database";
8
- import {
9
- ClientControlGetSessionList,
10
- ServerControlSessionList,
11
- } from "../chat/protocol/messages";
12
- import { userSessionCreateData } from "../chat/server/sessionRegistry";
13
-
14
- // Mock uuid to have predictable client message IDs
15
- vi.mock("uuid", () => ({
16
- v4: () => "mock-uuid-123",
17
- }));
18
-
19
- const logger = getLogger();
20
-
21
- describe("Client-Server WebSocket Integration", () => {
22
- let server: Server;
23
- let db: Database;
24
- const serverPort = 5105; // Different port to avoid conflicts
25
- // Test API key data
26
- const testApiKey = "integration_test";
27
- const testUserUuid = "test_user_0";
28
- const testUserName = "default";
29
- const testScopes: string[] = [];
30
- // Mock environment variables for server
31
- const mockEnv = {
32
- SUPABASE_URL: SUPABASE_LOCAL_URL,
33
- SUPABASE_KEY: SUPABASE_LOCAL_KEY,
34
- XMCP_URL: "http://localhost:8081", // not used in this test
35
- };
36
- beforeAll(async () => {
37
- // Set up environment variables
38
- Object.assign(process.env, mockEnv);
39
- // Initialize database connection
40
- db = new Database(mockEnv.SUPABASE_URL, mockEnv.SUPABASE_KEY);
41
- // Try to insert test data, but don't fail if there are database issues
42
- try {
43
- await cleanupTestData();
44
- await insertTestApiKey();
45
- logger.info("[Test] Test data setup completed successfully");
46
- } catch (error) {
47
- logger.warn(
48
- "[Test] Test data setup failed - will test with existing data:",
49
- error
50
- );
51
- }
52
- // Start the real server using runServer
53
- server = await runServer(
54
- serverPort,
55
- mockEnv.SUPABASE_URL,
56
- mockEnv.SUPABASE_KEY,
57
- mockEnv.XMCP_URL
58
- );
59
- // Wait for server to be ready
60
- await new Promise((resolve) => setTimeout(resolve, 500));
61
- });
62
- async function cleanupTestData() {
63
- try {
64
- // Delete test API key first (foreign key constraint)
65
- await db
66
- .getClientForTesting()
67
- .from("api_keys")
68
- .delete()
69
- .eq("api_key", testApiKey);
70
- // Delete test user
71
- await db
72
- .getClientForTesting()
73
- .from("users")
74
- .delete()
75
- .eq("uuid", testUserUuid);
76
- logger.info("[Test] Cleaned up existing test data");
77
- } catch (error) {
78
- logger.warn(
79
- "[Test] Error during cleanup (expected if no data exists):",
80
- error
81
- );
82
- }
83
- }
84
- async function insertTestApiKey() {
85
- try {
86
- // Use Database class methods which include timezone handling
87
- await db.createUser(
88
- testUserUuid,
89
- "test@example.com",
90
- testUserName,
91
- "UTC"
92
- );
93
- logger.info("[Test] User created successfully");
94
- await db.addApiKey(
95
- testUserUuid,
96
- testApiKey,
97
- testUserName,
98
- testScopes,
99
- true // is_default
100
- );
101
- } catch (error) {
102
- logger.error("[Test] Database method insert failed:", error);
103
- throw error;
104
- }
105
- }
106
- afterAll(async () => {
107
- // Clean up test data
108
- await cleanupTestData();
109
- // Close server
110
- server.close();
111
- });
112
- describe("Connection Setup and List Sessions", () => {
113
- it("should establish connection with valid API key", async () => {
114
- // Inject test agent profiles and sessions into the database
115
- const agentProfile1 = await db.createAgentProfile(
116
- testUserUuid,
117
- undefined,
118
- "Test agent profile 1",
119
- {
120
- model: undefined,
121
- system_prompt: "You are a test agent",
122
- mcp_settings: {},
123
- }
124
- );
125
- const agentProfile2 = await db.createAgentProfile(
126
- testUserUuid,
127
- undefined,
128
- "Test agent profile 2",
129
- {
130
- model: undefined,
131
- system_prompt: "You are a test agent",
132
- mcp_settings: {},
133
- }
134
- );
135
- if (!agentProfile1 || !agentProfile2) {
136
- throw new Error("Failed to create agent profiles");
137
- }
138
- const agentProfile1Id = agentProfile1.uuid;
139
- const agentProfile2Id = agentProfile2.uuid;
140
- const session1CreateData = userSessionCreateData(
141
- testUserUuid,
142
- "Test Session 1",
143
- agentProfile1Id
144
- );
145
- const session1Id = session1CreateData.session_uuid;
146
- await db.sessionCreate(session1CreateData);
147
- const session2CreateData = userSessionCreateData(
148
- testUserUuid,
149
- "Test Session 2",
150
- agentProfile2Id
151
- );
152
- const session2Id = session2CreateData.session_uuid;
153
- await db.sessionCreate(session2CreateData);
154
- // Log session creation for debugging
155
- logger.info(`[Test] Created sessions: ${session1Id}, ${session2Id}`);
156
- const client = new Connection({
157
- url: `ws://localhost:${String(serverPort)}`,
158
- token: testApiKey,
159
- });
160
- // Wait for session_list response
161
- const responsePromise = new Promise<ServerControlSessionList>(
162
- (resolve) => {
163
- client.on("control_session_list", (msg) => {
164
- resolve(msg as ServerControlSessionList);
165
- });
166
- }
167
- );
168
- await client.connect();
169
- expect(client.getState()).toBe("ready");
170
- client.send({
171
- type: "control_get_session_list",
172
- client_message_id: "test-msg-id",
173
- } as ClientControlGetSessionList);
174
- const response = await responsePromise;
175
- expect(response.type).toBe("control_session_list");
176
- expect(response.user_sessions).toBeDefined();
177
- expect(response.user_sessions.length).toBe(2);
178
- // Verify session details
179
- const sessionIds = response.user_sessions.map((s) => s.session_uuid);
180
- expect(sessionIds).toContain(session1Id);
181
- expect(sessionIds).toContain(session2Id);
182
- const session1Data = response.user_sessions.find(
183
- (s) => s.session_uuid === session1Id
184
- );
185
- expect(session1Data?.title).toBe("Test Session 1");
186
- const session2Data = response.user_sessions.find(
187
- (s) => s.session_uuid === session2Id
188
- );
189
- expect(session2Data?.title).toBe("Test Session 2");
190
- client.close();
191
- }, 15000);
192
- });
193
- describe("Authentication Error Handling", () => {
194
- it("should handle invalid API key gracefully", async () => {
195
- const invalidApiKey = "invalid-test-key";
196
- const client = new Connection({
197
- url: `ws://localhost:${String(serverPort)}`,
198
- token: invalidApiKey,
199
- });
200
- await expect(client.connect()).rejects.toThrow();
201
- expect(client.getState()).toBe("closed");
202
- client.close();
203
- }, 4000);
204
- });
205
- });
@@ -1,77 +0,0 @@
1
- import { expect } from "vitest";
2
-
3
- import {
4
- CompressingContextManager,
5
- createCheckpointMessage,
6
- } from "../agent/compressingContextManager";
7
- import { ILLM, MessageParam, UserMessageParam } from "../agent/llm";
8
- import { MESSAGES, basicContextTest } from "./contextTestTools";
9
- import { createLLM } from "../agent/agentUtils";
10
- import { IPlatform } from "../agent/iplatform";
11
-
12
- describe("Compression context", () => {
13
- it("context compression (basic)", async function () {
14
- const ccm = new CompressingContextManager(
15
- "sys_prompt",
16
- [],
17
- () => undefined as unknown as Promise<ILLM> // getLLM
18
- );
19
- await basicContextTest(ccm);
20
- });
21
-
22
- it("context compression", async function () {
23
- const llm = await createLLM(
24
- "",
25
- "",
26
- "repeat",
27
- false,
28
- undefined as unknown as IPlatform
29
- );
30
- const ccm = new CompressingContextManager("sys_prompt", [], () =>
31
- Promise.resolve(llm)
32
- );
33
-
34
- // Add first 2 messages
35
- let tx = await ccm.startTx([MESSAGES[0] as UserMessageParam]);
36
- tx.addMessage(MESSAGES[1]);
37
- await ccm.commit(tx);
38
-
39
- // Start the compression
40
- const compressionP = ccm.compress();
41
-
42
- // Add more messages and update system prompt
43
- tx = await ccm.startTx([MESSAGES[2] as UserMessageParam]);
44
- tx.addMessages(MESSAGES.slice(3));
45
- await ccm.commit(tx);
46
- ccm.setAgentPrompt("New system prompt");
47
-
48
- // Wait for compression to complete, then get the new context
49
- const summary = await compressionP;
50
- const context = ccm.getLLMContext();
51
-
52
- // Expect
53
- // - callback happened
54
- // - new context is as expected
55
-
56
- const expectSummary = "Message number 0";
57
- const expectContext: MessageParam[] = [
58
- {
59
- role: "system",
60
- content: "New system prompt",
61
- },
62
- createCheckpointMessage(expectSummary),
63
- MESSAGES[2], // 400
64
- MESSAGES[3], // 500
65
- MESSAGES[4], // 501
66
- MESSAGES[5], // 502
67
- ];
68
-
69
- expect(summary).eql(expectSummary);
70
- expect(context).eql(expectContext);
71
-
72
- // // Pending messages should still be intact
73
-
74
- // const pending = ccm.getPending();
75
- // expect(pending).eql(MESSAGES.slice(2));
76
- });
77
- });
@@ -1,150 +0,0 @@
1
- import { expect } from "vitest";
2
- import { strict as assert } from "assert";
3
-
4
- import { ContextManagerWithWorkspace } from "../agent/contextWithWorkspace";
5
- import { createUserMessage } from "../agent/agent";
6
- import { MessageParam, UserMessageParam } from "../agent/llm";
7
- import { SystemPromptProvider } from "../agent/promptProvider";
8
- import { ContextManager } from "../agent/context";
9
- import { basicContextTest } from "./contextTestTools";
10
-
11
- describe("ContextManagerWithWorkspace", () => {
12
- const msgs: MessageParam[] = [
13
- { role: "user", content: "message A" },
14
- { role: "assistant", content: "message B" },
15
- { role: "user", content: "message C" },
16
- { role: "assistant", content: "message D" },
17
- ];
18
-
19
- it("context (basic)", async function () {
20
- const cm = new ContextManager("sys_prompt", []);
21
- await basicContextTest(cm);
22
- });
23
-
24
- it("context with workspace (basic)", async function () {
25
- const cm = new ContextManagerWithWorkspace("sys_prompt", []);
26
- await basicContextTest(cm);
27
- });
28
-
29
- it("should correctly manage messages", async function () {
30
- const cm = new ContextManagerWithWorkspace("sys_msg", msgs.slice(0, 2));
31
-
32
- // set workspace and add new user and assistant messages
33
- cm.setWorkspace({ role: "user", content: "workspace1" });
34
-
35
- const ctxTx1 = await cm.startTx([msgs[2] as UserMessageParam]);
36
- ctxTx1.addMessage(msgs[3]);
37
-
38
- // context writer. workspace should be before first assistant message
39
- expect(ctxTx1.getLLMContext()).eql([
40
- { role: "system", content: "sys_msg" },
41
- ...msgs.slice(0, 3),
42
- { role: "user", content: "workspace1" },
43
- ...msgs.slice(3),
44
- ]);
45
-
46
- // original cm unchanged
47
- expect(cm.getLLMContext()).eql([
48
- { role: "system", content: "sys_msg" },
49
- ...msgs.slice(0, 2),
50
- { role: "user", content: "workspace1" },
51
- ]);
52
-
53
- // Commit
54
- await cm.commit(ctxTx1);
55
-
56
- // write new messages
57
- const lastMsg: MessageParam = {
58
- role: "user",
59
- content: "hello",
60
- };
61
- const ctxTx2 = await cm.startTx([lastMsg]);
62
- expect(ctxTx2.getLLMContext()).eql([
63
- { role: "system", content: "sys_msg" },
64
- ...msgs,
65
- lastMsg,
66
- { role: "user", content: "workspace1" },
67
- ]);
68
- expect(cm.getLLMContext()).eql([
69
- { role: "system", content: "sys_msg" },
70
- ...msgs,
71
- { role: "user", content: "workspace1" },
72
- ]);
73
- await cm.commit(ctxTx2);
74
-
75
- // context without workspace
76
- cm.setWorkspace(undefined);
77
- const ctx3 = cm.getLLMContext();
78
- expect(ctx3).eql([
79
- { role: "system", content: "sys_msg" },
80
- ...msgs,
81
- lastMsg,
82
- ]);
83
- });
84
-
85
- it("correctly includes all system prompt components", function () {
86
- const cm = new ContextManagerWithWorkspace(
87
- "agent_prompt",
88
- msgs.slice(0, 2)
89
- );
90
- SystemPromptProvider.setGlobalPrompt("global");
91
- cm.setPromptFragment("frag1", "FRAG1");
92
-
93
- // Get the agentPrompt and llmContext, then undo the global prompt change
94
- // (to ensure other tests are affected, even if this one fails).
95
-
96
- const agentPrompt = cm.getAgentPrompt();
97
- const llmContext = cm.getLLMContext();
98
- SystemPromptProvider.setGlobalPrompt(undefined);
99
-
100
- expect(agentPrompt).eql("agent_prompt");
101
- expect(llmContext[0].content).eql("global\nagent_prompt\nFRAG1");
102
- });
103
-
104
- it("handles rich workspace messages", async function () {
105
- const cm = new ContextManagerWithWorkspace("sys_msg", msgs.slice(0, 2));
106
-
107
- expect(cm.getLLMContext()).eql([
108
- { role: "system", content: "sys_msg" },
109
- ...msgs.slice(0, 2),
110
- ]);
111
-
112
- // set workspace and add new messages
113
- const wsMsg = createUserMessage(
114
- "text",
115
- "data:image/png;base64;adsfadsfadf",
116
- "user_name"
117
- );
118
- assert(wsMsg);
119
- assert(wsMsg.content);
120
- assert(typeof wsMsg.content !== "string");
121
- cm.setWorkspace(wsMsg);
122
-
123
- expect(cm.getLLMContext()).eql([
124
- { role: "system", content: "sys_msg" },
125
- ...msgs.slice(0, 2),
126
- wsMsg,
127
- ]);
128
-
129
- const ctxTx = await cm.startTx([msgs[2] as UserMessageParam]);
130
- expect(ctxTx.getLLMContext()).eql([
131
- { role: "system", content: "sys_msg" },
132
- ...msgs.slice(0, 3),
133
- wsMsg,
134
- ]);
135
- ctxTx.addMessage(msgs[3]);
136
- expect(ctxTx.getLLMContext()).eql([
137
- { role: "system", content: "sys_msg" },
138
- ...msgs.slice(0, 3),
139
- wsMsg,
140
- msgs[3],
141
- ]);
142
- expect(ctxTx.newMessages()).eql(msgs.slice(2, 4));
143
-
144
- await cm.commit(ctxTx);
145
-
146
- // context with workspace
147
- const ctx1 = cm.getLLMContext();
148
- expect(ctx1).eql([{ role: "system", content: "sys_msg" }, ...msgs, wsMsg]);
149
- });
150
- });
@@ -1,95 +0,0 @@
1
- import { expect } from "vitest";
2
-
3
- import { IContextManager } from "../agent/context";
4
- import { MessageParam, UserMessageParam } from "../agent/llm";
5
-
6
- export const MESSAGES: MessageParam[] = [
7
- { role: "user", content: "msg200" },
8
- { role: "assistant", content: "msg300" },
9
- { role: "user", content: "msg400" },
10
- {
11
- role: "assistant",
12
- content: "msg500",
13
- tool_calls: [
14
- {
15
- id: "tool_call_0",
16
- type: "function",
17
- function: { name: "tool1", arguments: "" },
18
- },
19
- ],
20
- },
21
- {
22
- role: "tool",
23
- content: "msg501",
24
- tool_call_id: "tool_call_0",
25
- },
26
- { role: "assistant", content: "msg502" },
27
- ];
28
-
29
- export async function basicContextTest(cm: IContextManager) {
30
- expect(cm.getAgentPrompt()).eql("sys_prompt");
31
-
32
- // Add first 2 messages
33
- let tx = await cm.startTx([MESSAGES[0] as UserMessageParam]);
34
- tx.addMessage(MESSAGES[1]);
35
- expect(tx.getLLMContext()).eql([
36
- {
37
- role: "system",
38
- content: "sys_prompt",
39
- },
40
- MESSAGES[0],
41
- MESSAGES[1],
42
- ]);
43
- await cm.commit(tx);
44
-
45
- // Add more messages
46
- tx = await cm.startTx([MESSAGES[2] as UserMessageParam]);
47
- expect(tx.getLLMContext()).eql([
48
- {
49
- role: "system",
50
- content: "sys_prompt",
51
- },
52
- MESSAGES[0],
53
- MESSAGES[1],
54
- MESSAGES[2],
55
- ]);
56
- tx.addMessages(MESSAGES.slice(3));
57
- expect(tx.getLLMContext()).eql([
58
- {
59
- role: "system",
60
- content: "sys_prompt",
61
- },
62
- MESSAGES[0],
63
- MESSAGES[1],
64
- MESSAGES[2],
65
- MESSAGES[3],
66
- MESSAGES[4],
67
- MESSAGES[5],
68
- ]);
69
- await cm.commit(tx);
70
-
71
- // Update system prompt
72
- cm.setAgentPrompt("New system prompt");
73
-
74
- // Wait for compression to complete, then get the new context
75
- const context = cm.getLLMContext();
76
-
77
- // Expect
78
- // - callback happened
79
- // - new context is as expected
80
-
81
- const expectContext: MessageParam[] = [
82
- {
83
- role: "system",
84
- content: "New system prompt",
85
- },
86
- MESSAGES[0], // 400
87
- MESSAGES[1], // 500
88
- MESSAGES[2], // 400
89
- MESSAGES[3], // 500
90
- MESSAGES[4], // 501
91
- MESSAGES[5], // 502
92
- ];
93
-
94
- expect(context).eql(expectContext);
95
- }
@@ -1,109 +0,0 @@
1
- import { expect } from "vitest";
2
- import {
3
- AssistantMessageParam,
4
- MessageParam,
5
- UserMessageParam,
6
- } from "../agent/llm";
7
- import {
8
- MESSAGE_INDEX_FULL_INCREMENT,
9
- MESSAGE_INDEX_SUB_INCREMENT,
10
- sessionMessagesToLLMConversation,
11
- sessionMessagesToNextIndex,
12
- } from "../chat/server/conversation";
13
- import { SessionMessage } from "../chat/data/dataModels";
14
-
15
- // Fake conversation values.
16
- const AGENT: AssistantMessageParam[] = [
17
- { role: "assistant", content: "Message 0" },
18
- { role: "assistant", content: "Message 1" },
19
- { role: "assistant", content: "Message 2" },
20
- ];
21
-
22
- const USER: UserMessageParam[] = [
23
- { role: "user", content: "Message 0", name: "userA" },
24
- { role: "user", content: "Message 1", name: "userA" },
25
- { role: "user", content: "Message 2", name: "userA" },
26
- ];
27
-
28
- describe("Conversation tools", () => {
29
- it("sessionMessagesToLLMConversation handles empty case", () => {
30
- const nextMessageIdx = sessionMessagesToNextIndex([]);
31
- const { firstIndex, conversation } = sessionMessagesToLLMConversation([]);
32
-
33
- expect(nextMessageIdx).eql(0);
34
- expect(firstIndex).eql(-1);
35
- expect(conversation).eql([]);
36
- });
37
-
38
- it("sessionMessagesToLLMConversation extracts LLM messages", () => {
39
- const messages: SessionMessage[] = [
40
- {
41
- message_idx: 0,
42
- sender_uuid: "userA",
43
- content: USER[0],
44
- is_for_llm: true,
45
- },
46
- {
47
- message_idx: 100,
48
- content: {} as unknown as MessageParam,
49
- is_for_llm: false,
50
- },
51
- {
52
- message_idx: 101,
53
- content: AGENT[0],
54
- is_for_llm: true,
55
- },
56
- ];
57
- const expectConversation = [USER[0], AGENT[0]];
58
- const expectNextIdx = 2 * MESSAGE_INDEX_FULL_INCREMENT;
59
- const expectFirstIdx = 0;
60
-
61
- const nextMessageIdx = sessionMessagesToNextIndex(messages);
62
- const nextMessageIdx100 = sessionMessagesToNextIndex(messages.slice(0, 2));
63
- const { firstIndex, conversation } =
64
- sessionMessagesToLLMConversation(messages);
65
- expect(conversation).eql(expectConversation);
66
- expect(nextMessageIdx).eql(expectNextIdx);
67
- expect(nextMessageIdx100).eql(expectNextIdx);
68
- expect(firstIndex).eql(expectFirstIdx);
69
- });
70
-
71
- it("sessionMessagesToLLMConversation skips leading invalid", () => {
72
- const messages: SessionMessage[] = [
73
- {
74
- message_idx: 3 * MESSAGE_INDEX_FULL_INCREMENT,
75
- content: AGENT[0],
76
- is_for_llm: true,
77
- },
78
- {
79
- // Should be identified as the first message, since we can't start
80
- // with an agent message
81
- message_idx: 4 * MESSAGE_INDEX_FULL_INCREMENT,
82
- sender_uuid: "userA",
83
- content: USER[0],
84
- is_for_llm: true,
85
- },
86
- {
87
- message_idx: 5 * MESSAGE_INDEX_FULL_INCREMENT,
88
- content: {} as unknown as MessageParam,
89
- is_for_llm: false,
90
- },
91
- {
92
- message_idx:
93
- 5 * MESSAGE_INDEX_FULL_INCREMENT + 3 * MESSAGE_INDEX_SUB_INCREMENT,
94
- content: AGENT[1],
95
- is_for_llm: true,
96
- },
97
- ];
98
- const expectConversation = [USER[0], AGENT[1]];
99
- const expectNextIdx = 6 * MESSAGE_INDEX_FULL_INCREMENT;
100
- const expectFirstIdx = 4 * MESSAGE_INDEX_FULL_INCREMENT;
101
-
102
- const nextMessageIdx = sessionMessagesToNextIndex(messages);
103
- const { firstIndex, conversation } =
104
- sessionMessagesToLLMConversation(messages);
105
- expect(conversation).eql(expectConversation);
106
- expect(nextMessageIdx).eql(expectNextIdx);
107
- expect(firstIndex).eql(expectFirstIdx);
108
- });
109
- });