@xalia/agent 0.5.7 → 0.6.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.
Files changed (186) hide show
  1. package/README.md +23 -8
  2. package/dist/agent/src/agent/agent.js +176 -96
  3. package/dist/agent/src/agent/agentUtils.js +82 -59
  4. package/dist/agent/src/agent/compressingContextManager.js +102 -0
  5. package/dist/agent/src/agent/context.js +189 -0
  6. package/dist/agent/src/agent/dummyLLM.js +46 -5
  7. package/dist/agent/src/agent/mcpServerManager.js +23 -24
  8. package/dist/agent/src/agent/nullAgentEventHandler.js +21 -0
  9. package/dist/agent/src/agent/nullPlatform.js +14 -0
  10. package/dist/agent/src/agent/openAILLMStreaming.js +26 -14
  11. package/dist/agent/src/agent/promptProvider.js +63 -0
  12. package/dist/agent/src/agent/repeatLLM.js +5 -5
  13. package/dist/agent/src/agent/sudoMcpServerManager.js +23 -21
  14. package/dist/agent/src/agent/tokenAuth.js +7 -7
  15. package/dist/agent/src/agent/tools.js +1 -1
  16. package/dist/agent/src/chat/client/chatClient.js +733 -0
  17. package/dist/agent/src/chat/client/connection.js +209 -0
  18. package/dist/agent/src/chat/client/connection.test.js +188 -0
  19. package/dist/agent/src/chat/client/constants.js +5 -0
  20. package/dist/agent/src/chat/client/index.js +15 -0
  21. package/dist/agent/src/chat/client/interfaces.js +2 -0
  22. package/dist/agent/src/chat/client/responseHandler.js +105 -0
  23. package/dist/agent/src/chat/client/sessionClient.js +331 -0
  24. package/dist/agent/src/chat/client/teamManager.js +2 -0
  25. package/dist/agent/src/chat/{apiKeyManager.js → data/apiKeyManager.js} +4 -0
  26. package/dist/agent/src/chat/data/dataModels.js +2 -0
  27. package/dist/agent/src/chat/data/database.js +749 -0
  28. package/dist/agent/src/chat/data/dbMcpServerConfigs.js +47 -0
  29. package/dist/agent/src/chat/protocol/connectionMessages.js +5 -0
  30. package/dist/agent/src/chat/protocol/constants.js +50 -0
  31. package/dist/agent/src/chat/protocol/errors.js +22 -0
  32. package/dist/agent/src/chat/protocol/messages.js +110 -0
  33. package/dist/agent/src/chat/server/chatContextManager.js +405 -0
  34. package/dist/agent/src/chat/server/connectionManager.js +352 -0
  35. package/dist/agent/src/chat/server/connectionManager.test.js +159 -0
  36. package/dist/agent/src/chat/server/conversation.js +198 -0
  37. package/dist/agent/src/chat/server/errorUtils.js +23 -0
  38. package/dist/agent/src/chat/server/openSession.js +869 -0
  39. package/dist/agent/src/chat/server/server.js +177 -0
  40. package/dist/agent/src/chat/server/sessionFileManager.js +161 -0
  41. package/dist/agent/src/chat/server/sessionRegistry.js +700 -0
  42. package/dist/agent/src/chat/server/sessionRegistry.test.js +97 -0
  43. package/dist/agent/src/chat/server/test-utils/mockFactories.js +307 -0
  44. package/dist/agent/src/chat/server/tools.js +243 -0
  45. package/dist/agent/src/chat/utils/agentSessionMap.js +66 -0
  46. package/dist/agent/src/chat/utils/approvalManager.js +85 -0
  47. package/dist/agent/src/{utils → chat/utils}/asyncLock.js +3 -3
  48. package/dist/agent/src/chat/{asyncQueue.js → utils/asyncQueue.js} +12 -2
  49. package/dist/agent/src/chat/utils/htmlToText.js +84 -0
  50. package/dist/agent/src/chat/utils/multiAsyncQueue.js +42 -0
  51. package/dist/agent/src/chat/utils/search.js +145 -0
  52. package/dist/agent/src/chat/utils/userResolver.js +46 -0
  53. package/dist/agent/src/chat/utils/websocket.js +16 -0
  54. package/dist/agent/src/test/agent.test.js +332 -0
  55. package/dist/agent/src/test/approvalManager.test.js +58 -0
  56. package/dist/agent/src/test/chatContextManager.test.js +392 -0
  57. package/dist/agent/src/test/clientServerConnection.test.js +158 -0
  58. package/dist/agent/src/test/compressingContextManager.test.js +65 -0
  59. package/dist/agent/src/test/context.test.js +83 -0
  60. package/dist/agent/src/test/conversation.test.js +89 -0
  61. package/dist/agent/src/test/db.test.js +271 -83
  62. package/dist/agent/src/test/dbMcpServerConfigs.test.js +72 -0
  63. package/dist/agent/src/test/dbTestTools.js +99 -0
  64. package/dist/agent/src/test/imageLoad.test.js +8 -7
  65. package/dist/agent/src/test/mcpServerManager.test.js +23 -20
  66. package/dist/agent/src/test/multiAsyncQueue.test.js +101 -0
  67. package/dist/agent/src/test/openaiStreaming.test.js +64 -35
  68. package/dist/agent/src/test/prompt.test.js +5 -4
  69. package/dist/agent/src/test/promptProvider.test.js +28 -0
  70. package/dist/agent/src/test/responseHandler.test.js +61 -0
  71. package/dist/agent/src/test/sudoMcpServerManager.test.js +24 -25
  72. package/dist/agent/src/test/testTools.js +109 -0
  73. package/dist/agent/src/test/tools.test.js +31 -0
  74. package/dist/agent/src/tool/agentChat.js +21 -10
  75. package/dist/agent/src/tool/agentMain.js +1 -1
  76. package/dist/agent/src/tool/chatMain.js +241 -58
  77. package/dist/agent/src/tool/commandPrompt.js +22 -17
  78. package/dist/agent/src/tool/files.js +20 -16
  79. package/dist/agent/src/tool/nodePlatform.js +47 -3
  80. package/dist/agent/src/tool/options.js +4 -4
  81. package/dist/agent/src/tool/prompt.js +19 -13
  82. package/eslint.config.mjs +14 -1
  83. package/package.json +14 -6
  84. package/scripts/chat_server +8 -0
  85. package/scripts/setup_chat +7 -2
  86. package/scripts/shutdown_chat_server +3 -0
  87. package/scripts/test_chat +135 -17
  88. package/src/agent/agent.ts +283 -138
  89. package/src/agent/agentUtils.ts +143 -108
  90. package/src/agent/compressingContextManager.ts +164 -0
  91. package/src/agent/context.ts +268 -0
  92. package/src/agent/dummyLLM.ts +76 -8
  93. package/src/agent/iAgentEventHandler.ts +54 -0
  94. package/src/agent/iplatform.ts +1 -0
  95. package/src/agent/mcpServerManager.ts +35 -31
  96. package/src/agent/nullAgentEventHandler.ts +20 -0
  97. package/src/agent/nullPlatform.ts +13 -0
  98. package/src/agent/openAILLMStreaming.ts +26 -13
  99. package/src/agent/promptProvider.ts +87 -0
  100. package/src/agent/repeatLLM.ts +5 -5
  101. package/src/agent/sudoMcpServerManager.ts +30 -29
  102. package/src/agent/tokenAuth.ts +7 -7
  103. package/src/agent/tools.ts +3 -1
  104. package/src/chat/client/chatClient.ts +900 -0
  105. package/src/chat/client/connection.test.ts +241 -0
  106. package/src/chat/client/connection.ts +276 -0
  107. package/src/chat/client/constants.ts +3 -0
  108. package/src/chat/client/index.ts +18 -0
  109. package/src/chat/client/interfaces.ts +34 -0
  110. package/src/chat/client/responseHandler.ts +131 -0
  111. package/src/chat/client/sessionClient.ts +443 -0
  112. package/src/chat/client/teamManager.ts +29 -0
  113. package/src/chat/{apiKeyManager.ts → data/apiKeyManager.ts} +6 -2
  114. package/src/chat/data/dataModels.ts +85 -0
  115. package/src/chat/data/database.ts +982 -0
  116. package/src/chat/data/dbMcpServerConfigs.ts +59 -0
  117. package/src/chat/protocol/connectionMessages.ts +49 -0
  118. package/src/chat/protocol/constants.ts +55 -0
  119. package/src/chat/protocol/errors.ts +16 -0
  120. package/src/chat/protocol/messages.ts +682 -0
  121. package/src/chat/server/README.md +127 -0
  122. package/src/chat/server/chatContextManager.ts +612 -0
  123. package/src/chat/server/connectionManager.test.ts +266 -0
  124. package/src/chat/server/connectionManager.ts +541 -0
  125. package/src/chat/server/conversation.ts +269 -0
  126. package/src/chat/server/errorUtils.ts +28 -0
  127. package/src/chat/server/openSession.ts +1332 -0
  128. package/src/chat/server/server.ts +177 -0
  129. package/src/chat/server/sessionFileManager.ts +239 -0
  130. package/src/chat/server/sessionRegistry.test.ts +138 -0
  131. package/src/chat/server/sessionRegistry.ts +1064 -0
  132. package/src/chat/server/test-utils/mockFactories.ts +422 -0
  133. package/src/chat/server/tools.ts +265 -0
  134. package/src/chat/utils/agentSessionMap.ts +76 -0
  135. package/src/chat/utils/approvalManager.ts +111 -0
  136. package/src/{utils → chat/utils}/asyncLock.ts +3 -3
  137. package/src/chat/{asyncQueue.ts → utils/asyncQueue.ts} +14 -3
  138. package/src/chat/utils/htmlToText.ts +61 -0
  139. package/src/chat/utils/multiAsyncQueue.ts +52 -0
  140. package/src/chat/utils/search.ts +139 -0
  141. package/src/chat/utils/userResolver.ts +48 -0
  142. package/src/chat/utils/websocket.ts +16 -0
  143. package/src/test/agent.test.ts +487 -0
  144. package/src/test/approvalManager.test.ts +73 -0
  145. package/src/test/chatContextManager.test.ts +521 -0
  146. package/src/test/clientServerConnection.test.ts +207 -0
  147. package/src/test/compressingContextManager.test.ts +82 -0
  148. package/src/test/context.test.ts +105 -0
  149. package/src/test/conversation.test.ts +109 -0
  150. package/src/test/db.test.ts +358 -89
  151. package/src/test/dbMcpServerConfigs.test.ts +112 -0
  152. package/src/test/dbTestTools.ts +153 -0
  153. package/src/test/imageLoad.test.ts +7 -6
  154. package/src/test/mcpServerManager.test.ts +21 -16
  155. package/src/test/multiAsyncQueue.test.ts +125 -0
  156. package/src/test/openaiStreaming.test.ts +71 -36
  157. package/src/test/prompt.test.ts +4 -3
  158. package/src/test/promptProvider.test.ts +33 -0
  159. package/src/test/responseHandler.test.ts +78 -0
  160. package/src/test/sudoMcpServerManager.test.ts +32 -30
  161. package/src/test/testTools.ts +146 -0
  162. package/src/test/tools.test.ts +39 -0
  163. package/src/tool/agentChat.ts +26 -12
  164. package/src/tool/agentMain.ts +1 -1
  165. package/src/tool/chatMain.ts +292 -100
  166. package/src/tool/commandPrompt.ts +28 -19
  167. package/src/tool/files.ts +25 -19
  168. package/src/tool/nodePlatform.ts +52 -3
  169. package/src/tool/options.ts +4 -2
  170. package/src/tool/prompt.ts +22 -15
  171. package/test_data/dummyllm_script_crash.json +32 -0
  172. package/test_data/frog.png.b64 +1 -0
  173. package/vitest.config.ts +39 -0
  174. package/dist/agent/src/chat/client.js +0 -349
  175. package/dist/agent/src/chat/conversationManager.js +0 -392
  176. package/dist/agent/src/chat/db.js +0 -209
  177. package/dist/agent/src/chat/frontendClient.js +0 -74
  178. package/dist/agent/src/chat/server.js +0 -158
  179. package/src/chat/client.ts +0 -455
  180. package/src/chat/conversationManager.ts +0 -595
  181. package/src/chat/db.ts +0 -290
  182. package/src/chat/frontendClient.ts +0 -123
  183. package/src/chat/messages.ts +0 -235
  184. package/src/chat/server.ts +0 -177
  185. /package/dist/agent/src/{chat/messages.js → agent/iAgentEventHandler.js} +0 -0
  186. /package/{frog.png → test_data/frog.png} +0 -0
@@ -0,0 +1,332 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const assert_1 = require("assert");
5
+ const agent_1 = require("../agent/agent");
6
+ const context_1 = require("../agent/context");
7
+ const sudoMcpServerManager_1 = require("../agent/sudoMcpServerManager");
8
+ const promptProvider_1 = require("../agent/promptProvider");
9
+ const testTools_1 = require("./testTools");
10
+ function clone(a) {
11
+ return JSON.parse(JSON.stringify(a));
12
+ }
13
+ const DUMMY_SCRIPT = [
14
+ {
15
+ index: 0,
16
+ finish_reason: "stop",
17
+ message: {
18
+ content: "message1",
19
+ refusal: null,
20
+ role: "assistant",
21
+ },
22
+ logprobs: null,
23
+ },
24
+ {
25
+ index: 0,
26
+ finish_reason: "stop",
27
+ message: {
28
+ content: "message2",
29
+ refusal: null,
30
+ role: "assistant",
31
+ },
32
+ logprobs: null,
33
+ },
34
+ ];
35
+ function createCallTestToolScript(tool_call_ids, param1, param2) {
36
+ // A trivial tool
37
+ const parameters = {
38
+ type: "object",
39
+ properties: {
40
+ param1: {
41
+ type: "string",
42
+ },
43
+ param2: {
44
+ type: "number",
45
+ },
46
+ },
47
+ required: ["param1", "param2"],
48
+ };
49
+ const toolDescriptor = {
50
+ type: "function",
51
+ function: {
52
+ name: "test_tool",
53
+ parameters,
54
+ strict: true,
55
+ },
56
+ };
57
+ const toolFn = async (_, args) => {
58
+ const { param1, param2 } = args;
59
+ return new Promise((r) => {
60
+ r({ response: `tool_result: '${param1}' '${String(param2)}'` });
61
+ });
62
+ };
63
+ // A script that uses the tool
64
+ const script = [
65
+ {
66
+ index: 0,
67
+ finish_reason: "tool_calls",
68
+ message: {
69
+ content: "calling test_tool.",
70
+ refusal: null,
71
+ role: "assistant",
72
+ tool_calls: tool_call_ids.map((t_id) => {
73
+ return {
74
+ id: t_id,
75
+ function: {
76
+ name: "test_tool",
77
+ arguments: JSON.stringify({ param1, param2 }),
78
+ },
79
+ type: "function",
80
+ };
81
+ }),
82
+ },
83
+ logprobs: null,
84
+ },
85
+ {
86
+ index: 0,
87
+ finish_reason: "stop",
88
+ message: {
89
+ content: "message after tools calls.",
90
+ refusal: null,
91
+ role: "assistant",
92
+ },
93
+ logprobs: null,
94
+ },
95
+ ];
96
+ // Expected output
97
+ const expectAgentMessages = [
98
+ "calling test_tool.",
99
+ "message after tools calls.",
100
+ ];
101
+ const expectToolResults = tool_call_ids.map((t_id) => {
102
+ return {
103
+ content: `tool_result: '${param1}' '${String(param2)}'`,
104
+ role: "tool",
105
+ tool_call_id: t_id,
106
+ };
107
+ });
108
+ return {
109
+ script,
110
+ expectCompletions: script.map((s) => s.message),
111
+ expectAgentMessages,
112
+ expectToolResults,
113
+ toolDescriptor,
114
+ toolFn,
115
+ };
116
+ }
117
+ /// Return a dummy agent and a TestAgentEventHandler for tracking messages.
118
+ async function createTestAgent(script) {
119
+ const agentProfile = {
120
+ model: "dummy:" + JSON.stringify(script),
121
+ system_prompt: "SYSTEM_PROMPT",
122
+ mcp_settings: {},
123
+ };
124
+ const eventHandler = new testTools_1.TestAgentEventHandler();
125
+ const skillManager = await sudoMcpServerManager_1.SkillManager.initialize((url, authResultP, displayName) => {
126
+ testTools_1.DUMMY_PLATFORM.openUrl(url, authResultP, displayName);
127
+ }, sudoMcpServerManager_1.LOCAL_SERVER_URL, "dummy_key", undefined);
128
+ const agent = agent_1.Agent.initializeWithLLM(eventHandler, new testTools_1.TestDummyLLM(script), new context_1.ContextManager(agentProfile.system_prompt, []), skillManager);
129
+ return { agent, skillManager, eventHandler };
130
+ }
131
+ describe("Agent", () => {
132
+ it("correctly calls custom tools", async function () {
133
+ const tool_call_id = "tool_call_1";
134
+ const param1 = "first param";
135
+ const param2 = 2;
136
+ const { script, expectAgentMessages, expectToolResults, toolDescriptor, toolFn, } = createCallTestToolScript([tool_call_id], param1, param2);
137
+ const { agent /*, skillManager */, eventHandler } = await createTestAgent(script);
138
+ agent.addAgentTool(toolDescriptor, toolFn);
139
+ await agent.userMessageEx("user message 1");
140
+ (0, vitest_1.expect)(eventHandler.getAgentMessages()).eql(expectAgentMessages);
141
+ (0, vitest_1.expect)(eventHandler.getToolCallResults()).eql(expectToolResults);
142
+ // Check the ordering
143
+ const allExpect = [
144
+ script[0].message,
145
+ ...expectToolResults,
146
+ script[1].message,
147
+ ];
148
+ const all = eventHandler.getAll();
149
+ (0, vitest_1.expect)(all).eql(allExpect);
150
+ const allToolCalls = eventHandler.getToolCalls();
151
+ const agentToolCalls = eventHandler.getAgentToolCalls();
152
+ const expectToolCalls = script[0].message.tool_calls;
153
+ (0, vitest_1.expect)(allToolCalls).eql(expectToolCalls);
154
+ (0, vitest_1.expect)(agentToolCalls).eql(expectToolCalls);
155
+ });
156
+ it("correctly invokes tool providers", async function () {
157
+ const tool_call_id = "tool_call_1";
158
+ const param1 = "asdf";
159
+ const param2 = 3;
160
+ const { script, expectCompletions, expectAgentMessages, expectToolResults, toolDescriptor, toolFn, } = createCallTestToolScript([tool_call_id], param1, param2);
161
+ const { agent /*, skillManager */, eventHandler } = await createTestAgent(script);
162
+ const toolProvider = {
163
+ setup: (agent) => {
164
+ // Add the tool async to test this mechanism
165
+ return new Promise((r) => {
166
+ setTimeout(() => {
167
+ agent.addAgentTool(toolDescriptor, toolFn);
168
+ r();
169
+ });
170
+ });
171
+ },
172
+ };
173
+ await agent.addAgentToolProvider(toolProvider);
174
+ await agent.userMessageEx("user message 1");
175
+ (0, vitest_1.expect)(eventHandler.getCompletions()).eql(expectCompletions);
176
+ (0, vitest_1.expect)(eventHandler.getAgentMessages()).eql(expectAgentMessages);
177
+ (0, vitest_1.expect)(eventHandler.getToolCallResults()).eql(expectToolResults);
178
+ });
179
+ it("correctly reflects system prompt", async function () {
180
+ const llm = new testTools_1.TestDummyLLM(DUMMY_SCRIPT);
181
+ const contextManager = new context_1.ContextManager("agent_prompt", []);
182
+ const agent = agent_1.Agent.initializeWithLLM(new testTools_1.TestAgentEventHandler(), llm, contextManager);
183
+ promptProvider_1.SystemPromptProvider.setGlobalPrompt("global_prompt");
184
+ // NOTE: SystemPromptProvider/ContextManager is unit tested elsewhere so
185
+ // we assume it computes the correct prompt. Here we check that this is
186
+ // reflected in the request to LLM.
187
+ // Check the prompt
188
+ await agent.userMessageEx("user message 1");
189
+ let lastRequest = llm.getLastRequest();
190
+ (0, assert_1.strict)(lastRequest);
191
+ (0, vitest_1.expect)(lastRequest[0].content).eql(contextManager.getLLMContext()[0].content);
192
+ (0, vitest_1.expect)(agent.getSystemPrompt()).eql("agent_prompt");
193
+ // Update and re-check the prompt
194
+ agent.setSystemPrompt("agent_prompt_2");
195
+ await agent.userMessageEx("user message 1");
196
+ lastRequest = llm.getLastRequest();
197
+ (0, assert_1.strict)(lastRequest);
198
+ (0, vitest_1.expect)(lastRequest[0].content).eql(contextManager.getLLMContext()[0].content);
199
+ (0, vitest_1.expect)(agent.getSystemPrompt()).eql("agent_prompt_2");
200
+ });
201
+ it("correctly orders messages for multiple tool calls", async function () {
202
+ const tool_call_ids = [
203
+ "tool_call_1",
204
+ "tool_call_2",
205
+ "tool_call_3",
206
+ ];
207
+ const param1 = "asdf";
208
+ const param2 = 3;
209
+ const { script, expectToolResults, toolDescriptor, toolFn } = createCallTestToolScript(tool_call_ids, param1, param2);
210
+ const { agent /*, skillManager */, eventHandler } = await createTestAgent(script);
211
+ agent.addAgentTool(toolDescriptor, toolFn);
212
+ await agent.userMessageEx("user message 1");
213
+ // Check the event handler was called with all completions and tool
214
+ // results, in the correct order.
215
+ const allExpect = [
216
+ script[0].message,
217
+ ...expectToolResults,
218
+ script[1].message,
219
+ ];
220
+ const all = eventHandler.getAll();
221
+ (0, vitest_1.expect)(all).eql(allExpect);
222
+ // The conversation (context) messages (order and number) should also
223
+ // match this.
224
+ const conv = agent.getConversation();
225
+ (0, vitest_1.expect)(conv.slice(1)).eql(all);
226
+ });
227
+ it("correctly updates tool call args", async function () {
228
+ const tool_call_ids = [
229
+ "tool_call_1",
230
+ "tool_call_2",
231
+ "tool_call_3",
232
+ ];
233
+ const param1 = "asdf";
234
+ const param2 = 3;
235
+ const { script, expectToolResults, toolDescriptor, toolFn } = createCallTestToolScript(tool_call_ids, param1, param2);
236
+ const { agent /*, skillManager */, eventHandler } = await createTestAgent(script);
237
+ // Take a copy of the script now, since this will be updated when the
238
+ // tools redacted their args.
239
+ const scriptCopy = clone(script);
240
+ const transformArgs = (args) => {
241
+ return { param1: args.param1.toUpperCase(), param2: args.param2 + 100 };
242
+ };
243
+ const transformArgsStr = (argsStr) => {
244
+ const args = JSON.parse(argsStr);
245
+ return JSON.stringify(transformArgs(args));
246
+ };
247
+ const newToolFn = async (agent, args) => {
248
+ const result = await toolFn(agent, args);
249
+ result.overwriteArgs = JSON.stringify(transformArgs(args));
250
+ return result;
251
+ };
252
+ agent.addAgentTool(toolDescriptor, newToolFn);
253
+ // Send a message and trigger the tool calls
254
+ await agent.userMessageEx("user message 1");
255
+ // Check the event handler was called with all completions and tool
256
+ // results, in the correct order.
257
+ const transformToolCall = (toolCall) => {
258
+ return {
259
+ ...toolCall,
260
+ function: {
261
+ ...toolCall.function,
262
+ arguments: transformArgsStr(toolCall.function.arguments),
263
+ },
264
+ };
265
+ };
266
+ (0, assert_1.strict)(scriptCopy[0].message.tool_calls);
267
+ const transformedFirstMsg = {
268
+ ...scriptCopy[0].message,
269
+ tool_calls: scriptCopy[0].message.tool_calls.map(transformToolCall),
270
+ };
271
+ const allExpect = [
272
+ transformedFirstMsg,
273
+ ...expectToolResults,
274
+ scriptCopy[1].message,
275
+ ];
276
+ const all = eventHandler.getAll();
277
+ const conv = agent.getConversation();
278
+ (0, vitest_1.expect)(all).eql(allExpect);
279
+ (0, vitest_1.expect)(conv.slice(1)).eql(all);
280
+ });
281
+ it("correctly updates tool call results", async function () {
282
+ const tool_call_ids = [
283
+ "tool_call_1",
284
+ "tool_call_2",
285
+ "tool_call_3",
286
+ ];
287
+ const param1 = "asdf";
288
+ const param2 = 3;
289
+ const { script, expectToolResults, toolDescriptor, toolFn } = createCallTestToolScript(tool_call_ids, param1, param2);
290
+ const { agent /*, skillManager */, eventHandler } = await createTestAgent(script);
291
+ // Define the tool to update the results. The transform is to up-case
292
+ // the whole result string.
293
+ const transformResult = (result) => {
294
+ return result.toUpperCase();
295
+ };
296
+ const newToolFn = async (agent, args) => {
297
+ const result = await toolFn(agent, args);
298
+ result.overwriteResponse = transformResult(result.response);
299
+ return result;
300
+ };
301
+ agent.addAgentTool(toolDescriptor, newToolFn);
302
+ // Send a message and trigger the tool calls
303
+ await agent.userMessageEx("user message 1");
304
+ // Check the event handler was called with all completions and tool
305
+ // results as expected.
306
+ const expectToolCallResults = expectToolResults.map((tr) => {
307
+ (0, assert_1.strict)(typeof tr.content === "string");
308
+ return {
309
+ ...tr,
310
+ content: transformResult(tr.content),
311
+ };
312
+ });
313
+ const allExpect = [
314
+ script[0].message,
315
+ ...expectToolCallResults,
316
+ script[1].message,
317
+ ];
318
+ const all = eventHandler.getAll();
319
+ const conv = agent.getConversation();
320
+ (0, vitest_1.expect)(all).eql(allExpect);
321
+ (0, vitest_1.expect)(conv.slice(1)).eql(all);
322
+ });
323
+ it("correctly handles LLM errors", async function () {
324
+ const eventHandler = new testTools_1.TestAgentEventHandler();
325
+ const llm = new testTools_1.TestErrorLLM();
326
+ const ctxMgr = new context_1.ContextManager("SYSTEM_PROMPT", []);
327
+ const agent = agent_1.Agent.initializeWithLLM(eventHandler, llm, ctxMgr);
328
+ await (0, vitest_1.expect)(agent.userMessagesRaw([{ role: "user", content: "message" }])).rejects.toThrow();
329
+ // Check the Agent has not added the user messages.
330
+ (0, vitest_1.expect)(ctxMgr.getLLMContext().length).eql(1);
331
+ });
332
+ });
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const approvalManager_1 = require("../chat/utils/approvalManager");
5
+ (0, vitest_1.describe)("ApprovalManager", () => {
6
+ let approvalManager;
7
+ (0, vitest_1.beforeEach)(() => {
8
+ approvalManager = new approvalManager_1.ApprovalManager(100); // Shorter timeout for tests
9
+ });
10
+ (0, vitest_1.it)("generate unique ids", async () => {
11
+ const app0 = approvalManager.startApproval("testApproval");
12
+ const app1 = approvalManager.startApproval("testApproval");
13
+ (0, vitest_1.expect)(app0.id).not.toBe(app1.id);
14
+ // Clean up to prevent unhandled rejections - catch the shutdown promises
15
+ const promises = [
16
+ app0.resultP.catch(() => "cancelled"),
17
+ app1.resultP.catch(() => "cancelled"),
18
+ ];
19
+ approvalManager.shutdown();
20
+ await Promise.all(promises);
21
+ });
22
+ (0, vitest_1.it)("resultP rejects on timeout", { timeout: 200 }, async function () {
23
+ const { resultP } = approvalManager.startApproval("timeoutTest");
24
+ const result = await resultP.catch((e) => e);
25
+ (0, vitest_1.expect)(result).toBeInstanceOf(approvalManager_1.ApprovalTimeout);
26
+ // No cleanup needed - the timeout already resolved the promise
27
+ });
28
+ (0, vitest_1.it)("resolve promises (accept and reject)", async () => {
29
+ const { id, resultP } = approvalManager.startApproval("acceptRejectTest");
30
+ const resultPromise = resultP.catch(() => ({
31
+ approved: false,
32
+ auto_approve: false,
33
+ }));
34
+ approvalManager.approvalResult(id, true, false);
35
+ const result = await resultPromise;
36
+ (0, vitest_1.expect)(result.approved).toBe(true);
37
+ const { id: rejectId, resultP: rejectP } = approvalManager.startApproval("rejectTest");
38
+ const rejectResultPromise = rejectP.catch(() => ({
39
+ approved: true,
40
+ auto_approve: false,
41
+ }));
42
+ approvalManager.approvalResult(rejectId, false, false);
43
+ const rejectResult = await rejectResultPromise;
44
+ (0, vitest_1.expect)(rejectResult.approved).toBe(false);
45
+ });
46
+ (0, vitest_1.it)("shutdown with unresolved promises", async () => {
47
+ const { resultP } = approvalManager.startApproval("acceptRejectTest");
48
+ // Setup a promise that catches the expected shutdown cancellation
49
+ const shutdownPromise = resultP.catch((error) => {
50
+ (0, vitest_1.expect)(error.message).toBe("shutdown");
51
+ return "cancelled";
52
+ });
53
+ approvalManager.shutdown();
54
+ // Await the promise to handle the rejection properly
55
+ const result = await shutdownPromise;
56
+ (0, vitest_1.expect)(result).toBe("cancelled");
57
+ });
58
+ });