@illuma-ai/agents 1.1.20 → 1.1.22

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 (246) hide show
  1. package/dist/cjs/graphs/Graph.cjs +12 -1
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/graphs/MultiAgentGraph.cjs +85 -1
  4. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  5. package/dist/cjs/llm/bedrock/index.cjs +14 -0
  6. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  7. package/dist/cjs/run.cjs +20 -9
  8. package/dist/cjs/run.cjs.map +1 -1
  9. package/dist/esm/graphs/Graph.mjs +12 -1
  10. package/dist/esm/graphs/Graph.mjs.map +1 -1
  11. package/dist/esm/graphs/MultiAgentGraph.mjs +85 -1
  12. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  13. package/dist/esm/llm/bedrock/index.mjs +14 -0
  14. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  15. package/dist/esm/run.mjs +20 -9
  16. package/dist/esm/run.mjs.map +1 -1
  17. package/dist/types/graphs/MultiAgentGraph.d.ts +17 -0
  18. package/package.json +1 -1
  19. package/src/graphs/Graph.ts +12 -1
  20. package/src/graphs/MultiAgentGraph.ts +105 -1
  21. package/src/graphs/__tests__/multi-agent-delegate.test.ts +191 -0
  22. package/src/llm/bedrock/index.ts +17 -0
  23. package/src/run.ts +20 -11
  24. package/src/scripts/test-bedrock-handoff-autonomous.ts +231 -0
  25. package/src/agents/AgentContext.js +0 -782
  26. package/src/agents/AgentContext.test.js +0 -421
  27. package/src/agents/__tests__/AgentContext.test.js +0 -678
  28. package/src/agents/__tests__/resolveStructuredOutputMode.test.js +0 -117
  29. package/src/common/enum.js +0 -192
  30. package/src/common/index.js +0 -3
  31. package/src/events.js +0 -166
  32. package/src/graphs/Graph.js +0 -1857
  33. package/src/graphs/MultiAgentGraph.js +0 -1092
  34. package/src/graphs/__tests__/structured-output.integration.test.js +0 -624
  35. package/src/graphs/__tests__/structured-output.test.js +0 -144
  36. package/src/graphs/contextManagement.e2e.test.js +0 -718
  37. package/src/graphs/contextManagement.test.js +0 -485
  38. package/src/graphs/handoffValidation.test.js +0 -276
  39. package/src/graphs/index.js +0 -3
  40. package/src/index.js +0 -28
  41. package/src/instrumentation.js +0 -21
  42. package/src/llm/anthropic/index.js +0 -319
  43. package/src/llm/anthropic/types.js +0 -46
  44. package/src/llm/anthropic/utils/message_inputs.js +0 -627
  45. package/src/llm/anthropic/utils/message_outputs.js +0 -290
  46. package/src/llm/anthropic/utils/output_parsers.js +0 -89
  47. package/src/llm/anthropic/utils/tools.js +0 -25
  48. package/src/llm/bedrock/__tests__/bedrock-caching.test.js +0 -392
  49. package/src/llm/bedrock/index.js +0 -303
  50. package/src/llm/bedrock/types.js +0 -2
  51. package/src/llm/bedrock/utils/index.js +0 -6
  52. package/src/llm/bedrock/utils/message_inputs.js +0 -463
  53. package/src/llm/bedrock/utils/message_outputs.js +0 -269
  54. package/src/llm/fake.js +0 -92
  55. package/src/llm/google/index.js +0 -215
  56. package/src/llm/google/types.js +0 -12
  57. package/src/llm/google/utils/common.js +0 -670
  58. package/src/llm/google/utils/tools.js +0 -111
  59. package/src/llm/google/utils/zod_to_genai_parameters.js +0 -47
  60. package/src/llm/openai/index.js +0 -1033
  61. package/src/llm/openai/types.js +0 -2
  62. package/src/llm/openai/utils/index.js +0 -756
  63. package/src/llm/openai/utils/isReasoningModel.test.js +0 -79
  64. package/src/llm/openrouter/index.js +0 -261
  65. package/src/llm/openrouter/reasoning.test.js +0 -181
  66. package/src/llm/providers.js +0 -36
  67. package/src/llm/text.js +0 -65
  68. package/src/llm/vertexai/index.js +0 -402
  69. package/src/messages/__tests__/tools.test.js +0 -392
  70. package/src/messages/cache.js +0 -404
  71. package/src/messages/cache.test.js +0 -1167
  72. package/src/messages/content.js +0 -48
  73. package/src/messages/content.test.js +0 -314
  74. package/src/messages/core.js +0 -359
  75. package/src/messages/ensureThinkingBlock.test.js +0 -997
  76. package/src/messages/format.js +0 -973
  77. package/src/messages/formatAgentMessages.test.js +0 -2278
  78. package/src/messages/formatAgentMessages.tools.test.js +0 -362
  79. package/src/messages/formatMessage.test.js +0 -608
  80. package/src/messages/ids.js +0 -18
  81. package/src/messages/index.js +0 -9
  82. package/src/messages/labelContentByAgent.test.js +0 -725
  83. package/src/messages/prune.js +0 -438
  84. package/src/messages/reducer.js +0 -60
  85. package/src/messages/shiftIndexTokenCountMap.test.js +0 -63
  86. package/src/messages/summarize.js +0 -146
  87. package/src/messages/summarize.test.js +0 -332
  88. package/src/messages/tools.js +0 -90
  89. package/src/mockStream.js +0 -81
  90. package/src/prompts/collab.js +0 -7
  91. package/src/prompts/index.js +0 -3
  92. package/src/prompts/taskmanager.js +0 -58
  93. package/src/run.js +0 -427
  94. package/src/schemas/index.js +0 -3
  95. package/src/schemas/schema-preparation.test.js +0 -370
  96. package/src/schemas/validate.js +0 -314
  97. package/src/schemas/validate.test.js +0 -264
  98. package/src/scripts/abort.js +0 -127
  99. package/src/scripts/ant_web_search.js +0 -130
  100. package/src/scripts/ant_web_search_edge_case.js +0 -133
  101. package/src/scripts/ant_web_search_error_edge_case.js +0 -119
  102. package/src/scripts/args.js +0 -41
  103. package/src/scripts/bedrock-cache-debug.js +0 -186
  104. package/src/scripts/bedrock-content-aggregation-test.js +0 -195
  105. package/src/scripts/bedrock-merge-test.js +0 -80
  106. package/src/scripts/bedrock-parallel-tools-test.js +0 -150
  107. package/src/scripts/caching.js +0 -106
  108. package/src/scripts/cli.js +0 -152
  109. package/src/scripts/cli2.js +0 -119
  110. package/src/scripts/cli3.js +0 -163
  111. package/src/scripts/cli4.js +0 -165
  112. package/src/scripts/cli5.js +0 -165
  113. package/src/scripts/code_exec.js +0 -171
  114. package/src/scripts/code_exec_files.js +0 -180
  115. package/src/scripts/code_exec_multi_session.js +0 -185
  116. package/src/scripts/code_exec_ptc.js +0 -265
  117. package/src/scripts/code_exec_session.js +0 -217
  118. package/src/scripts/code_exec_simple.js +0 -120
  119. package/src/scripts/content.js +0 -111
  120. package/src/scripts/empty_input.js +0 -125
  121. package/src/scripts/handoff-test.js +0 -96
  122. package/src/scripts/image.js +0 -138
  123. package/src/scripts/memory.js +0 -83
  124. package/src/scripts/multi-agent-chain.js +0 -271
  125. package/src/scripts/multi-agent-conditional.js +0 -185
  126. package/src/scripts/multi-agent-document-review-chain.js +0 -171
  127. package/src/scripts/multi-agent-hybrid-flow.js +0 -264
  128. package/src/scripts/multi-agent-parallel-start.js +0 -214
  129. package/src/scripts/multi-agent-parallel.js +0 -346
  130. package/src/scripts/multi-agent-sequence.js +0 -184
  131. package/src/scripts/multi-agent-supervisor.js +0 -324
  132. package/src/scripts/multi-agent-test.js +0 -147
  133. package/src/scripts/parallel-asymmetric-tools-test.js +0 -202
  134. package/src/scripts/parallel-full-metadata-test.js +0 -176
  135. package/src/scripts/parallel-tools-test.js +0 -256
  136. package/src/scripts/programmatic_exec.js +0 -277
  137. package/src/scripts/programmatic_exec_agent.js +0 -168
  138. package/src/scripts/search.js +0 -118
  139. package/src/scripts/sequential-full-metadata-test.js +0 -143
  140. package/src/scripts/simple.js +0 -174
  141. package/src/scripts/single-agent-metadata-test.js +0 -152
  142. package/src/scripts/stream.js +0 -113
  143. package/src/scripts/test-custom-prompt-key.js +0 -132
  144. package/src/scripts/test-handoff-input.js +0 -143
  145. package/src/scripts/test-handoff-preamble.js +0 -227
  146. package/src/scripts/test-handoff-steering.js +0 -353
  147. package/src/scripts/test-multi-agent-list-handoff.js +0 -318
  148. package/src/scripts/test-parallel-agent-labeling.js +0 -253
  149. package/src/scripts/test-parallel-handoffs.js +0 -229
  150. package/src/scripts/test-thinking-handoff-bedrock.js +0 -132
  151. package/src/scripts/test-thinking-handoff.js +0 -132
  152. package/src/scripts/test-thinking-to-thinking-handoff-bedrock.js +0 -140
  153. package/src/scripts/test-tool-before-handoff-role-order.js +0 -223
  154. package/src/scripts/test-tools-before-handoff.js +0 -187
  155. package/src/scripts/test_code_api.js +0 -263
  156. package/src/scripts/thinking-bedrock.js +0 -128
  157. package/src/scripts/thinking-vertexai.js +0 -130
  158. package/src/scripts/thinking.js +0 -134
  159. package/src/scripts/tool_search.js +0 -114
  160. package/src/scripts/tools.js +0 -125
  161. package/src/specs/agent-handoffs-bedrock.integration.test.js +0 -280
  162. package/src/specs/agent-handoffs.test.js +0 -924
  163. package/src/specs/anthropic.simple.test.js +0 -287
  164. package/src/specs/azure.simple.test.js +0 -381
  165. package/src/specs/cache.simple.test.js +0 -282
  166. package/src/specs/custom-event-await.test.js +0 -148
  167. package/src/specs/deepseek.simple.test.js +0 -189
  168. package/src/specs/emergency-prune.test.js +0 -308
  169. package/src/specs/moonshot.simple.test.js +0 -237
  170. package/src/specs/observability.integration.test.js +0 -1337
  171. package/src/specs/openai.simple.test.js +0 -233
  172. package/src/specs/openrouter.simple.test.js +0 -202
  173. package/src/specs/prune.test.js +0 -733
  174. package/src/specs/reasoning.test.js +0 -144
  175. package/src/specs/spec.utils.js +0 -4
  176. package/src/specs/thinking-handoff.test.js +0 -486
  177. package/src/specs/thinking-prune.test.js +0 -600
  178. package/src/specs/token-distribution-edge-case.test.js +0 -246
  179. package/src/specs/token-memoization.test.js +0 -32
  180. package/src/specs/tokens.test.js +0 -49
  181. package/src/specs/tool-error.test.js +0 -139
  182. package/src/splitStream.js +0 -204
  183. package/src/splitStream.test.js +0 -504
  184. package/src/stream.js +0 -650
  185. package/src/stream.test.js +0 -225
  186. package/src/test/mockTools.js +0 -340
  187. package/src/tools/BrowserTools.js +0 -245
  188. package/src/tools/Calculator.js +0 -38
  189. package/src/tools/Calculator.test.js +0 -225
  190. package/src/tools/CodeExecutor.js +0 -233
  191. package/src/tools/ProgrammaticToolCalling.js +0 -602
  192. package/src/tools/StreamingToolCallBuffer.js +0 -179
  193. package/src/tools/ToolNode.js +0 -930
  194. package/src/tools/ToolSearch.js +0 -904
  195. package/src/tools/__tests__/BrowserTools.test.js +0 -306
  196. package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.js +0 -276
  197. package/src/tools/__tests__/ProgrammaticToolCalling.test.js +0 -807
  198. package/src/tools/__tests__/StreamingToolCallBuffer.test.js +0 -175
  199. package/src/tools/__tests__/ToolApproval.test.js +0 -675
  200. package/src/tools/__tests__/ToolNode.recovery.test.js +0 -200
  201. package/src/tools/__tests__/ToolNode.session.test.js +0 -319
  202. package/src/tools/__tests__/ToolSearch.integration.test.js +0 -125
  203. package/src/tools/__tests__/ToolSearch.test.js +0 -812
  204. package/src/tools/__tests__/handlers.test.js +0 -799
  205. package/src/tools/__tests__/truncation-recovery.integration.test.js +0 -362
  206. package/src/tools/handlers.js +0 -306
  207. package/src/tools/schema.js +0 -25
  208. package/src/tools/search/anthropic.js +0 -34
  209. package/src/tools/search/content.js +0 -116
  210. package/src/tools/search/content.test.js +0 -133
  211. package/src/tools/search/firecrawl.js +0 -173
  212. package/src/tools/search/format.js +0 -198
  213. package/src/tools/search/highlights.js +0 -241
  214. package/src/tools/search/index.js +0 -3
  215. package/src/tools/search/jina-reranker.test.js +0 -106
  216. package/src/tools/search/rerankers.js +0 -165
  217. package/src/tools/search/schema.js +0 -102
  218. package/src/tools/search/search.js +0 -561
  219. package/src/tools/search/serper-scraper.js +0 -126
  220. package/src/tools/search/test.js +0 -129
  221. package/src/tools/search/tool.js +0 -453
  222. package/src/tools/search/types.js +0 -2
  223. package/src/tools/search/utils.js +0 -59
  224. package/src/types/graph.js +0 -24
  225. package/src/types/graph.test.js +0 -192
  226. package/src/types/index.js +0 -7
  227. package/src/types/llm.js +0 -2
  228. package/src/types/messages.js +0 -2
  229. package/src/types/run.js +0 -2
  230. package/src/types/stream.js +0 -2
  231. package/src/types/tools.js +0 -2
  232. package/src/utils/contextAnalytics.js +0 -79
  233. package/src/utils/contextAnalytics.test.js +0 -166
  234. package/src/utils/events.js +0 -26
  235. package/src/utils/graph.js +0 -11
  236. package/src/utils/handlers.js +0 -65
  237. package/src/utils/index.js +0 -10
  238. package/src/utils/llm.js +0 -21
  239. package/src/utils/llmConfig.js +0 -205
  240. package/src/utils/logging.js +0 -37
  241. package/src/utils/misc.js +0 -51
  242. package/src/utils/run.js +0 -69
  243. package/src/utils/schema.js +0 -21
  244. package/src/utils/title.js +0 -119
  245. package/src/utils/tokens.js +0 -92
  246. package/src/utils/toonFormat.js +0 -379
@@ -1,362 +0,0 @@
1
- import { HumanMessage, AIMessage, ToolMessage } from '@langchain/core/messages';
2
- import { formatAgentMessages } from './format';
3
- import { ContentTypes } from '@/common';
4
- describe('formatAgentMessages with tools parameter', () => {
5
- it('should process messages normally when tools is not provided', () => {
6
- const payload = [
7
- { role: 'user', content: 'Hello' },
8
- {
9
- role: 'assistant',
10
- content: [
11
- {
12
- type: ContentTypes.TEXT,
13
- [ContentTypes.TEXT]: 'Let me check that for you.',
14
- tool_call_ids: ['123'],
15
- },
16
- {
17
- type: ContentTypes.TOOL_CALL,
18
- tool_call: {
19
- id: '123',
20
- name: 'search',
21
- args: '{"query":"weather"}',
22
- output: 'The weather is sunny.',
23
- },
24
- },
25
- ],
26
- },
27
- ];
28
- const result = formatAgentMessages(payload);
29
- expect(result.messages).toHaveLength(3);
30
- expect(result.messages[0]).toBeInstanceOf(HumanMessage);
31
- expect(result.messages[1]).toBeInstanceOf(AIMessage);
32
- expect(result.messages[2]).toBeInstanceOf(ToolMessage);
33
- expect(result.messages[1].tool_calls).toHaveLength(1);
34
- expect(result.messages[2].tool_call_id).toBe('123');
35
- });
36
- it('should filter out all tool calls when tools set is empty', () => {
37
- const payload = [
38
- { role: 'user', content: 'What\'s the weather?' },
39
- {
40
- role: 'assistant',
41
- content: [
42
- {
43
- type: ContentTypes.TEXT,
44
- [ContentTypes.TEXT]: 'Let me check the weather for you.',
45
- tool_call_ids: ['weather_1'],
46
- },
47
- {
48
- type: ContentTypes.TOOL_CALL,
49
- tool_call: {
50
- id: 'weather_1',
51
- name: 'check_weather',
52
- args: '{"location":"New York"}',
53
- output: 'Sunny, 75°F',
54
- },
55
- },
56
- ],
57
- },
58
- ];
59
- // Provide an empty set of allowed tools
60
- const allowedTools = new Set();
61
- const result = formatAgentMessages(payload, undefined, allowedTools);
62
- // Should filter out the tool call, keeping only text content
63
- expect(result.messages).toHaveLength(2);
64
- expect(result.messages[0]).toBeInstanceOf(HumanMessage);
65
- expect(result.messages[1]).toBeInstanceOf(AIMessage);
66
- // The AIMessage should have no tool_calls (they were filtered out)
67
- expect(result.messages[1].tool_calls).toHaveLength(0);
68
- });
69
- it('should filter out tool calls not in the allowed set', () => {
70
- const payload = [
71
- { role: 'user', content: 'What\'s the weather?' },
72
- {
73
- role: 'assistant',
74
- content: [
75
- {
76
- type: ContentTypes.TEXT,
77
- [ContentTypes.TEXT]: 'Let me check the weather for you.',
78
- tool_call_ids: ['weather_1'],
79
- },
80
- {
81
- type: ContentTypes.TOOL_CALL,
82
- tool_call: {
83
- id: 'weather_1',
84
- name: 'check_weather',
85
- args: '{"location":"New York"}',
86
- output: 'Sunny, 75°F',
87
- },
88
- },
89
- ],
90
- },
91
- ];
92
- // Provide a set of allowed tools that doesn't include 'check_weather'
93
- const allowedTools = new Set(['search', 'calculator']);
94
- const result = formatAgentMessages(payload, undefined, allowedTools);
95
- // Should filter out the invalid tool call, keeping text content
96
- expect(result.messages).toHaveLength(2);
97
- expect(result.messages[0]).toBeInstanceOf(HumanMessage);
98
- expect(result.messages[1]).toBeInstanceOf(AIMessage);
99
- // The AIMessage should have no tool_calls (check_weather was filtered out)
100
- expect(result.messages[1].tool_calls).toHaveLength(0);
101
- });
102
- it('should not convert tool messages when tool is in the allowed set', () => {
103
- const payload = [
104
- { role: 'user', content: 'What\'s the weather?' },
105
- {
106
- role: 'assistant',
107
- content: [
108
- {
109
- type: ContentTypes.TEXT,
110
- [ContentTypes.TEXT]: 'Let me check the weather for you.',
111
- tool_call_ids: ['weather_1'],
112
- },
113
- {
114
- type: ContentTypes.TOOL_CALL,
115
- tool_call: {
116
- id: 'weather_1',
117
- name: 'check_weather',
118
- args: '{"location":"New York"}',
119
- output: 'Sunny, 75°F',
120
- },
121
- },
122
- ],
123
- },
124
- ];
125
- // Provide a set of allowed tools that includes 'check_weather'
126
- const allowedTools = new Set(['check_weather', 'search']);
127
- const result = formatAgentMessages(payload, undefined, allowedTools);
128
- // Should keep the original structure
129
- expect(result.messages).toHaveLength(3);
130
- expect(result.messages[0]).toBeInstanceOf(HumanMessage);
131
- expect(result.messages[1]).toBeInstanceOf(AIMessage);
132
- expect(result.messages[2]).toBeInstanceOf(ToolMessage);
133
- });
134
- it('should handle multiple tool calls with mixed allowed/disallowed tools', () => {
135
- const payload = [
136
- {
137
- role: 'user',
138
- content: 'Tell me about the weather and calculate something',
139
- },
140
- {
141
- role: 'assistant',
142
- content: [
143
- {
144
- type: ContentTypes.TEXT,
145
- [ContentTypes.TEXT]: 'Let me check the weather first.',
146
- tool_call_ids: ['weather_1'],
147
- },
148
- {
149
- type: ContentTypes.TOOL_CALL,
150
- tool_call: {
151
- id: 'weather_1',
152
- name: 'check_weather',
153
- args: '{"location":"New York"}',
154
- output: 'Sunny, 75°F',
155
- },
156
- },
157
- {
158
- type: ContentTypes.TEXT,
159
- [ContentTypes.TEXT]: 'Now let me calculate something for you.',
160
- tool_call_ids: ['calc_1'],
161
- },
162
- {
163
- type: ContentTypes.TOOL_CALL,
164
- tool_call: {
165
- id: 'calc_1',
166
- name: 'calculator',
167
- args: '{"expression":"1+1"}',
168
- output: '2',
169
- },
170
- },
171
- ],
172
- },
173
- ];
174
- // Allow calculator but not check_weather
175
- const allowedTools = new Set(['calculator', 'search']);
176
- const result = formatAgentMessages(payload, undefined, allowedTools);
177
- // Should keep valid tool (calculator) and convert invalid (check_weather) to string
178
- expect(result.messages).toHaveLength(3);
179
- expect(result.messages[0]).toBeInstanceOf(HumanMessage);
180
- expect(result.messages[1]).toBeInstanceOf(AIMessage);
181
- expect(result.messages[2]).toBeInstanceOf(ToolMessage);
182
- // The AIMessage should have the calculator tool_call
183
- expect(result.messages[1].tool_calls).toHaveLength(1);
184
- expect(result.messages[1].tool_calls?.[0].name).toBe('calculator');
185
- // The content should include invalid tool as string
186
- expect(result.messages[1].content).toContain('check_weather');
187
- expect(result.messages[1].content).toContain('Sunny, 75°F');
188
- // The ToolMessage should be for calculator
189
- expect(result.messages[2].name).toBe('calculator');
190
- expect(result.messages[2].content).toBe('2');
191
- });
192
- it('should update indexTokenCountMap correctly when converting tool messages', () => {
193
- const payload = [
194
- { role: 'user', content: 'What\'s the weather?' },
195
- {
196
- role: 'assistant',
197
- content: [
198
- {
199
- type: ContentTypes.TEXT,
200
- [ContentTypes.TEXT]: 'Let me check the weather for you.',
201
- tool_call_ids: ['weather_1'],
202
- },
203
- {
204
- type: ContentTypes.TOOL_CALL,
205
- tool_call: {
206
- id: 'weather_1',
207
- name: 'check_weather',
208
- args: '{"location":"New York"}',
209
- output: 'Sunny, 75°F',
210
- },
211
- },
212
- ],
213
- },
214
- ];
215
- const indexTokenCountMap = {
216
- 0: 10, // 10 tokens for user message
217
- 1: 40, // 40 tokens for assistant message with tool call
218
- };
219
- // Provide a set of allowed tools that doesn't include 'check_weather'
220
- const allowedTools = new Set(['search', 'calculator']);
221
- const result = formatAgentMessages(payload, indexTokenCountMap, allowedTools);
222
- // Should have 2 messages and 2 entries in the token count map
223
- expect(result.messages).toHaveLength(2);
224
- expect(Object.keys(result.indexTokenCountMap || {}).length).toBe(2);
225
- // User message token count should be unchanged
226
- expect(result.indexTokenCountMap?.[0]).toBe(10);
227
- // All assistant message tokens should be assigned to the single AIMessage
228
- expect(result.indexTokenCountMap?.[1]).toBe(40);
229
- });
230
- it('should convert invalid tool to text content when no other content exists', () => {
231
- const payload = [
232
- {
233
- role: 'assistant',
234
- content: [
235
- {
236
- type: ContentTypes.TOOL_CALL,
237
- tool_call: {
238
- id: 'tool_1',
239
- name: 'check_weather',
240
- args: '{"location":"New York"}',
241
- output: 'Sunny, 75°F',
242
- },
243
- },
244
- ],
245
- },
246
- ];
247
- // Provide a set of allowed tools that doesn't include 'check_weather'
248
- const allowedTools = new Set(['search', 'calculator']);
249
- const result = formatAgentMessages(payload, undefined, allowedTools);
250
- // Should create an AIMessage with the invalid tool converted to text
251
- expect(result.messages).toHaveLength(1);
252
- expect(result.messages[0]).toBeInstanceOf(AIMessage);
253
- // The AIMessage should have no tool_calls (all were invalid)
254
- expect(result.messages[0].tool_calls).toHaveLength(0);
255
- // The content should contain the invalid tool info
256
- const content = result.messages[0].content;
257
- const contentStr = typeof content === 'string' ? content : JSON.stringify(content);
258
- expect(contentStr).toContain('check_weather');
259
- expect(contentStr).toContain('Sunny, 75°F');
260
- });
261
- it('should handle complex sequences with multiple tool calls', () => {
262
- const payload = [
263
- { role: 'user', content: 'Help me with a complex task' },
264
- {
265
- role: 'assistant',
266
- content: [
267
- {
268
- type: ContentTypes.TEXT,
269
- [ContentTypes.TEXT]: 'I\'ll search for information first.',
270
- tool_call_ids: ['search_1'],
271
- },
272
- {
273
- type: ContentTypes.TOOL_CALL,
274
- tool_call: {
275
- id: 'search_1',
276
- name: 'search',
277
- args: '{"query":"complex task"}',
278
- output: 'Found information about complex tasks.',
279
- },
280
- },
281
- ],
282
- },
283
- {
284
- role: 'assistant',
285
- content: [
286
- {
287
- type: ContentTypes.TEXT,
288
- [ContentTypes.TEXT]: 'Now I\'ll check the weather.',
289
- tool_call_ids: ['weather_1'],
290
- },
291
- {
292
- type: ContentTypes.TOOL_CALL,
293
- tool_call: {
294
- id: 'weather_1',
295
- name: 'check_weather',
296
- args: '{"location":"New York"}',
297
- output: 'Sunny, 75°F',
298
- },
299
- },
300
- ],
301
- },
302
- {
303
- role: 'assistant',
304
- content: [
305
- {
306
- type: ContentTypes.TEXT,
307
- [ContentTypes.TEXT]: 'Finally, I\'ll calculate something.',
308
- tool_call_ids: ['calc_1'],
309
- },
310
- {
311
- type: ContentTypes.TOOL_CALL,
312
- tool_call: {
313
- id: 'calc_1',
314
- name: 'calculator',
315
- args: '{"expression":"1+1"}',
316
- output: '2',
317
- },
318
- },
319
- ],
320
- },
321
- {
322
- role: 'assistant',
323
- content: 'Here\'s your answer based on all that information.',
324
- },
325
- ];
326
- // Allow search and calculator but not check_weather
327
- const allowedTools = new Set(['search', 'calculator']);
328
- const result = formatAgentMessages(payload, undefined, allowedTools);
329
- // With selective filtering: valid tools are kept, invalid tools are converted to string
330
- // 1. HumanMessage
331
- // 2. AIMessage (search tool_call)
332
- // 3. ToolMessage (search result)
333
- // 4. AIMessage (text + invalid weather tool as string, no tool_calls)
334
- // 5. AIMessage (calculator tool_call)
335
- // 6. ToolMessage (calculator result)
336
- // 7. AIMessage (final text)
337
- expect(result.messages).toHaveLength(7);
338
- // Check the types of messages
339
- expect(result.messages[0]).toBeInstanceOf(HumanMessage);
340
- expect(result.messages[1]).toBeInstanceOf(AIMessage); // Search message
341
- expect(result.messages[2]).toBeInstanceOf(ToolMessage); // Search tool response
342
- expect(result.messages[3]).toBeInstanceOf(AIMessage); // Weather message (tool converted to string)
343
- expect(result.messages[4]).toBeInstanceOf(AIMessage); // Calculator message
344
- expect(result.messages[5]).toBeInstanceOf(ToolMessage); // Calculator tool response
345
- expect(result.messages[6]).toBeInstanceOf(AIMessage); // Final message
346
- // Check that search tool was kept
347
- expect(result.messages[1].tool_calls).toHaveLength(1);
348
- expect(result.messages[1].tool_calls?.[0].name).toBe('search');
349
- // Check that weather message has no tool_calls but contains the invalid tool as text
350
- expect(result.messages[3].tool_calls).toHaveLength(0);
351
- const weatherContent = result.messages[3].content;
352
- const weatherContentStr = typeof weatherContent === 'string'
353
- ? weatherContent
354
- : JSON.stringify(weatherContent);
355
- expect(weatherContentStr).toContain('check_weather');
356
- expect(weatherContentStr).toContain('Sunny');
357
- // Check that calculator tool was kept
358
- expect(result.messages[4].tool_calls).toHaveLength(1);
359
- expect(result.messages[4].tool_calls?.[0].name).toBe('calculator');
360
- });
361
- });
362
- //# sourceMappingURL=formatAgentMessages.tools.test.js.map