illuma-agents 1.0.8 → 1.0.9

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 (217) 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/instrumentation.cjs.map +1 -1
  5. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  6. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +79 -2
  7. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  8. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -1
  9. package/dist/cjs/llm/bedrock/index.cjs +99 -0
  10. package/dist/cjs/llm/bedrock/index.cjs.map +1 -0
  11. package/dist/cjs/llm/fake.cjs.map +1 -1
  12. package/dist/cjs/llm/providers.cjs +13 -16
  13. package/dist/cjs/llm/providers.cjs.map +1 -1
  14. package/dist/cjs/llm/text.cjs.map +1 -1
  15. package/dist/cjs/messages/core.cjs +14 -14
  16. package/dist/cjs/messages/core.cjs.map +1 -1
  17. package/dist/cjs/messages/ids.cjs.map +1 -1
  18. package/dist/cjs/messages/prune.cjs.map +1 -1
  19. package/dist/cjs/run.cjs +10 -1
  20. package/dist/cjs/run.cjs.map +1 -1
  21. package/dist/cjs/splitStream.cjs.map +1 -1
  22. package/dist/cjs/stream.cjs +4 -1
  23. package/dist/cjs/stream.cjs.map +1 -1
  24. package/dist/cjs/tools/ToolNode.cjs +10 -1
  25. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  26. package/dist/cjs/tools/handlers.cjs +29 -25
  27. package/dist/cjs/tools/handlers.cjs.map +1 -1
  28. package/dist/cjs/tools/search/anthropic.cjs.map +1 -1
  29. package/dist/cjs/tools/search/content.cjs.map +1 -1
  30. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  31. package/dist/cjs/tools/search/format.cjs.map +1 -1
  32. package/dist/cjs/tools/search/highlights.cjs.map +1 -1
  33. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  34. package/dist/cjs/tools/search/schema.cjs +25 -25
  35. package/dist/cjs/tools/search/schema.cjs.map +1 -1
  36. package/dist/cjs/tools/search/search.cjs +6 -1
  37. package/dist/cjs/tools/search/search.cjs.map +1 -1
  38. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -1
  39. package/dist/cjs/tools/search/tool.cjs +162 -35
  40. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  41. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  42. package/dist/cjs/utils/graph.cjs.map +1 -1
  43. package/dist/cjs/utils/llm.cjs +0 -1
  44. package/dist/cjs/utils/llm.cjs.map +1 -1
  45. package/dist/cjs/utils/misc.cjs.map +1 -1
  46. package/dist/cjs/utils/run.cjs.map +1 -1
  47. package/dist/cjs/utils/title.cjs +7 -7
  48. package/dist/cjs/utils/title.cjs.map +1 -1
  49. package/dist/esm/common/enum.mjs +1 -2
  50. package/dist/esm/common/enum.mjs.map +1 -1
  51. package/dist/esm/instrumentation.mjs.map +1 -1
  52. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  53. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +79 -2
  54. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  55. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -1
  56. package/dist/esm/llm/bedrock/index.mjs +97 -0
  57. package/dist/esm/llm/bedrock/index.mjs.map +1 -0
  58. package/dist/esm/llm/fake.mjs.map +1 -1
  59. package/dist/esm/llm/providers.mjs +2 -5
  60. package/dist/esm/llm/providers.mjs.map +1 -1
  61. package/dist/esm/llm/text.mjs.map +1 -1
  62. package/dist/esm/messages/core.mjs +14 -14
  63. package/dist/esm/messages/core.mjs.map +1 -1
  64. package/dist/esm/messages/ids.mjs.map +1 -1
  65. package/dist/esm/messages/prune.mjs.map +1 -1
  66. package/dist/esm/run.mjs +10 -1
  67. package/dist/esm/run.mjs.map +1 -1
  68. package/dist/esm/splitStream.mjs.map +1 -1
  69. package/dist/esm/stream.mjs +4 -1
  70. package/dist/esm/stream.mjs.map +1 -1
  71. package/dist/esm/tools/ToolNode.mjs +10 -1
  72. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  73. package/dist/esm/tools/handlers.mjs +30 -26
  74. package/dist/esm/tools/handlers.mjs.map +1 -1
  75. package/dist/esm/tools/search/anthropic.mjs.map +1 -1
  76. package/dist/esm/tools/search/content.mjs.map +1 -1
  77. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  78. package/dist/esm/tools/search/format.mjs.map +1 -1
  79. package/dist/esm/tools/search/highlights.mjs.map +1 -1
  80. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  81. package/dist/esm/tools/search/schema.mjs +25 -25
  82. package/dist/esm/tools/search/schema.mjs.map +1 -1
  83. package/dist/esm/tools/search/search.mjs +6 -1
  84. package/dist/esm/tools/search/search.mjs.map +1 -1
  85. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -1
  86. package/dist/esm/tools/search/tool.mjs +162 -35
  87. package/dist/esm/tools/search/tool.mjs.map +1 -1
  88. package/dist/esm/tools/search/utils.mjs.map +1 -1
  89. package/dist/esm/utils/graph.mjs.map +1 -1
  90. package/dist/esm/utils/llm.mjs +0 -1
  91. package/dist/esm/utils/llm.mjs.map +1 -1
  92. package/dist/esm/utils/misc.mjs.map +1 -1
  93. package/dist/esm/utils/run.mjs.map +1 -1
  94. package/dist/esm/utils/title.mjs +7 -7
  95. package/dist/esm/utils/title.mjs.map +1 -1
  96. package/dist/types/common/enum.d.ts +1 -2
  97. package/dist/types/llm/bedrock/index.d.ts +36 -0
  98. package/dist/types/tools/search/types.d.ts +2 -0
  99. package/dist/types/types/llm.d.ts +3 -8
  100. package/package.json +15 -11
  101. package/src/common/enum.ts +1 -2
  102. package/src/common/index.ts +1 -1
  103. package/src/instrumentation.ts +22 -22
  104. package/src/llm/anthropic/llm.spec.ts +1442 -1442
  105. package/src/llm/anthropic/types.ts +140 -140
  106. package/src/llm/anthropic/utils/message_inputs.ts +757 -660
  107. package/src/llm/anthropic/utils/output_parsers.ts +133 -133
  108. package/src/llm/anthropic/utils/tools.ts +29 -29
  109. package/src/llm/bedrock/index.ts +128 -0
  110. package/src/llm/fake.ts +133 -133
  111. package/src/llm/google/utils/tools.ts +160 -160
  112. package/src/llm/openai/types.ts +24 -24
  113. package/src/llm/openai/utils/isReasoningModel.test.ts +90 -90
  114. package/src/llm/providers.ts +2 -7
  115. package/src/llm/text.ts +94 -94
  116. package/src/messages/core.ts +463 -463
  117. package/src/messages/formatAgentMessages.tools.test.ts +400 -400
  118. package/src/messages/formatMessage.test.ts +693 -693
  119. package/src/messages/ids.ts +26 -26
  120. package/src/messages/prune.ts +567 -567
  121. package/src/messages/shiftIndexTokenCountMap.test.ts +81 -81
  122. package/src/mockStream.ts +98 -98
  123. package/src/prompts/collab.ts +5 -5
  124. package/src/prompts/index.ts +1 -1
  125. package/src/prompts/taskmanager.ts +61 -61
  126. package/src/run.ts +13 -4
  127. package/src/scripts/ant_web_search_edge_case.ts +162 -0
  128. package/src/scripts/ant_web_search_error_edge_case.ts +148 -0
  129. package/src/scripts/args.ts +48 -48
  130. package/src/scripts/caching.ts +123 -123
  131. package/src/scripts/code_exec_files.ts +193 -193
  132. package/src/scripts/empty_input.ts +137 -137
  133. package/src/scripts/image.ts +178 -178
  134. package/src/scripts/memory.ts +97 -97
  135. package/src/scripts/thinking.ts +149 -149
  136. package/src/specs/anthropic.simple.test.ts +67 -0
  137. package/src/specs/spec.utils.ts +3 -3
  138. package/src/specs/token-distribution-edge-case.test.ts +316 -316
  139. package/src/specs/tool-error.test.ts +193 -193
  140. package/src/splitStream.test.ts +691 -691
  141. package/src/splitStream.ts +234 -234
  142. package/src/stream.test.ts +94 -94
  143. package/src/stream.ts +4 -1
  144. package/src/tools/ToolNode.ts +12 -1
  145. package/src/tools/handlers.ts +32 -28
  146. package/src/tools/search/anthropic.ts +51 -51
  147. package/src/tools/search/content.test.ts +173 -173
  148. package/src/tools/search/content.ts +147 -147
  149. package/src/tools/search/direct-url.test.ts +530 -0
  150. package/src/tools/search/firecrawl.ts +210 -210
  151. package/src/tools/search/format.ts +250 -250
  152. package/src/tools/search/highlights.ts +320 -320
  153. package/src/tools/search/index.ts +2 -2
  154. package/src/tools/search/jina-reranker.test.ts +126 -126
  155. package/src/tools/search/output.md +2775 -2775
  156. package/src/tools/search/rerankers.ts +242 -242
  157. package/src/tools/search/schema.ts +63 -63
  158. package/src/tools/search/search.ts +766 -759
  159. package/src/tools/search/serper-scraper.ts +155 -155
  160. package/src/tools/search/test.html +883 -883
  161. package/src/tools/search/test.md +642 -642
  162. package/src/tools/search/test.ts +159 -159
  163. package/src/tools/search/tool.ts +619 -471
  164. package/src/tools/search/types.ts +689 -687
  165. package/src/tools/search/utils.ts +79 -79
  166. package/src/types/index.ts +6 -6
  167. package/src/types/llm.ts +2 -8
  168. package/src/utils/graph.ts +10 -10
  169. package/src/utils/llm.ts +26 -27
  170. package/src/utils/llmConfig.ts +5 -3
  171. package/src/utils/logging.ts +48 -48
  172. package/src/utils/misc.ts +57 -57
  173. package/src/utils/run.ts +100 -100
  174. package/src/utils/title.ts +165 -165
  175. package/dist/cjs/llm/ollama/index.cjs +0 -70
  176. package/dist/cjs/llm/ollama/index.cjs.map +0 -1
  177. package/dist/cjs/llm/ollama/utils.cjs +0 -158
  178. package/dist/cjs/llm/ollama/utils.cjs.map +0 -1
  179. package/dist/esm/llm/ollama/index.mjs +0 -68
  180. package/dist/esm/llm/ollama/index.mjs.map +0 -1
  181. package/dist/esm/llm/ollama/utils.mjs +0 -155
  182. package/dist/esm/llm/ollama/utils.mjs.map +0 -1
  183. package/dist/types/llm/ollama/index.d.ts +0 -8
  184. package/dist/types/llm/ollama/utils.d.ts +0 -7
  185. package/src/llm/ollama/index.ts +0 -92
  186. package/src/llm/ollama/utils.ts +0 -193
  187. package/src/proto/CollabGraph.ts +0 -269
  188. package/src/proto/TaskManager.ts +0 -243
  189. package/src/proto/collab.ts +0 -200
  190. package/src/proto/collab_design.ts +0 -184
  191. package/src/proto/collab_design_v2.ts +0 -224
  192. package/src/proto/collab_design_v3.ts +0 -255
  193. package/src/proto/collab_design_v4.ts +0 -220
  194. package/src/proto/collab_design_v5.ts +0 -251
  195. package/src/proto/collab_graph.ts +0 -181
  196. package/src/proto/collab_original.ts +0 -123
  197. package/src/proto/example.ts +0 -93
  198. package/src/proto/example_new.ts +0 -68
  199. package/src/proto/example_old.ts +0 -201
  200. package/src/proto/example_test.ts +0 -152
  201. package/src/proto/example_test_anthropic.ts +0 -100
  202. package/src/proto/log_stream.ts +0 -202
  203. package/src/proto/main_collab_community_event.ts +0 -133
  204. package/src/proto/main_collab_design_v2.ts +0 -96
  205. package/src/proto/main_collab_design_v4.ts +0 -100
  206. package/src/proto/main_collab_design_v5.ts +0 -135
  207. package/src/proto/main_collab_global_analysis.ts +0 -122
  208. package/src/proto/main_collab_hackathon_event.ts +0 -153
  209. package/src/proto/main_collab_space_mission.ts +0 -153
  210. package/src/proto/main_philosophy.ts +0 -210
  211. package/src/proto/original_script.ts +0 -126
  212. package/src/proto/standard.ts +0 -100
  213. package/src/proto/stream.ts +0 -56
  214. package/src/proto/tasks.ts +0 -118
  215. package/src/proto/tools/global_analysis_tools.ts +0 -86
  216. package/src/proto/tools/space_mission_tools.ts +0 -60
  217. package/src/proto/vertexai.ts +0 -54
@@ -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
  });
@@ -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
+ }