@xalia/agent 0.6.9 → 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 (199) hide show
  1. package/README.md +11 -0
  2. package/dist/agent/src/agent/agent.js +77 -18
  3. package/dist/agent/src/agent/agentUtils.js +3 -2
  4. package/dist/agent/src/agent/documentSummarizer.js +126 -0
  5. package/dist/agent/src/agent/dummyLLM.js +25 -22
  6. package/dist/agent/src/agent/imageGenLLM.js +22 -19
  7. package/dist/agent/src/agent/llm.js +1 -1
  8. package/dist/agent/src/agent/openAILLM.js +15 -12
  9. package/dist/agent/src/agent/openAILLMStreaming.js +68 -37
  10. package/dist/agent/src/agent/repeatLLM.js +16 -7
  11. package/dist/agent/src/agent/tokenCounter.js +390 -0
  12. package/dist/agent/src/agent/tokenCounter.test.js +206 -0
  13. package/dist/agent/src/agent/toolSettings.js +17 -0
  14. package/dist/agent/src/agent/tools/calculatorTool.js +45 -0
  15. package/dist/agent/src/agent/tools/contentExtractors/pdfToText.js +55 -0
  16. package/dist/agent/src/agent/tools/datetimeTool.js +38 -0
  17. package/dist/agent/src/agent/tools/fileManager/fileManagerTool.js +156 -0
  18. package/dist/agent/src/agent/tools/fileManager/index.js +31 -0
  19. package/dist/agent/src/agent/tools/fileManager/memoryFileManager.js +102 -0
  20. package/dist/agent/src/{chat/data → agent/tools/fileManager}/mimeTypes.js +3 -1
  21. package/dist/agent/src/agent/tools/fileManager/prompt.js +33 -0
  22. package/dist/agent/src/{chat/data/dbSessionFileModels.js → agent/tools/fileManager/types.js} +7 -0
  23. package/dist/agent/src/agent/tools/index.js +64 -0
  24. package/dist/agent/src/agent/tools/openUrlTool.js +57 -0
  25. package/dist/agent/src/agent/tools/renderTool.js +89 -0
  26. package/dist/agent/src/agent/tools/utils.js +61 -0
  27. package/dist/agent/src/{chat/utils/search.js → agent/tools/webSearch.js} +1 -2
  28. package/dist/agent/src/agent/tools/webSearchTool.js +40 -0
  29. package/dist/agent/src/chat/client/chatClient.js +28 -0
  30. package/dist/agent/src/chat/client/index.js +4 -1
  31. package/dist/agent/src/chat/client/sessionClient.js +28 -2
  32. package/dist/agent/src/chat/constants.js +8 -0
  33. package/dist/agent/src/chat/data/dbSessionFiles.js +11 -6
  34. package/dist/agent/src/chat/protocol/messages.js +5 -0
  35. package/dist/agent/src/chat/server/chatContextManager.js +45 -25
  36. package/dist/agent/src/chat/server/conversation.js +3 -0
  37. package/dist/agent/src/chat/server/imageGeneratorTools.js +20 -8
  38. package/dist/agent/src/chat/server/openAIRouterLLM.js +0 -3
  39. package/dist/agent/src/chat/server/openSession.js +218 -55
  40. package/dist/agent/src/chat/server/promptRefiner.js +86 -0
  41. package/dist/agent/src/chat/server/server.js +5 -1
  42. package/dist/agent/src/chat/server/sessionFileManager.js +22 -221
  43. package/dist/agent/src/chat/server/sessionRegistry.js +87 -0
  44. package/dist/agent/src/chat/server/titleGenerator.js +112 -0
  45. package/dist/agent/src/chat/server/titleGenerator.test.js +113 -0
  46. package/dist/agent/src/chat/server/tools.js +63 -287
  47. package/dist/agent/src/chat/utils/approvalManager.js +6 -3
  48. package/dist/agent/src/chat/utils/multiAsyncQueue.js +3 -0
  49. package/dist/agent/src/test/agent.test.js +16 -17
  50. package/dist/agent/src/test/chatContextManager.test.js +15 -3
  51. package/dist/agent/src/test/dbMcpServerConfigs.test.js +4 -4
  52. package/dist/agent/src/test/dbSessionFiles.test.js +17 -17
  53. package/dist/agent/src/test/testTools.js +6 -1
  54. package/dist/agent/src/test/tools.test.js +27 -9
  55. package/dist/agent/src/tool/agentChat.js +5 -2
  56. package/dist/agent/src/tool/chatMain.js +34 -7
  57. package/dist/agent/src/tool/commandPrompt.js +2 -2
  58. package/dist/agent/src/tool/files.js +7 -8
  59. package/package.json +8 -2
  60. package/.env.development +0 -1
  61. package/.prettierrc.json +0 -11
  62. package/dist/agent/src/agent/tools.js +0 -44
  63. package/eslint.config.mjs +0 -38
  64. package/scripts/chat_server +0 -8
  65. package/scripts/git_message +0 -31
  66. package/scripts/git_wip +0 -21
  67. package/scripts/pr_message +0 -18
  68. package/scripts/pr_review +0 -16
  69. package/scripts/setup_chat +0 -90
  70. package/scripts/shutdown_chat_server +0 -42
  71. package/scripts/start_chat_server +0 -24
  72. package/scripts/sudomcp_import +0 -23
  73. package/scripts/test_chat +0 -308
  74. package/src/agent/agent.ts +0 -624
  75. package/src/agent/agentUtils.ts +0 -285
  76. package/src/agent/compressingContextManager.ts +0 -129
  77. package/src/agent/context.ts +0 -265
  78. package/src/agent/contextWithWorkspace.ts +0 -162
  79. package/src/agent/dummyLLM.ts +0 -126
  80. package/src/agent/iAgentEventHandler.ts +0 -64
  81. package/src/agent/imageGenLLM.ts +0 -97
  82. package/src/agent/imageGenerator.ts +0 -45
  83. package/src/agent/iplatform.ts +0 -18
  84. package/src/agent/llm.ts +0 -74
  85. package/src/agent/mcpServerManager.ts +0 -541
  86. package/src/agent/nullAgentEventHandler.ts +0 -26
  87. package/src/agent/nullPlatform.ts +0 -13
  88. package/src/agent/openAI.ts +0 -123
  89. package/src/agent/openAILLM.ts +0 -95
  90. package/src/agent/openAILLMStreaming.ts +0 -609
  91. package/src/agent/promptProvider.ts +0 -87
  92. package/src/agent/repeatLLM.ts +0 -50
  93. package/src/agent/sudoMcpServerManager.ts +0 -361
  94. package/src/agent/tokenAuth.ts +0 -50
  95. package/src/agent/tools.ts +0 -57
  96. package/src/chat/client/chatClient.ts +0 -922
  97. package/src/chat/client/connection.test.ts +0 -241
  98. package/src/chat/client/connection.ts +0 -286
  99. package/src/chat/client/constants.ts +0 -1
  100. package/src/chat/client/index.ts +0 -18
  101. package/src/chat/client/interfaces.ts +0 -34
  102. package/src/chat/client/sessionClient.ts +0 -537
  103. package/src/chat/client/sessionFiles.ts +0 -142
  104. package/src/chat/client/teamManager.ts +0 -29
  105. package/src/chat/data/apiKeyManager.ts +0 -76
  106. package/src/chat/data/dataModels.ts +0 -101
  107. package/src/chat/data/database.ts +0 -997
  108. package/src/chat/data/dbMcpServerConfigs.ts +0 -59
  109. package/src/chat/data/dbSessionFileModels.ts +0 -113
  110. package/src/chat/data/dbSessionFiles.ts +0 -99
  111. package/src/chat/data/dbSessionMessages.ts +0 -102
  112. package/src/chat/data/mimeTypes.ts +0 -58
  113. package/src/chat/protocol/connectionMessages.ts +0 -49
  114. package/src/chat/protocol/constants.ts +0 -55
  115. package/src/chat/protocol/errors.ts +0 -16
  116. package/src/chat/protocol/messages.ts +0 -846
  117. package/src/chat/server/README.md +0 -127
  118. package/src/chat/server/chatContextManager.ts +0 -639
  119. package/src/chat/server/connectionManager.test.ts +0 -246
  120. package/src/chat/server/connectionManager.ts +0 -506
  121. package/src/chat/server/conversation.ts +0 -316
  122. package/src/chat/server/errorUtils.ts +0 -28
  123. package/src/chat/server/imageGeneratorTools.ts +0 -160
  124. package/src/chat/server/openAIRouterLLM.ts +0 -171
  125. package/src/chat/server/openSession.ts +0 -1689
  126. package/src/chat/server/openSessionMessageSender.ts +0 -4
  127. package/src/chat/server/server.ts +0 -175
  128. package/src/chat/server/sessionFileManager.ts +0 -422
  129. package/src/chat/server/sessionRegistry.test.ts +0 -137
  130. package/src/chat/server/sessionRegistry.ts +0 -1425
  131. package/src/chat/server/test-utils/mockFactories.ts +0 -422
  132. package/src/chat/server/tools.ts +0 -397
  133. package/src/chat/utils/agentSessionMap.ts +0 -76
  134. package/src/chat/utils/approvalManager.ts +0 -183
  135. package/src/chat/utils/asyncLock.ts +0 -43
  136. package/src/chat/utils/asyncQueue.ts +0 -62
  137. package/src/chat/utils/htmlToText.ts +0 -61
  138. package/src/chat/utils/multiAsyncQueue.ts +0 -62
  139. package/src/chat/utils/responseAwaiter.ts +0 -181
  140. package/src/chat/utils/search.ts +0 -139
  141. package/src/chat/utils/userResolver.ts +0 -48
  142. package/src/chat/utils/websocket.ts +0 -16
  143. package/src/index.ts +0 -0
  144. package/src/test/agent.test.ts +0 -590
  145. package/src/test/approvalManager.test.ts +0 -141
  146. package/src/test/chatContextManager.test.ts +0 -527
  147. package/src/test/clientServerConnection.test.ts +0 -205
  148. package/src/test/compressingContextManager.test.ts +0 -77
  149. package/src/test/context.test.ts +0 -150
  150. package/src/test/contextTestTools.ts +0 -95
  151. package/src/test/conversation.test.ts +0 -109
  152. package/src/test/db.test.ts +0 -363
  153. package/src/test/dbMcpServerConfigs.test.ts +0 -112
  154. package/src/test/dbSessionFiles.test.ts +0 -258
  155. package/src/test/dbSessionMessages.test.ts +0 -85
  156. package/src/test/dbTestTools.ts +0 -157
  157. package/src/test/imageLoad.test.ts +0 -15
  158. package/src/test/mcpServerManager.test.ts +0 -114
  159. package/src/test/multiAsyncQueue.test.ts +0 -183
  160. package/src/test/openaiStreaming.test.ts +0 -177
  161. package/src/test/prompt.test.ts +0 -27
  162. package/src/test/promptProvider.test.ts +0 -33
  163. package/src/test/responseAwaiter.test.ts +0 -103
  164. package/src/test/sudoMcpServerManager.test.ts +0 -63
  165. package/src/test/testTools.ts +0 -171
  166. package/src/test/tools.test.ts +0 -39
  167. package/src/tool/agentChat.ts +0 -194
  168. package/src/tool/agentMain.ts +0 -180
  169. package/src/tool/chatMain.ts +0 -594
  170. package/src/tool/commandPrompt.ts +0 -264
  171. package/src/tool/files.ts +0 -84
  172. package/src/tool/main.ts +0 -25
  173. package/src/tool/nodePlatform.ts +0 -73
  174. package/src/tool/options.ts +0 -144
  175. package/src/tool/prompt.ts +0 -101
  176. package/test_data/background_test_profile.json +0 -6
  177. package/test_data/background_test_script.json +0 -11
  178. package/test_data/dummyllm_script_crash.json +0 -32
  179. package/test_data/dummyllm_script_image_gen.json +0 -19
  180. package/test_data/dummyllm_script_image_gen_fe.json +0 -29
  181. package/test_data/dummyllm_script_invoke_image_gen_tool.json +0 -37
  182. package/test_data/dummyllm_script_render_tool.json +0 -29
  183. package/test_data/dummyllm_script_simplecalc.json +0 -28
  184. package/test_data/dummyllm_script_test_auto_approve.json +0 -81
  185. package/test_data/dummyllm_script_test_simplecalc_addition.json +0 -29
  186. package/test_data/frog.png +0 -0
  187. package/test_data/frog.png.b64 +0 -1
  188. package/test_data/git_message_profile.json +0 -4
  189. package/test_data/git_wip_system.txt +0 -5
  190. package/test_data/image_gen_test_profile.json +0 -5
  191. package/test_data/pr_message_profile.json +0 -4
  192. package/test_data/pr_review_profile.json +0 -4
  193. package/test_data/prompt_simplecalc.txt +0 -1
  194. package/test_data/simplecalc_profile.json +0 -4
  195. package/test_data/sudomcp_import_profile.json +0 -4
  196. package/test_data/test_script_profile.json +0 -8
  197. package/tsconfig.json +0 -13
  198. package/vitest.config.ts +0 -39
  199. /package/dist/agent/src/{chat/utils → agent/tools/contentExtractors}/htmlToText.js +0 -0
@@ -1,590 +0,0 @@
1
- import { expect } from "vitest";
2
- import { strict as assert } from "assert";
3
-
4
- import { Schema } from "@xalia/xmcp/sdk";
5
-
6
- import {
7
- Agent,
8
- AgentEx,
9
- AgentProfile,
10
- IAgentToolProvider,
11
- ToolCallResult,
12
- completionToAssistantMessageParam,
13
- } from "../agent/agent";
14
- import {
15
- AssistantMessageParam,
16
- Choice,
17
- MessageParam,
18
- MessageToolCall,
19
- ToolDescriptor,
20
- ToolMessageParam,
21
- } from "../agent/llm";
22
- import { ContextManager } from "../agent/context";
23
- import { LOCAL_SERVER_URL, SkillManager } from "../agent/sudoMcpServerManager";
24
- import { SystemPromptProvider } from "../agent/promptProvider";
25
- import {
26
- DUMMY_PLATFORM,
27
- TestAgentEventHandler,
28
- TestDummyLLM,
29
- TestErrorLLM,
30
- } from "./testTools";
31
- import { DummyLLMScriptEntry } from "../agent/dummyLLM";
32
-
33
- function clone<T>(a: T): T {
34
- return JSON.parse(JSON.stringify(a)) as T;
35
- }
36
-
37
- const DUMMY_SCRIPT: Choice[] = [
38
- {
39
- index: 0,
40
- finish_reason: "stop",
41
- message: {
42
- content: "message1",
43
- refusal: null,
44
- role: "assistant",
45
- },
46
- logprobs: null,
47
- },
48
- {
49
- index: 0,
50
- finish_reason: "stop",
51
- message: {
52
- content: "message2",
53
- refusal: null,
54
- role: "assistant",
55
- },
56
- logprobs: null,
57
- },
58
- ];
59
-
60
- function createCallTestToolScript(
61
- tool_call_ids: string[],
62
- param1: string,
63
- param2: number
64
- ): {
65
- script: Choice[];
66
- expectCompletions: AssistantMessageParam[];
67
- expectAgentMessages: string[];
68
- expectToolResults: ToolMessageParam[];
69
- tool0_descriptor: ToolDescriptor;
70
- tool0_fn: (agent: AgentEx, args: unknown) => Promise<ToolCallResult>;
71
- test_tool_descriptor: ToolDescriptor;
72
- test_tool_fn: (agent: AgentEx, args: unknown) => Promise<ToolCallResult>;
73
- } {
74
- // A tool with no args
75
-
76
- const tool0_params: Schema = {
77
- type: "object",
78
- properties: {},
79
- };
80
-
81
- const tool0_descriptor: ToolDescriptor = {
82
- type: "function",
83
- function: {
84
- name: "tool0",
85
- parameters: tool0_params,
86
- strict: true,
87
- },
88
- };
89
-
90
- const tool0_fn = (_: AgentEx, _args: unknown): Promise<ToolCallResult> => {
91
- return Promise.resolve({ response: "0" });
92
- };
93
-
94
- // A trivial tool
95
-
96
- const test_tool_params: Schema = {
97
- type: "object",
98
- properties: {
99
- param1: {
100
- type: "string",
101
- },
102
- param2: {
103
- type: "number",
104
- },
105
- },
106
- required: ["param1", "param2"],
107
- };
108
-
109
- const test_tool_descriptor: ToolDescriptor = {
110
- type: "function",
111
- function: {
112
- name: "test_tool",
113
- parameters: test_tool_params,
114
- strict: true,
115
- },
116
- };
117
-
118
- const test_tool_fn = async (
119
- _: AgentEx,
120
- args: unknown
121
- ): Promise<ToolCallResult> => {
122
- const { param1, param2 } = args as { param1: string; param2: number };
123
- return new Promise((r) => {
124
- r({
125
- response: `tool_result: '${param1}' '${String(param2)}'`,
126
- _meta: { type: "text/plain" },
127
- });
128
- });
129
- };
130
-
131
- const tool_calls: MessageToolCall[] = [];
132
- const expectToolResults: ToolMessageParam[] = [];
133
-
134
- // First tool call (if requested) is test_tool
135
- if (tool_call_ids.length > 0) {
136
- const id = tool_call_ids[0];
137
- tool_calls.push({
138
- id,
139
- function: {
140
- name: "test_tool",
141
- arguments: JSON.stringify({ param1, param2 }),
142
- },
143
- type: "function",
144
- });
145
- expectToolResults.push({
146
- content: `tool_result: '${param1}' '${String(param2)}'`,
147
- role: "tool",
148
- tool_call_id: id,
149
- _meta: { type: "text/plain" },
150
- });
151
- }
152
-
153
- // Second tool call (if requested) is tool0
154
- if (tool_call_ids.length > 1) {
155
- const id = tool_call_ids[1];
156
- tool_calls.push({
157
- id,
158
- function: {
159
- name: "tool0",
160
- arguments: "",
161
- },
162
- type: "function",
163
- });
164
- expectToolResults.push({
165
- content: "0",
166
- role: "tool",
167
- tool_call_id: id,
168
- });
169
- }
170
-
171
- // 3 calls not supported
172
- if (tool_call_ids.length > 2) {
173
- throw new Error("3 toolc alls not supported in this test");
174
- }
175
-
176
- // A script that uses the tools
177
-
178
- const script: Choice[] = [
179
- {
180
- index: 0,
181
- finish_reason: "tool_calls",
182
- message: {
183
- content: "calling test_tool.",
184
- refusal: null,
185
- role: "assistant",
186
- tool_calls,
187
- },
188
- logprobs: null,
189
- },
190
- {
191
- index: 0,
192
- finish_reason: "stop",
193
- message: {
194
- content: "message after tools calls.",
195
- refusal: null,
196
- role: "assistant",
197
- },
198
- logprobs: null,
199
- },
200
- ];
201
-
202
- // Expected output
203
-
204
- const expectAgentMessages = [
205
- "calling test_tool.",
206
- "message after tools calls.",
207
- ];
208
-
209
- return {
210
- script,
211
- expectCompletions: script.map((s) =>
212
- completionToAssistantMessageParam(s.message)
213
- ),
214
- expectAgentMessages,
215
- expectToolResults,
216
- tool0_descriptor,
217
- tool0_fn,
218
- test_tool_descriptor,
219
- test_tool_fn,
220
- };
221
- }
222
-
223
- /// Return a dummy agent and a TestAgentEventHandler for tracking messages.
224
- async function createTestAgent(script: Choice[]): Promise<{
225
- agent: Agent;
226
- skillManager: SkillManager;
227
- eventHandler: TestAgentEventHandler;
228
- }> {
229
- const agentProfile: AgentProfile = {
230
- model: "dummy:" + JSON.stringify(script),
231
- system_prompt: "SYSTEM_PROMPT",
232
- mcp_settings: {},
233
- };
234
-
235
- const eventHandler = new TestAgentEventHandler();
236
-
237
- const skillManager = await SkillManager.initialize(
238
- (url: string, authResultP: Promise<boolean>, displayName: string) => {
239
- DUMMY_PLATFORM.openUrl(url, authResultP, displayName);
240
- },
241
- LOCAL_SERVER_URL,
242
- "dummy_key",
243
- undefined
244
- );
245
-
246
- const agent = Agent.initializeWithLLM(
247
- eventHandler,
248
- new TestDummyLLM(script),
249
- new ContextManager(agentProfile.system_prompt, []),
250
- skillManager
251
- );
252
-
253
- return { agent, skillManager, eventHandler };
254
- }
255
-
256
- describe("Agent", () => {
257
- it("correctly calls custom tools", async function () {
258
- const tool_call_id: string = "tool_call_1";
259
- const param1: string = "first param";
260
- const param2: number = 2;
261
-
262
- const {
263
- script,
264
- expectAgentMessages,
265
- expectToolResults,
266
- tool0_descriptor,
267
- tool0_fn,
268
- test_tool_descriptor,
269
- test_tool_fn,
270
- } = createCallTestToolScript([tool_call_id], param1, param2);
271
- const { agent /*, skillManager */, eventHandler } =
272
- await createTestAgent(script);
273
-
274
- agent.addAgentTool(tool0_descriptor, tool0_fn);
275
- agent.addAgentTool(test_tool_descriptor, test_tool_fn);
276
-
277
- await agent.userMessageEx("user message 1");
278
-
279
- expect(eventHandler.getAgentMessages()).eql(expectAgentMessages);
280
- expect(eventHandler.getToolCallResults()).eql(expectToolResults);
281
-
282
- // Check the ordering
283
-
284
- const allExpect = [
285
- completionToAssistantMessageParam(script[0].message),
286
- ...expectToolResults,
287
- completionToAssistantMessageParam(script[1].message),
288
- ];
289
- const all = eventHandler.getAll();
290
- expect(all).eql(allExpect);
291
-
292
- const allToolCalls = eventHandler.getToolCalls();
293
- const agentToolCalls = eventHandler.getAgentToolCalls();
294
- const expectToolCalls = script[0].message.tool_calls;
295
-
296
- expect(allToolCalls).eql(expectToolCalls);
297
- expect(agentToolCalls).eql(expectToolCalls);
298
- });
299
-
300
- it("correctly invokes tool providers", async function () {
301
- const tool_call_id: string = "tool_call_1";
302
- const param1: string = "asdf";
303
- const param2: number = 3;
304
- const {
305
- script,
306
- expectCompletions,
307
- expectAgentMessages,
308
- expectToolResults,
309
- test_tool_descriptor,
310
- test_tool_fn,
311
- } = createCallTestToolScript([tool_call_id], param1, param2);
312
- const { agent /*, skillManager */, eventHandler } =
313
- await createTestAgent(script);
314
-
315
- const toolProvider: IAgentToolProvider = {
316
- setup: (agent: AgentEx) => {
317
- // Add the tool async to test this mechanism
318
- return new Promise<void>((r) => {
319
- setTimeout(() => {
320
- agent.addAgentTool(test_tool_descriptor, test_tool_fn);
321
- r();
322
- });
323
- });
324
- },
325
- };
326
- await agent.addAgentToolProvider(toolProvider);
327
-
328
- await agent.userMessageEx("user message 1");
329
-
330
- expect(eventHandler.getCompletions()).eql(expectCompletions);
331
- expect(eventHandler.getAgentMessages()).eql(expectAgentMessages);
332
- expect(eventHandler.getToolCallResults()).eql(expectToolResults);
333
- });
334
-
335
- it("correctly reflects system prompt", async function () {
336
- const llm = new TestDummyLLM(DUMMY_SCRIPT);
337
- const contextManager = new ContextManager("agent_prompt", []);
338
- const agent = Agent.initializeWithLLM(
339
- new TestAgentEventHandler(),
340
- llm,
341
- contextManager
342
- );
343
-
344
- SystemPromptProvider.setGlobalPrompt("global_prompt");
345
-
346
- // NOTE: SystemPromptProvider/ContextManager is unit tested elsewhere so
347
- // we assume it computes the correct prompt. Here we check that this is
348
- // reflected in the request to LLM.
349
-
350
- // Check the prompt
351
-
352
- await agent.userMessageEx("user message 1");
353
- let lastRequest = llm.getLastRequest();
354
- assert(lastRequest);
355
- expect(lastRequest[0].content).eql(
356
- contextManager.getLLMContext()[0].content
357
- );
358
- expect(agent.getSystemPrompt()).eql("agent_prompt");
359
-
360
- // Update and re-check the prompt
361
-
362
- agent.setSystemPrompt("agent_prompt_2");
363
- await agent.userMessageEx("user message 1");
364
- lastRequest = llm.getLastRequest();
365
- assert(lastRequest);
366
- expect(lastRequest[0].content).eql(
367
- contextManager.getLLMContext()[0].content
368
- );
369
- expect(agent.getSystemPrompt()).eql("agent_prompt_2");
370
- });
371
-
372
- it("correctly orders messages for multiple tool calls", async function () {
373
- const tool_call_ids: string[] = ["tool_call_1", "tool_call_2"];
374
- const param1: string = "asdf";
375
- const param2: number = 3;
376
- const {
377
- script,
378
- expectToolResults,
379
- test_tool_descriptor,
380
- test_tool_fn,
381
- tool0_descriptor,
382
- tool0_fn,
383
- } = createCallTestToolScript(tool_call_ids, param1, param2);
384
- const { agent /*, skillManager */, eventHandler } =
385
- await createTestAgent(script);
386
- agent.addAgentTool(test_tool_descriptor, test_tool_fn);
387
- agent.addAgentTool(tool0_descriptor, tool0_fn);
388
-
389
- await agent.userMessageEx("user message 1");
390
-
391
- // Check the event handler was called with all completions and tool
392
- // results, in the correct order.
393
-
394
- const allExpect = [
395
- completionToAssistantMessageParam(script[0].message),
396
- ...expectToolResults,
397
- completionToAssistantMessageParam(script[1].message),
398
- ];
399
- const all = eventHandler.getAll();
400
- expect(all).eql(allExpect);
401
-
402
- // The conversation (context) messages (order and number) should also
403
- // match this.
404
-
405
- const conv = agent.getConversation();
406
- expect(conv.slice(1)).eql(all);
407
- });
408
-
409
- it("correctly updates tool call args", async function () {
410
- const tool_call_ids: string[] = ["tool_call_1", "tool_call_2"];
411
- const param1: string = "asdf";
412
- const param2: number = 3;
413
- const {
414
- script,
415
- expectToolResults,
416
- test_tool_descriptor,
417
- test_tool_fn,
418
- tool0_descriptor,
419
- tool0_fn,
420
- } = createCallTestToolScript(tool_call_ids, param1, param2);
421
- const { agent /*, skillManager */, eventHandler } =
422
- await createTestAgent(script);
423
-
424
- // Take a copy of the script now, since this will be updated when the
425
- // tools redacted their args.
426
-
427
- const scriptCopy: Choice[] = clone(script);
428
-
429
- // Define the tool to update the arg. The transform is to up-case
430
- // `param1: string` and add 100 to `param2: number`.
431
-
432
- type Args = { param1: string; param2: number };
433
- const transformArgs = (args: Args): Args => {
434
- return { param1: args.param1.toUpperCase(), param2: args.param2 + 100 };
435
- };
436
- const transformArgsStr = (argsStr: string): string => {
437
- const args = JSON.parse(argsStr) as Args;
438
- return JSON.stringify(transformArgs(args));
439
- };
440
- const newToolFn = async (
441
- agent: AgentEx,
442
- args: unknown
443
- ): Promise<ToolCallResult> => {
444
- const result = await test_tool_fn(agent, args);
445
- result.overwriteArgs = JSON.stringify(transformArgs(args as Args));
446
- return result;
447
- };
448
- agent.addAgentTool(test_tool_descriptor, newToolFn);
449
- agent.addAgentTool(tool0_descriptor, tool0_fn);
450
-
451
- // Send a message and trigger the tool calls
452
-
453
- await agent.userMessageEx("user message 1");
454
-
455
- // Check the event handler was called with all completions and tool
456
- // results, in the correct order.
457
-
458
- const transformToolCall = (toolCall: MessageToolCall): MessageToolCall => {
459
- return {
460
- ...toolCall,
461
- function: {
462
- ...toolCall.function,
463
- arguments: transformArgsStr(toolCall.function.arguments),
464
- },
465
- };
466
- };
467
-
468
- assert(scriptCopy[0].message.tool_calls);
469
- const transformedFirstMsg = completionToAssistantMessageParam({
470
- ...scriptCopy[0].message,
471
- tool_calls: [
472
- transformToolCall(scriptCopy[0].message.tool_calls[0]),
473
- scriptCopy[0].message.tool_calls[1],
474
- ],
475
- });
476
-
477
- const allExpect: MessageParam[] = [
478
- transformedFirstMsg,
479
- ...expectToolResults,
480
- completionToAssistantMessageParam(scriptCopy[1].message),
481
- ];
482
- const all = eventHandler.getAll();
483
- const conv = agent.getConversation();
484
-
485
- expect(all).eql(allExpect);
486
- expect(conv.slice(1)).eql(all);
487
- });
488
-
489
- it("correctly updates tool call results", async function () {
490
- const tool_call_ids: string[] = ["tool_call_1", "tool_call_2"];
491
- const param1: string = "asdf";
492
- const param2: number = 3;
493
- const {
494
- script,
495
- expectToolResults,
496
- test_tool_descriptor,
497
- test_tool_fn,
498
- tool0_descriptor,
499
- tool0_fn,
500
- } = createCallTestToolScript(tool_call_ids, param1, param2);
501
- const { agent /*, skillManager */, eventHandler } =
502
- await createTestAgent(script);
503
-
504
- // Define the tool to update the results. The transform is to up-case
505
- // the whole result string.
506
-
507
- const transformResult = (result: string): string => {
508
- return result.toUpperCase();
509
- };
510
- const newToolFn = async (
511
- agent: AgentEx,
512
- args: unknown
513
- ): Promise<ToolCallResult> => {
514
- const result = await test_tool_fn(agent, args);
515
- result.overwriteResponse = transformResult(result.response);
516
- return result;
517
- };
518
- agent.addAgentTool(tool0_descriptor, tool0_fn);
519
- agent.addAgentTool(test_tool_descriptor, newToolFn);
520
-
521
- // Send a message and trigger the tool calls
522
-
523
- await agent.userMessageEx("user message 1");
524
-
525
- // Check the event handler was called with all completions and tool
526
- // results as expected.
527
-
528
- const expectToolCallResults: MessageParam[] = expectToolResults.map(
529
- (tr) => {
530
- assert(typeof tr.content === "string");
531
- return {
532
- ...tr,
533
- content: transformResult(tr.content),
534
- };
535
- }
536
- );
537
-
538
- const allExpect: MessageParam[] = [
539
- completionToAssistantMessageParam(script[0].message),
540
- ...expectToolCallResults,
541
- completionToAssistantMessageParam(script[1].message),
542
- ];
543
- const all = eventHandler.getAll();
544
- const conv = agent.getConversation();
545
-
546
- expect(all).eql(allExpect);
547
- expect(conv.slice(1)).eql(all);
548
- });
549
-
550
- it("correctly handles LLM errors", async function () {
551
- const eventHandler = new TestAgentEventHandler();
552
- const llm = new TestErrorLLM();
553
- const ctxMgr = new ContextManager("SYSTEM_PROMPT", []);
554
- const agent = Agent.initializeWithLLM(eventHandler, llm, ctxMgr);
555
-
556
- await expect(
557
- agent.userMessagesRaw([{ role: "user", content: "message" }])
558
- ).rejects.toThrow();
559
-
560
- // Check the Agent has not added the user messages.
561
- expect(ctxMgr.getLLMContext().length).eql(1);
562
- });
563
-
564
- it("supports reasoning token callbacks", async function () {
565
- const script: DummyLLMScriptEntry[] = [
566
- {
567
- finish_reason: "reasoning",
568
- message: "Some reasoning tokens...",
569
- },
570
- {
571
- index: 0,
572
- finish_reason: "stop",
573
- message: {
574
- content: "Agent Message",
575
- refusal: null,
576
- role: "assistant",
577
- },
578
- logprobs: null,
579
- },
580
- ];
581
-
582
- const llm = new TestDummyLLM(script);
583
- const eventHandler = new TestAgentEventHandler();
584
- const ctxMgr = new ContextManager("SYSTEM_PROMPT", []);
585
- const agent = Agent.initializeWithLLM(eventHandler, llm, ctxMgr);
586
-
587
- await agent.userMessageEx("user message 1");
588
- expect(eventHandler.getReasoning()).eql([script[0].message, ""]);
589
- });
590
- });