illuma-agents 1.0.8 → 1.0.10

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 (250) hide show
  1. package/LICENSE +1 -5
  2. package/dist/cjs/common/enum.cjs +1 -2
  3. package/dist/cjs/common/enum.cjs.map +1 -1
  4. package/dist/cjs/events.cjs +11 -0
  5. package/dist/cjs/events.cjs.map +1 -1
  6. package/dist/cjs/graphs/Graph.cjs +2 -1
  7. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  8. package/dist/cjs/instrumentation.cjs +3 -1
  9. package/dist/cjs/instrumentation.cjs.map +1 -1
  10. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  11. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +79 -2
  12. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  13. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -1
  14. package/dist/cjs/llm/bedrock/index.cjs +99 -0
  15. package/dist/cjs/llm/bedrock/index.cjs.map +1 -0
  16. package/dist/cjs/llm/fake.cjs.map +1 -1
  17. package/dist/cjs/llm/openai/index.cjs +102 -0
  18. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  19. package/dist/cjs/llm/openai/utils/index.cjs +87 -1
  20. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  21. package/dist/cjs/llm/openrouter/index.cjs +175 -1
  22. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  23. package/dist/cjs/llm/providers.cjs +13 -16
  24. package/dist/cjs/llm/providers.cjs.map +1 -1
  25. package/dist/cjs/llm/text.cjs.map +1 -1
  26. package/dist/cjs/messages/core.cjs +14 -14
  27. package/dist/cjs/messages/core.cjs.map +1 -1
  28. package/dist/cjs/messages/ids.cjs.map +1 -1
  29. package/dist/cjs/messages/prune.cjs.map +1 -1
  30. package/dist/cjs/run.cjs +18 -1
  31. package/dist/cjs/run.cjs.map +1 -1
  32. package/dist/cjs/splitStream.cjs.map +1 -1
  33. package/dist/cjs/stream.cjs +24 -1
  34. package/dist/cjs/stream.cjs.map +1 -1
  35. package/dist/cjs/tools/ToolNode.cjs +20 -1
  36. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  37. package/dist/cjs/tools/handlers.cjs +29 -25
  38. package/dist/cjs/tools/handlers.cjs.map +1 -1
  39. package/dist/cjs/tools/search/anthropic.cjs.map +1 -1
  40. package/dist/cjs/tools/search/content.cjs.map +1 -1
  41. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  42. package/dist/cjs/tools/search/format.cjs.map +1 -1
  43. package/dist/cjs/tools/search/highlights.cjs.map +1 -1
  44. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  45. package/dist/cjs/tools/search/schema.cjs +27 -25
  46. package/dist/cjs/tools/search/schema.cjs.map +1 -1
  47. package/dist/cjs/tools/search/search.cjs +6 -1
  48. package/dist/cjs/tools/search/search.cjs.map +1 -1
  49. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -1
  50. package/dist/cjs/tools/search/tool.cjs +182 -35
  51. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  52. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  53. package/dist/cjs/utils/graph.cjs.map +1 -1
  54. package/dist/cjs/utils/llm.cjs +0 -1
  55. package/dist/cjs/utils/llm.cjs.map +1 -1
  56. package/dist/cjs/utils/misc.cjs.map +1 -1
  57. package/dist/cjs/utils/run.cjs.map +1 -1
  58. package/dist/cjs/utils/title.cjs +7 -7
  59. package/dist/cjs/utils/title.cjs.map +1 -1
  60. package/dist/esm/common/enum.mjs +1 -2
  61. package/dist/esm/common/enum.mjs.map +1 -1
  62. package/dist/esm/events.mjs +11 -0
  63. package/dist/esm/events.mjs.map +1 -1
  64. package/dist/esm/graphs/Graph.mjs +2 -1
  65. package/dist/esm/graphs/Graph.mjs.map +1 -1
  66. package/dist/esm/instrumentation.mjs +3 -1
  67. package/dist/esm/instrumentation.mjs.map +1 -1
  68. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  69. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +79 -2
  70. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  71. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -1
  72. package/dist/esm/llm/bedrock/index.mjs +97 -0
  73. package/dist/esm/llm/bedrock/index.mjs.map +1 -0
  74. package/dist/esm/llm/fake.mjs.map +1 -1
  75. package/dist/esm/llm/openai/index.mjs +103 -1
  76. package/dist/esm/llm/openai/index.mjs.map +1 -1
  77. package/dist/esm/llm/openai/utils/index.mjs +88 -2
  78. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  79. package/dist/esm/llm/openrouter/index.mjs +175 -1
  80. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  81. package/dist/esm/llm/providers.mjs +2 -5
  82. package/dist/esm/llm/providers.mjs.map +1 -1
  83. package/dist/esm/llm/text.mjs.map +1 -1
  84. package/dist/esm/messages/core.mjs +14 -14
  85. package/dist/esm/messages/core.mjs.map +1 -1
  86. package/dist/esm/messages/ids.mjs.map +1 -1
  87. package/dist/esm/messages/prune.mjs.map +1 -1
  88. package/dist/esm/run.mjs +18 -1
  89. package/dist/esm/run.mjs.map +1 -1
  90. package/dist/esm/splitStream.mjs.map +1 -1
  91. package/dist/esm/stream.mjs +24 -1
  92. package/dist/esm/stream.mjs.map +1 -1
  93. package/dist/esm/tools/ToolNode.mjs +20 -1
  94. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  95. package/dist/esm/tools/handlers.mjs +30 -26
  96. package/dist/esm/tools/handlers.mjs.map +1 -1
  97. package/dist/esm/tools/search/anthropic.mjs.map +1 -1
  98. package/dist/esm/tools/search/content.mjs.map +1 -1
  99. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  100. package/dist/esm/tools/search/format.mjs.map +1 -1
  101. package/dist/esm/tools/search/highlights.mjs.map +1 -1
  102. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  103. package/dist/esm/tools/search/schema.mjs +27 -25
  104. package/dist/esm/tools/search/schema.mjs.map +1 -1
  105. package/dist/esm/tools/search/search.mjs +6 -1
  106. package/dist/esm/tools/search/search.mjs.map +1 -1
  107. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -1
  108. package/dist/esm/tools/search/tool.mjs +182 -35
  109. package/dist/esm/tools/search/tool.mjs.map +1 -1
  110. package/dist/esm/tools/search/utils.mjs.map +1 -1
  111. package/dist/esm/utils/graph.mjs.map +1 -1
  112. package/dist/esm/utils/llm.mjs +0 -1
  113. package/dist/esm/utils/llm.mjs.map +1 -1
  114. package/dist/esm/utils/misc.mjs.map +1 -1
  115. package/dist/esm/utils/run.mjs.map +1 -1
  116. package/dist/esm/utils/title.mjs +7 -7
  117. package/dist/esm/utils/title.mjs.map +1 -1
  118. package/dist/types/common/enum.d.ts +1 -2
  119. package/dist/types/llm/bedrock/index.d.ts +36 -0
  120. package/dist/types/llm/openai/index.d.ts +1 -0
  121. package/dist/types/llm/openai/utils/index.d.ts +10 -1
  122. package/dist/types/llm/openrouter/index.d.ts +4 -1
  123. package/dist/types/tools/search/types.d.ts +2 -0
  124. package/dist/types/types/llm.d.ts +3 -8
  125. package/package.json +16 -12
  126. package/src/common/enum.ts +1 -2
  127. package/src/common/index.ts +1 -1
  128. package/src/events.ts +11 -0
  129. package/src/graphs/Graph.ts +2 -1
  130. package/src/instrumentation.ts +25 -22
  131. package/src/llm/anthropic/llm.spec.ts +1442 -1442
  132. package/src/llm/anthropic/types.ts +140 -140
  133. package/src/llm/anthropic/utils/message_inputs.ts +757 -660
  134. package/src/llm/anthropic/utils/output_parsers.ts +133 -133
  135. package/src/llm/anthropic/utils/tools.ts +29 -29
  136. package/src/llm/bedrock/index.ts +128 -0
  137. package/src/llm/fake.ts +133 -133
  138. package/src/llm/google/llm.spec.ts +3 -1
  139. package/src/llm/google/utils/tools.ts +160 -160
  140. package/src/llm/openai/index.ts +126 -0
  141. package/src/llm/openai/types.ts +24 -24
  142. package/src/llm/openai/utils/index.ts +116 -1
  143. package/src/llm/openai/utils/isReasoningModel.test.ts +90 -90
  144. package/src/llm/openrouter/index.ts +222 -1
  145. package/src/llm/providers.ts +2 -7
  146. package/src/llm/text.ts +94 -94
  147. package/src/messages/core.ts +463 -463
  148. package/src/messages/formatAgentMessages.tools.test.ts +400 -400
  149. package/src/messages/formatMessage.test.ts +693 -693
  150. package/src/messages/ids.ts +26 -26
  151. package/src/messages/prune.ts +567 -567
  152. package/src/messages/shiftIndexTokenCountMap.test.ts +81 -81
  153. package/src/mockStream.ts +98 -98
  154. package/src/prompts/collab.ts +5 -5
  155. package/src/prompts/index.ts +1 -1
  156. package/src/prompts/taskmanager.ts +61 -61
  157. package/src/run.ts +22 -4
  158. package/src/scripts/ant_web_search_edge_case.ts +162 -0
  159. package/src/scripts/ant_web_search_error_edge_case.ts +148 -0
  160. package/src/scripts/args.ts +48 -48
  161. package/src/scripts/caching.ts +123 -123
  162. package/src/scripts/code_exec_files.ts +193 -193
  163. package/src/scripts/empty_input.ts +137 -137
  164. package/src/scripts/memory.ts +97 -97
  165. package/src/scripts/test-tools-before-handoff.ts +1 -5
  166. package/src/scripts/thinking.ts +149 -149
  167. package/src/scripts/tools.ts +1 -4
  168. package/src/specs/anthropic.simple.test.ts +67 -0
  169. package/src/specs/spec.utils.ts +3 -3
  170. package/src/specs/token-distribution-edge-case.test.ts +316 -316
  171. package/src/specs/tool-error.test.ts +193 -193
  172. package/src/splitStream.test.ts +691 -691
  173. package/src/splitStream.ts +234 -234
  174. package/src/stream.test.ts +94 -94
  175. package/src/stream.ts +30 -1
  176. package/src/tools/ToolNode.ts +24 -1
  177. package/src/tools/handlers.ts +32 -28
  178. package/src/tools/search/anthropic.ts +51 -51
  179. package/src/tools/search/content.test.ts +173 -173
  180. package/src/tools/search/content.ts +147 -147
  181. package/src/tools/search/direct-url.test.ts +530 -0
  182. package/src/tools/search/firecrawl.ts +210 -210
  183. package/src/tools/search/format.ts +250 -250
  184. package/src/tools/search/highlights.ts +320 -320
  185. package/src/tools/search/index.ts +2 -2
  186. package/src/tools/search/jina-reranker.test.ts +126 -126
  187. package/src/tools/search/output.md +2775 -2775
  188. package/src/tools/search/rerankers.ts +242 -242
  189. package/src/tools/search/schema.ts +65 -63
  190. package/src/tools/search/search.ts +766 -759
  191. package/src/tools/search/serper-scraper.ts +155 -155
  192. package/src/tools/search/test.html +883 -883
  193. package/src/tools/search/test.md +642 -642
  194. package/src/tools/search/test.ts +159 -159
  195. package/src/tools/search/tool.ts +641 -471
  196. package/src/tools/search/types.ts +689 -687
  197. package/src/tools/search/utils.ts +79 -79
  198. package/src/types/index.ts +6 -6
  199. package/src/types/llm.ts +2 -8
  200. package/src/utils/graph.ts +10 -10
  201. package/src/utils/llm.ts +26 -27
  202. package/src/utils/llmConfig.ts +13 -5
  203. package/src/utils/logging.ts +48 -48
  204. package/src/utils/misc.ts +57 -57
  205. package/src/utils/run.ts +100 -100
  206. package/src/utils/title.ts +165 -165
  207. package/dist/cjs/llm/ollama/index.cjs +0 -70
  208. package/dist/cjs/llm/ollama/index.cjs.map +0 -1
  209. package/dist/cjs/llm/ollama/utils.cjs +0 -158
  210. package/dist/cjs/llm/ollama/utils.cjs.map +0 -1
  211. package/dist/esm/llm/ollama/index.mjs +0 -68
  212. package/dist/esm/llm/ollama/index.mjs.map +0 -1
  213. package/dist/esm/llm/ollama/utils.mjs +0 -155
  214. package/dist/esm/llm/ollama/utils.mjs.map +0 -1
  215. package/dist/types/llm/ollama/index.d.ts +0 -8
  216. package/dist/types/llm/ollama/utils.d.ts +0 -7
  217. package/src/llm/ollama/index.ts +0 -92
  218. package/src/llm/ollama/utils.ts +0 -193
  219. package/src/proto/CollabGraph.ts +0 -269
  220. package/src/proto/TaskManager.ts +0 -243
  221. package/src/proto/collab.ts +0 -200
  222. package/src/proto/collab_design.ts +0 -184
  223. package/src/proto/collab_design_v2.ts +0 -224
  224. package/src/proto/collab_design_v3.ts +0 -255
  225. package/src/proto/collab_design_v4.ts +0 -220
  226. package/src/proto/collab_design_v5.ts +0 -251
  227. package/src/proto/collab_graph.ts +0 -181
  228. package/src/proto/collab_original.ts +0 -123
  229. package/src/proto/example.ts +0 -93
  230. package/src/proto/example_new.ts +0 -68
  231. package/src/proto/example_old.ts +0 -201
  232. package/src/proto/example_test.ts +0 -152
  233. package/src/proto/example_test_anthropic.ts +0 -100
  234. package/src/proto/log_stream.ts +0 -202
  235. package/src/proto/main_collab_community_event.ts +0 -133
  236. package/src/proto/main_collab_design_v2.ts +0 -96
  237. package/src/proto/main_collab_design_v4.ts +0 -100
  238. package/src/proto/main_collab_design_v5.ts +0 -135
  239. package/src/proto/main_collab_global_analysis.ts +0 -122
  240. package/src/proto/main_collab_hackathon_event.ts +0 -153
  241. package/src/proto/main_collab_space_mission.ts +0 -153
  242. package/src/proto/main_philosophy.ts +0 -210
  243. package/src/proto/original_script.ts +0 -126
  244. package/src/proto/standard.ts +0 -100
  245. package/src/proto/stream.ts +0 -56
  246. package/src/proto/tasks.ts +0 -118
  247. package/src/proto/tools/global_analysis_tools.ts +0 -86
  248. package/src/proto/tools/space_mission_tools.ts +0 -60
  249. package/src/proto/vertexai.ts +0 -54
  250. package/src/scripts/image.ts +0 -178
@@ -1,97 +1,97 @@
1
- // src/scripts/cli.ts
2
- import { config } from 'dotenv';
3
- config();
4
-
5
- import z from 'zod';
6
- import { tool } from '@langchain/core/tools';
7
- import { HumanMessage, BaseMessage } from '@langchain/core/messages';
8
- import type * as t from '@/types';
9
- import { getArgs } from '@/scripts/args';
10
- import { Providers } from '@/common';
11
- import { Run } from '@/run';
12
-
13
- const conversationHistory: BaseMessage[] = [];
14
-
15
- const memoryKv: Record<string, string> = {};
16
-
17
- const setMemory = tool(
18
- async ({ key, value }) => {
19
- if (!/^[a-z_]+$/.test(key)) {
20
- throw new Error('Key must only contain lowercase letters and underscores');
21
- }
22
-
23
- memoryKv[key] = value;
24
-
25
- return { ok: true };
26
- },
27
- {
28
- name: 'set_memory',
29
- description: 'Saves important data about the user into memory.',
30
- schema: z.object({
31
- key: z.string().describe('The key of the memory value. Always use lowercase and underscores, no other characters.'),
32
- value: z.string().describe('Value can be anything represented as a string')
33
- }),
34
- }
35
- );
36
-
37
- async function testStandardStreaming(): Promise<void> {
38
- const { userName, provider } = await getArgs();
39
-
40
- const run = await Run.create<t.IState>({
41
- runId: 'memory-run',
42
- graphConfig: {
43
- type: 'standard',
44
- llmConfig: {
45
- provider: Providers.OPENAI,
46
- model: 'gpt-4o-mini',
47
- temperature: 0.5,
48
- streaming: false,
49
- },
50
- tools: [setMemory],
51
- instructions: 'You can use the `set_memory` tool to save important data about the user into memory. If there is nothing to note about the user specifically, respond with `nothing`.',
52
- toolEnd: true,
53
- },
54
- returnContent: true,
55
- });
56
-
57
- const config = {
58
- configurable: {
59
- provider,
60
- thread_id: 'conversation-num-1',
61
- },
62
- streamMode: 'values',
63
- version: 'v2' as const,
64
- };
65
-
66
- console.log('Test 1: Simple message test');
67
-
68
- const userMessage = `hi`;
69
-
70
- conversationHistory.push(new HumanMessage(userMessage));
71
-
72
- const inputs = {
73
- messages: conversationHistory,
74
- };
75
- await run.processStream(inputs, config);
76
- const finalMessages = run.getRunMessages();
77
- if (finalMessages) {
78
- conversationHistory.push(...finalMessages);
79
- console.dir(conversationHistory, { depth: null });
80
- }
81
-
82
- console.log('\n\n====================\n\n');
83
- console.dir(memoryKv, { depth: null });
84
- }
85
-
86
- process.on('unhandledRejection', (reason, promise) => {
87
- console.error('Unhandled Rejection at:', promise, 'reason:', reason);
88
- console.log('Conversation history:');
89
- process.exit(1);
90
- });
91
-
92
- testStandardStreaming().catch((err) => {
93
- console.error(err);
94
- console.log('Conversation history:');
95
- console.dir(conversationHistory, { depth: null });
96
- process.exit(1);
97
- });
1
+ // src/scripts/cli.ts
2
+ import { config } from 'dotenv';
3
+ config();
4
+
5
+ import z from 'zod';
6
+ import { tool } from '@langchain/core/tools';
7
+ import { HumanMessage, BaseMessage } from '@langchain/core/messages';
8
+ import type * as t from '@/types';
9
+ import { getArgs } from '@/scripts/args';
10
+ import { Providers } from '@/common';
11
+ import { Run } from '@/run';
12
+
13
+ const conversationHistory: BaseMessage[] = [];
14
+
15
+ const memoryKv: Record<string, string> = {};
16
+
17
+ const setMemory = tool(
18
+ async ({ key, value }) => {
19
+ if (!/^[a-z_]+$/.test(key)) {
20
+ throw new Error('Key must only contain lowercase letters and underscores');
21
+ }
22
+
23
+ memoryKv[key] = value;
24
+
25
+ return { ok: true };
26
+ },
27
+ {
28
+ name: 'set_memory',
29
+ description: 'Saves important data about the user into memory.',
30
+ schema: z.object({
31
+ key: z.string().describe('The key of the memory value. Always use lowercase and underscores, no other characters.'),
32
+ value: z.string().describe('Value can be anything represented as a string')
33
+ }),
34
+ }
35
+ );
36
+
37
+ async function testStandardStreaming(): Promise<void> {
38
+ const { userName, provider } = await getArgs();
39
+
40
+ const run = await Run.create<t.IState>({
41
+ runId: 'memory-run',
42
+ graphConfig: {
43
+ type: 'standard',
44
+ llmConfig: {
45
+ provider: Providers.OPENAI,
46
+ model: 'gpt-4o-mini',
47
+ temperature: 0.5,
48
+ streaming: false,
49
+ },
50
+ tools: [setMemory],
51
+ instructions: 'You can use the `set_memory` tool to save important data about the user into memory. If there is nothing to note about the user specifically, respond with `nothing`.',
52
+ toolEnd: true,
53
+ },
54
+ returnContent: true,
55
+ });
56
+
57
+ const config = {
58
+ configurable: {
59
+ provider,
60
+ thread_id: 'conversation-num-1',
61
+ },
62
+ streamMode: 'values',
63
+ version: 'v2' as const,
64
+ };
65
+
66
+ console.log('Test 1: Simple message test');
67
+
68
+ const userMessage = `hi`;
69
+
70
+ conversationHistory.push(new HumanMessage(userMessage));
71
+
72
+ const inputs = {
73
+ messages: conversationHistory,
74
+ };
75
+ await run.processStream(inputs, config);
76
+ const finalMessages = run.getRunMessages();
77
+ if (finalMessages) {
78
+ conversationHistory.push(...finalMessages);
79
+ console.dir(conversationHistory, { depth: null });
80
+ }
81
+
82
+ console.log('\n\n====================\n\n');
83
+ console.dir(memoryKv, { depth: null });
84
+ }
85
+
86
+ process.on('unhandledRejection', (reason, promise) => {
87
+ console.error('Unhandled Rejection at:', promise, 'reason:', reason);
88
+ console.log('Conversation history:');
89
+ process.exit(1);
90
+ });
91
+
92
+ testStandardStreaming().catch((err) => {
93
+ console.error(err);
94
+ console.log('Conversation history:');
95
+ console.dir(conversationHistory, { depth: null });
96
+ process.exit(1);
97
+ });
@@ -5,7 +5,7 @@ import { HumanMessage, BaseMessage } from '@langchain/core/messages';
5
5
  import { Run } from '@/run';
6
6
  import { Providers, GraphEvents } from '@/common';
7
7
  import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
8
- import { ToolEndHandler, ModelEndHandler } from '@/events';
8
+ import { ModelEndHandler } from '@/events';
9
9
  import type * as t from '@/types';
10
10
 
11
11
  const conversationHistory: BaseMessage[] = [];
@@ -28,10 +28,6 @@ async function testToolsBeforeHandoff() {
28
28
 
29
29
  // Create custom handlers
30
30
  const customHandlers = {
31
- [GraphEvents.TOOL_END]: new ToolEndHandler(undefined, (name?: string) => {
32
- console.log(`\n✅ Tool completed: ${name}`);
33
- return true;
34
- }),
35
31
  [GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
36
32
  [GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
37
33
  [GraphEvents.ON_RUN_STEP]: {
@@ -1,150 +1,150 @@
1
- // src/scripts/test-thinking.ts
2
- import { config } from 'dotenv';
3
- config();
4
- import { HumanMessage, SystemMessage, BaseMessage } from '@langchain/core/messages';
5
- import type { UsageMetadata } from '@langchain/core/messages';
6
- import * as t from '@/types';
7
- import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
8
- import { createCodeExecutionTool } from '@/tools/CodeExecutor';
9
- import { ToolEndHandler, ModelEndHandler } from '@/events';
10
- import { GraphEvents, Providers } from '@/common';
11
- import { getLLMConfig } from '@/utils/llmConfig';
12
- import { getArgs } from '@/scripts/args';
13
- import { Run } from '@/run';
14
-
15
- const conversationHistory: BaseMessage[] = [];
16
- let _contentParts: t.MessageContentComplex[] = [];
17
- const collectedUsage: UsageMetadata[] = [];
18
-
19
- async function testThinking(): Promise<void> {
20
- const { userName } = await getArgs();
21
- const instructions = `You are a helpful AI assistant for ${userName}. When answering questions, be thorough in your reasoning.`;
22
- const { contentParts, aggregateContent } = createContentAggregator();
23
- _contentParts = contentParts as t.MessageContentComplex[];
24
-
25
- // Set up event handlers
26
- const customHandlers = {
27
- [GraphEvents.TOOL_END]: new ToolEndHandler(),
28
- [GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(collectedUsage),
29
- [GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
30
- [GraphEvents.ON_RUN_STEP_COMPLETED]: {
31
- handle: (event: GraphEvents.ON_RUN_STEP_COMPLETED, data: t.StreamEventData): void => {
32
- console.log('====== ON_RUN_STEP_COMPLETED ======');
33
- aggregateContent({ event, data: data as unknown as { result: t.ToolEndEvent } });
34
- }
35
- },
36
- [GraphEvents.ON_RUN_STEP]: {
37
- handle: (event: GraphEvents.ON_RUN_STEP, data: t.RunStep) => {
38
- aggregateContent({ event, data });
39
- },
40
- },
41
- [GraphEvents.ON_RUN_STEP_DELTA]: {
42
- handle: (event: GraphEvents.ON_RUN_STEP_DELTA, data: t.RunStepDeltaEvent) => {
43
- aggregateContent({ event, data });
44
- },
45
- },
46
- [GraphEvents.ON_MESSAGE_DELTA]: {
47
- handle: (event: GraphEvents.ON_MESSAGE_DELTA, data: t.MessageDeltaEvent) => {
48
- aggregateContent({ event, data });
49
- },
50
- },
51
- [GraphEvents.ON_REASONING_DELTA]: {
52
- handle: (event: GraphEvents.ON_REASONING_DELTA, data: t.ReasoningDeltaEvent) => {
53
- aggregateContent({ event, data });
54
- },
55
- },
56
- };
57
-
58
- const baseLlmConfig: t.LLMConfig = getLLMConfig(Providers.ANTHROPIC);
59
-
60
- // Enable thinking with token budget
61
- const llmConfig = {
62
- ...baseLlmConfig,
63
- model: 'claude-3-7-sonnet-latest',
64
- thinking: { type: "enabled", budget_tokens: 2000 }
65
- };
66
-
67
- const run = await Run.create<t.IState>({
68
- runId: 'test-thinking-id',
69
- graphConfig: {
70
- instructions,
71
- type: 'standard',
72
- tools: [createCodeExecutionTool()],
73
- llmConfig,
74
- },
75
- returnContent: true,
76
- customHandlers: customHandlers as t.RunConfig['customHandlers'],
77
- });
78
-
79
- const config = {
80
- configurable: {
81
- thread_id: 'thinking-test-thread',
82
- },
83
- streamMode: 'values',
84
- version: 'v2' as const,
85
- };
86
-
87
- // Test 1: Regular thinking mode
88
- console.log('\n\nTest 1: Regular thinking mode');
89
- // const userMessage1 = `What would be the environmental and economic impacts if all cars globally were replaced by electric vehicles overnight?`;
90
- const userMessage1 = `Please print 'hello world' in python`;
91
- conversationHistory.push(new HumanMessage(userMessage1));
92
-
93
- console.log('Running first query with thinking enabled...');
94
- const firstInputs = { messages: [...conversationHistory] };
95
- await run.processStream(firstInputs, config);
96
-
97
- // Extract and display thinking blocks
98
- const finalMessages = run.getRunMessages();
99
-
100
- // Test 2: Try multi-turn conversation
101
- console.log('\n\nTest 2: Multi-turn conversation with thinking enabled');
102
- const userMessage2 = `Given your previous analysis, what would be the most significant technical challenges in making this transition?`;
103
- conversationHistory.push(new HumanMessage(userMessage2));
104
-
105
- console.log('Running second query with thinking enabled...');
106
- const secondInputs = { messages: [...conversationHistory] };
107
- await run.processStream(secondInputs, config);
108
-
109
- // Display thinking blocks for second response
110
- const finalMessages2 = run.getRunMessages();
111
-
112
- // Test 3: Redacted thinking mode
113
- console.log('\n\nTest 3: Redacted thinking mode');
114
- const magicString = "ANTHROPIC_MAGIC_STRING_TRIGGER_REDACTED_THINKING_46C9A13E193C177646C7398A98432ECCCE4C1253D5E2D82641AC0E52CC2876CB";
115
- const userMessage3 = `${magicString}\n\nExplain how quantum computing works in simple terms.`;
116
-
117
- // Reset conversation for clean test
118
- conversationHistory.length = 0;
119
- conversationHistory.push(new HumanMessage(userMessage3));
120
-
121
- console.log('Running query with redacted thinking...');
122
- const thirdInputs = { messages: [...conversationHistory] };
123
- await run.processStream(thirdInputs, config);
124
-
125
- // Display redacted thinking blocks
126
- const finalMessages3 = run.getRunMessages();
127
- console.log('\n\nThinking feature test completed!');
128
- }
129
-
130
- process.on('unhandledRejection', (reason, promise) => {
131
- console.error('Unhandled Rejection at:', promise, 'reason:', reason);
132
- console.log('Conversation history:');
133
- console.dir(conversationHistory, { depth: null });
134
- console.log('Content parts:');
135
- console.dir(_contentParts, { depth: null });
136
- process.exit(1);
137
- });
138
-
139
- process.on('uncaughtException', (err) => {
140
- console.error('Uncaught Exception:', err);
141
- });
142
-
143
- testThinking().catch((err) => {
144
- console.error(err);
145
- console.log('Conversation history:');
146
- console.dir(conversationHistory, { depth: null });
147
- console.log('Content parts:');
148
- console.dir(_contentParts, { depth: null });
149
- process.exit(1);
1
+ // src/scripts/test-thinking.ts
2
+ import { config } from 'dotenv';
3
+ config();
4
+ import { HumanMessage, SystemMessage, BaseMessage } from '@langchain/core/messages';
5
+ import type { UsageMetadata } from '@langchain/core/messages';
6
+ import * as t from '@/types';
7
+ import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
8
+ import { createCodeExecutionTool } from '@/tools/CodeExecutor';
9
+ import { ToolEndHandler, ModelEndHandler } from '@/events';
10
+ import { GraphEvents, Providers } from '@/common';
11
+ import { getLLMConfig } from '@/utils/llmConfig';
12
+ import { getArgs } from '@/scripts/args';
13
+ import { Run } from '@/run';
14
+
15
+ const conversationHistory: BaseMessage[] = [];
16
+ let _contentParts: t.MessageContentComplex[] = [];
17
+ const collectedUsage: UsageMetadata[] = [];
18
+
19
+ async function testThinking(): Promise<void> {
20
+ const { userName } = await getArgs();
21
+ const instructions = `You are a helpful AI assistant for ${userName}. When answering questions, be thorough in your reasoning.`;
22
+ const { contentParts, aggregateContent } = createContentAggregator();
23
+ _contentParts = contentParts as t.MessageContentComplex[];
24
+
25
+ // Set up event handlers
26
+ const customHandlers = {
27
+ [GraphEvents.TOOL_END]: new ToolEndHandler(),
28
+ [GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(collectedUsage),
29
+ [GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
30
+ [GraphEvents.ON_RUN_STEP_COMPLETED]: {
31
+ handle: (event: GraphEvents.ON_RUN_STEP_COMPLETED, data: t.StreamEventData): void => {
32
+ console.log('====== ON_RUN_STEP_COMPLETED ======');
33
+ aggregateContent({ event, data: data as unknown as { result: t.ToolEndEvent } });
34
+ }
35
+ },
36
+ [GraphEvents.ON_RUN_STEP]: {
37
+ handle: (event: GraphEvents.ON_RUN_STEP, data: t.RunStep) => {
38
+ aggregateContent({ event, data });
39
+ },
40
+ },
41
+ [GraphEvents.ON_RUN_STEP_DELTA]: {
42
+ handle: (event: GraphEvents.ON_RUN_STEP_DELTA, data: t.RunStepDeltaEvent) => {
43
+ aggregateContent({ event, data });
44
+ },
45
+ },
46
+ [GraphEvents.ON_MESSAGE_DELTA]: {
47
+ handle: (event: GraphEvents.ON_MESSAGE_DELTA, data: t.MessageDeltaEvent) => {
48
+ aggregateContent({ event, data });
49
+ },
50
+ },
51
+ [GraphEvents.ON_REASONING_DELTA]: {
52
+ handle: (event: GraphEvents.ON_REASONING_DELTA, data: t.ReasoningDeltaEvent) => {
53
+ aggregateContent({ event, data });
54
+ },
55
+ },
56
+ };
57
+
58
+ const baseLlmConfig: t.LLMConfig = getLLMConfig(Providers.ANTHROPIC);
59
+
60
+ // Enable thinking with token budget
61
+ const llmConfig = {
62
+ ...baseLlmConfig,
63
+ model: 'claude-3-7-sonnet-latest',
64
+ thinking: { type: "enabled", budget_tokens: 2000 }
65
+ };
66
+
67
+ const run = await Run.create<t.IState>({
68
+ runId: 'test-thinking-id',
69
+ graphConfig: {
70
+ instructions,
71
+ type: 'standard',
72
+ tools: [createCodeExecutionTool()],
73
+ llmConfig,
74
+ },
75
+ returnContent: true,
76
+ customHandlers: customHandlers as t.RunConfig['customHandlers'],
77
+ });
78
+
79
+ const config = {
80
+ configurable: {
81
+ thread_id: 'thinking-test-thread',
82
+ },
83
+ streamMode: 'values',
84
+ version: 'v2' as const,
85
+ };
86
+
87
+ // Test 1: Regular thinking mode
88
+ console.log('\n\nTest 1: Regular thinking mode');
89
+ // const userMessage1 = `What would be the environmental and economic impacts if all cars globally were replaced by electric vehicles overnight?`;
90
+ const userMessage1 = `Please print 'hello world' in python`;
91
+ conversationHistory.push(new HumanMessage(userMessage1));
92
+
93
+ console.log('Running first query with thinking enabled...');
94
+ const firstInputs = { messages: [...conversationHistory] };
95
+ await run.processStream(firstInputs, config);
96
+
97
+ // Extract and display thinking blocks
98
+ const finalMessages = run.getRunMessages();
99
+
100
+ // Test 2: Try multi-turn conversation
101
+ console.log('\n\nTest 2: Multi-turn conversation with thinking enabled');
102
+ const userMessage2 = `Given your previous analysis, what would be the most significant technical challenges in making this transition?`;
103
+ conversationHistory.push(new HumanMessage(userMessage2));
104
+
105
+ console.log('Running second query with thinking enabled...');
106
+ const secondInputs = { messages: [...conversationHistory] };
107
+ await run.processStream(secondInputs, config);
108
+
109
+ // Display thinking blocks for second response
110
+ const finalMessages2 = run.getRunMessages();
111
+
112
+ // Test 3: Redacted thinking mode
113
+ console.log('\n\nTest 3: Redacted thinking mode');
114
+ const magicString = "ANTHROPIC_MAGIC_STRING_TRIGGER_REDACTED_THINKING_46C9A13E193C177646C7398A98432ECCCE4C1253D5E2D82641AC0E52CC2876CB";
115
+ const userMessage3 = `${magicString}\n\nExplain how quantum computing works in simple terms.`;
116
+
117
+ // Reset conversation for clean test
118
+ conversationHistory.length = 0;
119
+ conversationHistory.push(new HumanMessage(userMessage3));
120
+
121
+ console.log('Running query with redacted thinking...');
122
+ const thirdInputs = { messages: [...conversationHistory] };
123
+ await run.processStream(thirdInputs, config);
124
+
125
+ // Display redacted thinking blocks
126
+ const finalMessages3 = run.getRunMessages();
127
+ console.log('\n\nThinking feature test completed!');
128
+ }
129
+
130
+ process.on('unhandledRejection', (reason, promise) => {
131
+ console.error('Unhandled Rejection at:', promise, 'reason:', reason);
132
+ console.log('Conversation history:');
133
+ console.dir(conversationHistory, { depth: null });
134
+ console.log('Content parts:');
135
+ console.dir(_contentParts, { depth: null });
136
+ process.exit(1);
137
+ });
138
+
139
+ process.on('uncaughtException', (err) => {
140
+ console.error('Uncaught Exception:', err);
141
+ });
142
+
143
+ testThinking().catch((err) => {
144
+ console.error(err);
145
+ console.log('Conversation history:');
146
+ console.dir(conversationHistory, { depth: null });
147
+ console.log('Content parts:');
148
+ console.dir(_contentParts, { depth: null });
149
+ process.exit(1);
150
150
  });
@@ -6,7 +6,7 @@ config();
6
6
  import { HumanMessage, BaseMessage } from '@langchain/core/messages';
7
7
  import type * as t from '@/types';
8
8
  import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
9
- import { ToolEndHandler, ModelEndHandler } from '@/events';
9
+ import { ModelEndHandler } from '@/events';
10
10
  import { GraphEvents, Providers } from '@/common';
11
11
  import { getLLMConfig } from '@/utils/llmConfig';
12
12
  import { Calculator } from '@/tools/Calculator';
@@ -18,9 +18,6 @@ async function testStandardStreaming(): Promise<void> {
18
18
  const { userName, location, provider, currentDate } = await getArgs();
19
19
  const { contentParts, aggregateContent } = createContentAggregator();
20
20
  const customHandlers = {
21
- [GraphEvents.TOOL_END]: new ToolEndHandler(undefined, (name?: string) => {
22
- return true;
23
- }),
24
21
  [GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
25
22
  [GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
26
23
  [GraphEvents.ON_RUN_STEP_COMPLETED]: {
@@ -306,6 +306,73 @@ describe(`${capitalizeFirstLetter(provider)} Streaming Tests`, () => {
306
306
  expect(onRunStepSpy.mock.calls.length).toBeGreaterThan(0);
307
307
  });
308
308
 
309
+ test(`${capitalizeFirstLetter(provider)}: should handle parallel tool usage (web search + calculator)`, async () => {
310
+ const llmConfig = getLLMConfig(provider);
311
+ const customHandlers = setupCustomHandlers();
312
+
313
+ run = await Run.create<t.IState>({
314
+ runId: 'test-parallel-tools',
315
+ graphConfig: {
316
+ type: 'standard',
317
+ llmConfig,
318
+ tools: [
319
+ {
320
+ type: 'web_search_20250305',
321
+ name: 'web_search',
322
+ max_uses: 5,
323
+ },
324
+ new Calculator(),
325
+ ],
326
+ instructions: 'You are a helpful AI assistant.',
327
+ },
328
+ returnContent: true,
329
+ customHandlers,
330
+ });
331
+
332
+ // Use the same query as the edge case script to test actual parallel tool usage
333
+ const userMessage =
334
+ 'Can you search the web for the current population of Tokyo, and also calculate what 15% of that population would be? Do both at the same time.';
335
+ conversationHistory = [];
336
+ conversationHistory.push(new HumanMessage(userMessage));
337
+
338
+ const inputs = {
339
+ messages: conversationHistory,
340
+ };
341
+
342
+ // This should complete without errors despite using both server tools and regular tools in parallel
343
+ const finalContentParts = await run.processStream(inputs, config);
344
+ expect(finalContentParts).toBeDefined();
345
+
346
+ const finalMessages = run.getRunMessages();
347
+ expect(finalMessages).toBeDefined();
348
+ expect(finalMessages?.length).toBeGreaterThan(0);
349
+
350
+ const hasWebSearch = contentParts.some(
351
+ (part) =>
352
+ !!(
353
+ part.type === 'tool_call' &&
354
+ part.tool_call?.name === 'web_search' &&
355
+ part.tool_call?.id?.startsWith('srvtoolu_') === true
356
+ )
357
+ );
358
+ const hasCalculator = contentParts.some(
359
+ (part) =>
360
+ !!(
361
+ part.type === 'tool_call' &&
362
+ part.tool_call?.name === 'calculator' &&
363
+ part.tool_call?.id?.startsWith('toolu_') === true
364
+ )
365
+ );
366
+
367
+ // Both tools should have been used for this query
368
+ expect(hasWebSearch).toBe(true);
369
+ expect(hasCalculator).toBe(true);
370
+
371
+ console.log(
372
+ `${capitalizeFirstLetter(provider)} parallel tools test: web_search (server tool) + calculator (regular tool) both used successfully`
373
+ );
374
+ });
375
+
309
376
  test('should handle errors appropriately', async () => {
310
377
  // Test error scenarios
311
378
  await expect(async () => {
@@ -1,3 +1,3 @@
1
- export function capitalizeFirstLetter(string: string): string {
2
- return string.charAt(0).toUpperCase() + string.slice(1);
3
- }
1
+ export function capitalizeFirstLetter(string: string): string {
2
+ return string.charAt(0).toUpperCase() + string.slice(1);
3
+ }