@librechat/agents 3.2.32 → 3.2.34

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 (597) hide show
  1. package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
  2. package/dist/cjs/agents/AgentContext.cjs +844 -1046
  3. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  4. package/dist/cjs/common/constants.cjs +13 -13
  5. package/dist/cjs/common/constants.cjs.map +1 -1
  6. package/dist/cjs/common/enum.cjs +233 -240
  7. package/dist/cjs/common/enum.cjs.map +1 -1
  8. package/dist/cjs/common/index.cjs +2 -0
  9. package/dist/cjs/events.cjs +121 -169
  10. package/dist/cjs/events.cjs.map +1 -1
  11. package/dist/cjs/graphs/Graph.cjs +1389 -1807
  12. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  13. package/dist/cjs/graphs/MultiAgentGraph.cjs +713 -945
  14. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  15. package/dist/cjs/graphs/index.cjs +2 -0
  16. package/dist/cjs/hitl/askUserQuestion.cjs +60 -62
  17. package/dist/cjs/hitl/askUserQuestion.cjs.map +1 -1
  18. package/dist/cjs/hitl/index.cjs +1 -0
  19. package/dist/cjs/hooks/HookRegistry.cjs +176 -202
  20. package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
  21. package/dist/cjs/hooks/createToolPolicyHook.cjs +71 -101
  22. package/dist/cjs/hooks/createToolPolicyHook.cjs.map +1 -1
  23. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +170 -273
  24. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -1
  25. package/dist/cjs/hooks/executeHooks.cjs +227 -282
  26. package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
  27. package/dist/cjs/hooks/index.cjs +6 -0
  28. package/dist/cjs/hooks/matchers.cjs +196 -230
  29. package/dist/cjs/hooks/matchers.cjs.map +1 -1
  30. package/dist/cjs/hooks/types.cjs +24 -24
  31. package/dist/cjs/hooks/types.cjs.map +1 -1
  32. package/dist/cjs/instrumentation.cjs +110 -137
  33. package/dist/cjs/instrumentation.cjs.map +1 -1
  34. package/dist/cjs/langchain/google-common.cjs +0 -3
  35. package/dist/cjs/langchain/index.cjs +80 -43
  36. package/dist/cjs/langchain/language_models/chat_models.cjs +0 -3
  37. package/dist/cjs/langchain/messages/tool.cjs +0 -3
  38. package/dist/cjs/langchain/messages.cjs +35 -18
  39. package/dist/cjs/langchain/openai.cjs +0 -3
  40. package/dist/cjs/langchain/prompts.cjs +5 -8
  41. package/dist/cjs/langchain/runnables.cjs +11 -10
  42. package/dist/cjs/langchain/tools.cjs +14 -11
  43. package/dist/cjs/langchain/utils/env.cjs +5 -8
  44. package/dist/cjs/langfuse.cjs +60 -79
  45. package/dist/cjs/langfuse.cjs.map +1 -1
  46. package/dist/cjs/langfuseToolOutputTracing.cjs +267 -399
  47. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  48. package/dist/cjs/llm/anthropic/index.cjs +432 -562
  49. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  50. package/dist/cjs/llm/anthropic/types.cjs +23 -47
  51. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  52. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +441 -731
  53. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  54. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +171 -256
  55. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  56. package/dist/cjs/llm/anthropic/utils/output_parsers.cjs +2 -0
  57. package/dist/cjs/llm/anthropic/utils/tools.cjs +12 -26
  58. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -1
  59. package/dist/cjs/llm/bedrock/index.cjs +214 -240
  60. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  61. package/dist/cjs/llm/bedrock/toolCache.cjs +84 -106
  62. package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
  63. package/dist/cjs/llm/bedrock/utils/index.cjs +2 -0
  64. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +357 -620
  65. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  66. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs +141 -149
  67. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs.map +1 -1
  68. package/dist/cjs/llm/fake.cjs +86 -96
  69. package/dist/cjs/llm/fake.cjs.map +1 -1
  70. package/dist/cjs/llm/google/index.cjs +183 -237
  71. package/dist/cjs/llm/google/index.cjs.map +1 -1
  72. package/dist/cjs/llm/google/utils/common.cjs +404 -674
  73. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  74. package/dist/cjs/llm/google/utils/zod_to_genai_parameters.cjs +2 -0
  75. package/dist/cjs/llm/init.cjs +44 -53
  76. package/dist/cjs/llm/init.cjs.map +1 -1
  77. package/dist/cjs/llm/invoke.cjs +142 -182
  78. package/dist/cjs/llm/invoke.cjs.map +1 -1
  79. package/dist/cjs/llm/openai/index.cjs +1035 -1273
  80. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  81. package/dist/cjs/llm/openai/utils/index.cjs +189 -316
  82. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  83. package/dist/cjs/llm/openrouter/index.cjs +102 -153
  84. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  85. package/dist/cjs/llm/openrouter/toolCache.cjs +35 -44
  86. package/dist/cjs/llm/openrouter/toolCache.cjs.map +1 -1
  87. package/dist/cjs/llm/providers.cjs +29 -37
  88. package/dist/cjs/llm/providers.cjs.map +1 -1
  89. package/dist/cjs/llm/request.cjs +20 -33
  90. package/dist/cjs/llm/request.cjs.map +1 -1
  91. package/dist/cjs/llm/vertexai/index.cjs +446 -453
  92. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  93. package/dist/cjs/main.cjs +547 -528
  94. package/dist/cjs/messages/anthropicToolCache.cjs +68 -119
  95. package/dist/cjs/messages/anthropicToolCache.cjs.map +1 -1
  96. package/dist/cjs/messages/cache.cjs +305 -418
  97. package/dist/cjs/messages/cache.cjs.map +1 -1
  98. package/dist/cjs/messages/content.cjs +36 -49
  99. package/dist/cjs/messages/content.cjs.map +1 -1
  100. package/dist/cjs/messages/contextPruning.cjs +112 -145
  101. package/dist/cjs/messages/contextPruning.cjs.map +1 -1
  102. package/dist/cjs/messages/contextPruningSettings.cjs +36 -46
  103. package/dist/cjs/messages/contextPruningSettings.cjs.map +1 -1
  104. package/dist/cjs/messages/core.cjs +256 -397
  105. package/dist/cjs/messages/core.cjs.map +1 -1
  106. package/dist/cjs/messages/format.cjs +904 -1387
  107. package/dist/cjs/messages/format.cjs.map +1 -1
  108. package/dist/cjs/messages/ids.cjs +16 -20
  109. package/dist/cjs/messages/ids.cjs.map +1 -1
  110. package/dist/cjs/messages/index.cjs +12 -0
  111. package/dist/cjs/messages/langchain.cjs +18 -18
  112. package/dist/cjs/messages/langchain.cjs.map +1 -1
  113. package/dist/cjs/messages/prune.cjs +1054 -1517
  114. package/dist/cjs/messages/prune.cjs.map +1 -1
  115. package/dist/cjs/messages/recency.cjs +77 -95
  116. package/dist/cjs/messages/recency.cjs.map +1 -1
  117. package/dist/cjs/messages/reducer.cjs +63 -78
  118. package/dist/cjs/messages/reducer.cjs.map +1 -1
  119. package/dist/cjs/messages/tools.cjs +51 -79
  120. package/dist/cjs/messages/tools.cjs.map +1 -1
  121. package/dist/cjs/openai/index.cjs +171 -217
  122. package/dist/cjs/openai/index.cjs.map +1 -1
  123. package/dist/cjs/responses/index.cjs +302 -391
  124. package/dist/cjs/responses/index.cjs.map +1 -1
  125. package/dist/cjs/run.cjs +903 -1113
  126. package/dist/cjs/run.cjs.map +1 -1
  127. package/dist/cjs/session/AgentSession.cjs +805 -986
  128. package/dist/cjs/session/AgentSession.cjs.map +1 -1
  129. package/dist/cjs/session/JsonlSessionStore.cjs +327 -410
  130. package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
  131. package/dist/cjs/session/handlers.cjs +192 -208
  132. package/dist/cjs/session/handlers.cjs.map +1 -1
  133. package/dist/cjs/session/ids.cjs +9 -10
  134. package/dist/cjs/session/ids.cjs.map +1 -1
  135. package/dist/cjs/session/index.cjs +4 -0
  136. package/dist/cjs/session/messageSerialization.cjs +94 -156
  137. package/dist/cjs/session/messageSerialization.cjs.map +1 -1
  138. package/dist/cjs/splitStream.cjs +147 -206
  139. package/dist/cjs/splitStream.cjs.map +1 -1
  140. package/dist/cjs/stream.cjs +874 -1344
  141. package/dist/cjs/stream.cjs.map +1 -1
  142. package/dist/cjs/summarization/index.cjs +57 -101
  143. package/dist/cjs/summarization/index.cjs.map +1 -1
  144. package/dist/cjs/summarization/node.cjs +643 -796
  145. package/dist/cjs/summarization/node.cjs.map +1 -1
  146. package/dist/cjs/tools/BashExecutor.cjs +110 -136
  147. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  148. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +165 -245
  149. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  150. package/dist/cjs/tools/Calculator.cjs +36 -57
  151. package/dist/cjs/tools/Calculator.cjs.map +1 -1
  152. package/dist/cjs/tools/CodeExecutor.cjs +126 -168
  153. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  154. package/dist/cjs/tools/CodeSessionFileSummary.cjs +36 -46
  155. package/dist/cjs/tools/CodeSessionFileSummary.cjs.map +1 -1
  156. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +459 -649
  157. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  158. package/dist/cjs/tools/ReadFile.cjs +17 -20
  159. package/dist/cjs/tools/ReadFile.cjs.map +1 -1
  160. package/dist/cjs/tools/SkillTool.cjs +26 -27
  161. package/dist/cjs/tools/SkillTool.cjs.map +1 -1
  162. package/dist/cjs/tools/SubagentTool.cjs +59 -61
  163. package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
  164. package/dist/cjs/tools/ToolNode.cjs +2146 -2686
  165. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  166. package/dist/cjs/tools/ToolSearch.cjs +663 -825
  167. package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
  168. package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs +248 -340
  169. package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs.map +1 -1
  170. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs +170 -197
  171. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -1
  172. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs +425 -520
  173. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs.map +1 -1
  174. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs +91 -124
  175. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs.map +1 -1
  176. package/dist/cjs/tools/cloudflare/index.cjs +4 -0
  177. package/dist/cjs/tools/eagerEventExecution.cjs +75 -99
  178. package/dist/cjs/tools/eagerEventExecution.cjs.map +1 -1
  179. package/dist/cjs/tools/handlers.cjs +200 -262
  180. package/dist/cjs/tools/handlers.cjs.map +1 -1
  181. package/dist/cjs/tools/local/CompileCheckTool.cjs +150 -212
  182. package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -1
  183. package/dist/cjs/tools/local/FileCheckpointer.cjs +77 -85
  184. package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -1
  185. package/dist/cjs/tools/local/LocalCodingTools.cjs +763 -1022
  186. package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -1
  187. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +666 -941
  188. package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
  189. package/dist/cjs/tools/local/LocalExecutionTools.cjs +49 -92
  190. package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -1
  191. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +286 -354
  192. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
  193. package/dist/cjs/tools/local/attachments.cjs +108 -165
  194. package/dist/cjs/tools/local/attachments.cjs.map +1 -1
  195. package/dist/cjs/tools/local/bashAst.cjs +99 -113
  196. package/dist/cjs/tools/local/bashAst.cjs.map +1 -1
  197. package/dist/cjs/tools/local/editStrategies.cjs +126 -169
  198. package/dist/cjs/tools/local/editStrategies.cjs.map +1 -1
  199. package/dist/cjs/tools/local/index.cjs +12 -0
  200. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +136 -218
  201. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
  202. package/dist/cjs/tools/local/syntaxCheck.cjs +142 -161
  203. package/dist/cjs/tools/local/syntaxCheck.cjs.map +1 -1
  204. package/dist/cjs/tools/local/textEncoding.cjs +25 -23
  205. package/dist/cjs/tools/local/textEncoding.cjs.map +1 -1
  206. package/dist/cjs/tools/local/workspaceFS.cjs +38 -46
  207. package/dist/cjs/tools/local/workspaceFS.cjs.map +1 -1
  208. package/dist/cjs/tools/ptcTimeout.cjs +27 -47
  209. package/dist/cjs/tools/ptcTimeout.cjs.map +1 -1
  210. package/dist/cjs/tools/schema.cjs +24 -23
  211. package/dist/cjs/tools/schema.cjs.map +1 -1
  212. package/dist/cjs/tools/search/anthropic.cjs +24 -33
  213. package/dist/cjs/tools/search/anthropic.cjs.map +1 -1
  214. package/dist/cjs/tools/search/content.cjs +95 -137
  215. package/dist/cjs/tools/search/content.cjs.map +1 -1
  216. package/dist/cjs/tools/search/firecrawl.cjs +141 -172
  217. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  218. package/dist/cjs/tools/search/format.cjs +128 -196
  219. package/dist/cjs/tools/search/format.cjs.map +1 -1
  220. package/dist/cjs/tools/search/highlights.cjs +165 -232
  221. package/dist/cjs/tools/search/highlights.cjs.map +1 -1
  222. package/dist/cjs/tools/search/index.cjs +2 -0
  223. package/dist/cjs/tools/search/rerankers.cjs +151 -174
  224. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  225. package/dist/cjs/tools/search/schema.cjs +40 -39
  226. package/dist/cjs/tools/search/schema.cjs.map +1 -1
  227. package/dist/cjs/tools/search/search.cjs +428 -530
  228. package/dist/cjs/tools/search/search.cjs.map +1 -1
  229. package/dist/cjs/tools/search/serper-scraper.cjs +106 -127
  230. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -1
  231. package/dist/cjs/tools/search/tavily-scraper.cjs +129 -181
  232. package/dist/cjs/tools/search/tavily-scraper.cjs.map +1 -1
  233. package/dist/cjs/tools/search/tavily-search.cjs +295 -359
  234. package/dist/cjs/tools/search/tavily-search.cjs.map +1 -1
  235. package/dist/cjs/tools/search/tool.cjs +260 -299
  236. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  237. package/dist/cjs/tools/search/utils.cjs +74 -117
  238. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  239. package/dist/cjs/tools/skillCatalog.cjs +54 -72
  240. package/dist/cjs/tools/skillCatalog.cjs.map +1 -1
  241. package/dist/cjs/tools/streamedToolCallSeals.cjs +46 -34
  242. package/dist/cjs/tools/streamedToolCallSeals.cjs.map +1 -1
  243. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +612 -771
  244. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  245. package/dist/cjs/tools/subagent/index.cjs +1 -0
  246. package/dist/cjs/tools/toolOutputReferences.cjs +523 -630
  247. package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
  248. package/dist/cjs/utils/callbacks.cjs +11 -21
  249. package/dist/cjs/utils/callbacks.cjs.map +1 -1
  250. package/dist/cjs/utils/errors.cjs +70 -95
  251. package/dist/cjs/utils/errors.cjs.map +1 -1
  252. package/dist/cjs/utils/events.cjs +32 -42
  253. package/dist/cjs/utils/events.cjs.map +1 -1
  254. package/dist/cjs/utils/graph.cjs +8 -12
  255. package/dist/cjs/utils/graph.cjs.map +1 -1
  256. package/dist/cjs/utils/handlers.cjs +60 -82
  257. package/dist/cjs/utils/handlers.cjs.map +1 -1
  258. package/dist/cjs/utils/index.cjs +9 -0
  259. package/dist/cjs/utils/llm.cjs +19 -27
  260. package/dist/cjs/utils/llm.cjs.map +1 -1
  261. package/dist/cjs/utils/misc.cjs +30 -46
  262. package/dist/cjs/utils/misc.cjs.map +1 -1
  263. package/dist/cjs/utils/run.cjs +50 -66
  264. package/dist/cjs/utils/run.cjs.map +1 -1
  265. package/dist/cjs/utils/schema.cjs +11 -19
  266. package/dist/cjs/utils/schema.cjs.map +1 -1
  267. package/dist/cjs/utils/title.cjs +71 -106
  268. package/dist/cjs/utils/title.cjs.map +1 -1
  269. package/dist/cjs/utils/tokens.cjs +186 -283
  270. package/dist/cjs/utils/tokens.cjs.map +1 -1
  271. package/dist/cjs/utils/truncation.cjs +95 -114
  272. package/dist/cjs/utils/truncation.cjs.map +1 -1
  273. package/dist/esm/agents/AgentContext.mjs +844 -1044
  274. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  275. package/dist/esm/common/constants.mjs +13 -11
  276. package/dist/esm/common/constants.mjs.map +1 -1
  277. package/dist/esm/common/enum.mjs +221 -238
  278. package/dist/esm/common/enum.mjs.map +1 -1
  279. package/dist/esm/common/index.mjs +3 -0
  280. package/dist/esm/events.mjs +121 -167
  281. package/dist/esm/events.mjs.map +1 -1
  282. package/dist/esm/graphs/Graph.mjs +1388 -1804
  283. package/dist/esm/graphs/Graph.mjs.map +1 -1
  284. package/dist/esm/graphs/MultiAgentGraph.mjs +713 -943
  285. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  286. package/dist/esm/graphs/index.mjs +3 -0
  287. package/dist/esm/hitl/askUserQuestion.mjs +60 -60
  288. package/dist/esm/hitl/askUserQuestion.mjs.map +1 -1
  289. package/dist/esm/hitl/index.mjs +2 -0
  290. package/dist/esm/hooks/HookRegistry.mjs +176 -200
  291. package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
  292. package/dist/esm/hooks/createToolPolicyHook.mjs +71 -99
  293. package/dist/esm/hooks/createToolPolicyHook.mjs.map +1 -1
  294. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +170 -271
  295. package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -1
  296. package/dist/esm/hooks/executeHooks.mjs +227 -280
  297. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  298. package/dist/esm/hooks/index.mjs +7 -0
  299. package/dist/esm/hooks/matchers.mjs +196 -228
  300. package/dist/esm/hooks/matchers.mjs.map +1 -1
  301. package/dist/esm/hooks/types.mjs +24 -22
  302. package/dist/esm/hooks/types.mjs.map +1 -1
  303. package/dist/esm/instrumentation.mjs +109 -132
  304. package/dist/esm/instrumentation.mjs.map +1 -1
  305. package/dist/esm/langchain/google-common.mjs +1 -2
  306. package/dist/esm/langchain/index.mjs +5 -5
  307. package/dist/esm/langchain/language_models/chat_models.mjs +1 -2
  308. package/dist/esm/langchain/messages/tool.mjs +1 -2
  309. package/dist/esm/langchain/messages.mjs +2 -2
  310. package/dist/esm/langchain/openai.mjs +1 -2
  311. package/dist/esm/langchain/prompts.mjs +2 -2
  312. package/dist/esm/langchain/runnables.mjs +2 -2
  313. package/dist/esm/langchain/tools.mjs +2 -2
  314. package/dist/esm/langchain/utils/env.mjs +2 -2
  315. package/dist/esm/langfuse.mjs +60 -76
  316. package/dist/esm/langfuse.mjs.map +1 -1
  317. package/dist/esm/langfuseToolOutputTracing.mjs +267 -395
  318. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  319. package/dist/esm/llm/anthropic/index.mjs +432 -559
  320. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  321. package/dist/esm/llm/anthropic/types.mjs +23 -45
  322. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  323. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +439 -725
  324. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  325. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +171 -253
  326. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  327. package/dist/esm/llm/anthropic/utils/output_parsers.mjs +3 -0
  328. package/dist/esm/llm/anthropic/utils/tools.mjs +12 -24
  329. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -1
  330. package/dist/esm/llm/bedrock/index.mjs +214 -238
  331. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  332. package/dist/esm/llm/bedrock/toolCache.mjs +84 -104
  333. package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
  334. package/dist/esm/llm/bedrock/utils/index.mjs +3 -0
  335. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +357 -618
  336. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  337. package/dist/esm/llm/bedrock/utils/message_outputs.mjs +140 -147
  338. package/dist/esm/llm/bedrock/utils/message_outputs.mjs.map +1 -1
  339. package/dist/esm/llm/fake.mjs +86 -94
  340. package/dist/esm/llm/fake.mjs.map +1 -1
  341. package/dist/esm/llm/google/index.mjs +183 -235
  342. package/dist/esm/llm/google/index.mjs.map +1 -1
  343. package/dist/esm/llm/google/utils/common.mjs +403 -666
  344. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  345. package/dist/esm/llm/google/utils/zod_to_genai_parameters.mjs +3 -0
  346. package/dist/esm/llm/init.mjs +44 -51
  347. package/dist/esm/llm/init.mjs.map +1 -1
  348. package/dist/esm/llm/invoke.mjs +142 -180
  349. package/dist/esm/llm/invoke.mjs.map +1 -1
  350. package/dist/esm/llm/openai/index.mjs +1035 -1268
  351. package/dist/esm/llm/openai/index.mjs.map +1 -1
  352. package/dist/esm/llm/openai/utils/index.mjs +188 -312
  353. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  354. package/dist/esm/llm/openrouter/index.mjs +102 -151
  355. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  356. package/dist/esm/llm/openrouter/toolCache.mjs +35 -42
  357. package/dist/esm/llm/openrouter/toolCache.mjs.map +1 -1
  358. package/dist/esm/llm/providers.mjs +29 -34
  359. package/dist/esm/llm/providers.mjs.map +1 -1
  360. package/dist/esm/llm/request.mjs +20 -31
  361. package/dist/esm/llm/request.mjs.map +1 -1
  362. package/dist/esm/llm/vertexai/index.mjs +446 -449
  363. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  364. package/dist/esm/main.mjs +99 -87
  365. package/dist/esm/messages/anthropicToolCache.mjs +68 -117
  366. package/dist/esm/messages/anthropicToolCache.mjs.map +1 -1
  367. package/dist/esm/messages/cache.mjs +305 -416
  368. package/dist/esm/messages/cache.mjs.map +1 -1
  369. package/dist/esm/messages/content.mjs +36 -47
  370. package/dist/esm/messages/content.mjs.map +1 -1
  371. package/dist/esm/messages/contextPruning.mjs +112 -143
  372. package/dist/esm/messages/contextPruning.mjs.map +1 -1
  373. package/dist/esm/messages/contextPruningSettings.mjs +36 -44
  374. package/dist/esm/messages/contextPruningSettings.mjs.map +1 -1
  375. package/dist/esm/messages/core.mjs +254 -393
  376. package/dist/esm/messages/core.mjs.map +1 -1
  377. package/dist/esm/messages/format.mjs +902 -1383
  378. package/dist/esm/messages/format.mjs.map +1 -1
  379. package/dist/esm/messages/ids.mjs +16 -18
  380. package/dist/esm/messages/ids.mjs.map +1 -1
  381. package/dist/esm/messages/index.mjs +13 -0
  382. package/dist/esm/messages/langchain.mjs +18 -16
  383. package/dist/esm/messages/langchain.mjs.map +1 -1
  384. package/dist/esm/messages/prune.mjs +1053 -1514
  385. package/dist/esm/messages/prune.mjs.map +1 -1
  386. package/dist/esm/messages/recency.mjs +77 -93
  387. package/dist/esm/messages/recency.mjs.map +1 -1
  388. package/dist/esm/messages/reducer.mjs +63 -76
  389. package/dist/esm/messages/reducer.mjs.map +1 -1
  390. package/dist/esm/messages/tools.mjs +49 -75
  391. package/dist/esm/messages/tools.mjs.map +1 -1
  392. package/dist/esm/openai/index.mjs +170 -215
  393. package/dist/esm/openai/index.mjs.map +1 -1
  394. package/dist/esm/responses/index.mjs +301 -389
  395. package/dist/esm/responses/index.mjs.map +1 -1
  396. package/dist/esm/run.mjs +903 -1111
  397. package/dist/esm/run.mjs.map +1 -1
  398. package/dist/esm/session/AgentSession.mjs +806 -985
  399. package/dist/esm/session/AgentSession.mjs.map +1 -1
  400. package/dist/esm/session/JsonlSessionStore.mjs +326 -407
  401. package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
  402. package/dist/esm/session/handlers.mjs +192 -206
  403. package/dist/esm/session/handlers.mjs.map +1 -1
  404. package/dist/esm/session/ids.mjs +9 -8
  405. package/dist/esm/session/ids.mjs.map +1 -1
  406. package/dist/esm/session/index.mjs +5 -0
  407. package/dist/esm/session/messageSerialization.mjs +94 -154
  408. package/dist/esm/session/messageSerialization.mjs.map +1 -1
  409. package/dist/esm/splitStream.mjs +147 -204
  410. package/dist/esm/splitStream.mjs.map +1 -1
  411. package/dist/esm/stream.mjs +872 -1341
  412. package/dist/esm/stream.mjs.map +1 -1
  413. package/dist/esm/summarization/index.mjs +57 -99
  414. package/dist/esm/summarization/index.mjs.map +1 -1
  415. package/dist/esm/summarization/node.mjs +640 -790
  416. package/dist/esm/summarization/node.mjs.map +1 -1
  417. package/dist/esm/tools/BashExecutor.mjs +103 -129
  418. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  419. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +162 -239
  420. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  421. package/dist/esm/tools/Calculator.mjs +34 -36
  422. package/dist/esm/tools/Calculator.mjs.map +1 -1
  423. package/dist/esm/tools/CodeExecutor.mjs +123 -164
  424. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  425. package/dist/esm/tools/CodeSessionFileSummary.mjs +36 -44
  426. package/dist/esm/tools/CodeSessionFileSummary.mjs.map +1 -1
  427. package/dist/esm/tools/ProgrammaticToolCalling.mjs +454 -644
  428. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  429. package/dist/esm/tools/ReadFile.mjs +17 -18
  430. package/dist/esm/tools/ReadFile.mjs.map +1 -1
  431. package/dist/esm/tools/SkillTool.mjs +26 -25
  432. package/dist/esm/tools/SkillTool.mjs.map +1 -1
  433. package/dist/esm/tools/SubagentTool.mjs +59 -59
  434. package/dist/esm/tools/SubagentTool.mjs.map +1 -1
  435. package/dist/esm/tools/ToolNode.mjs +2144 -2684
  436. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  437. package/dist/esm/tools/ToolSearch.mjs +659 -804
  438. package/dist/esm/tools/ToolSearch.mjs.map +1 -1
  439. package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs +248 -338
  440. package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs.map +1 -1
  441. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs +170 -195
  442. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -1
  443. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs +424 -517
  444. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs.map +1 -1
  445. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs +91 -122
  446. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs.map +1 -1
  447. package/dist/esm/tools/cloudflare/index.mjs +5 -0
  448. package/dist/esm/tools/eagerEventExecution.mjs +75 -96
  449. package/dist/esm/tools/eagerEventExecution.mjs.map +1 -1
  450. package/dist/esm/tools/handlers.mjs +200 -260
  451. package/dist/esm/tools/handlers.mjs.map +1 -1
  452. package/dist/esm/tools/local/CompileCheckTool.mjs +150 -210
  453. package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -1
  454. package/dist/esm/tools/local/FileCheckpointer.mjs +77 -83
  455. package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -1
  456. package/dist/esm/tools/local/LocalCodingTools.mjs +760 -1017
  457. package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -1
  458. package/dist/esm/tools/local/LocalExecutionEngine.mjs +663 -936
  459. package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
  460. package/dist/esm/tools/local/LocalExecutionTools.mjs +49 -90
  461. package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -1
  462. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +283 -349
  463. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
  464. package/dist/esm/tools/local/attachments.mjs +108 -163
  465. package/dist/esm/tools/local/attachments.mjs.map +1 -1
  466. package/dist/esm/tools/local/bashAst.mjs +99 -111
  467. package/dist/esm/tools/local/bashAst.mjs.map +1 -1
  468. package/dist/esm/tools/local/editStrategies.mjs +126 -167
  469. package/dist/esm/tools/local/editStrategies.mjs.map +1 -1
  470. package/dist/esm/tools/local/index.mjs +13 -0
  471. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +136 -216
  472. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
  473. package/dist/esm/tools/local/syntaxCheck.mjs +138 -155
  474. package/dist/esm/tools/local/syntaxCheck.mjs.map +1 -1
  475. package/dist/esm/tools/local/textEncoding.mjs +25 -21
  476. package/dist/esm/tools/local/textEncoding.mjs.map +1 -1
  477. package/dist/esm/tools/local/workspaceFS.mjs +38 -44
  478. package/dist/esm/tools/local/workspaceFS.mjs.map +1 -1
  479. package/dist/esm/tools/ptcTimeout.mjs +27 -42
  480. package/dist/esm/tools/ptcTimeout.mjs.map +1 -1
  481. package/dist/esm/tools/schema.mjs +24 -21
  482. package/dist/esm/tools/schema.mjs.map +1 -1
  483. package/dist/esm/tools/search/anthropic.mjs +24 -31
  484. package/dist/esm/tools/search/anthropic.mjs.map +1 -1
  485. package/dist/esm/tools/search/content.mjs +93 -116
  486. package/dist/esm/tools/search/content.mjs.map +1 -1
  487. package/dist/esm/tools/search/firecrawl.mjs +139 -169
  488. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  489. package/dist/esm/tools/search/format.mjs +128 -194
  490. package/dist/esm/tools/search/format.mjs.map +1 -1
  491. package/dist/esm/tools/search/highlights.mjs +165 -230
  492. package/dist/esm/tools/search/highlights.mjs.map +1 -1
  493. package/dist/esm/tools/search/index.mjs +3 -0
  494. package/dist/esm/tools/search/rerankers.mjs +149 -168
  495. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  496. package/dist/esm/tools/search/schema.mjs +39 -37
  497. package/dist/esm/tools/search/schema.mjs.map +1 -1
  498. package/dist/esm/tools/search/search.mjs +426 -528
  499. package/dist/esm/tools/search/search.mjs.map +1 -1
  500. package/dist/esm/tools/search/serper-scraper.mjs +104 -124
  501. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -1
  502. package/dist/esm/tools/search/tavily-scraper.mjs +127 -178
  503. package/dist/esm/tools/search/tavily-scraper.mjs.map +1 -1
  504. package/dist/esm/tools/search/tavily-search.mjs +293 -357
  505. package/dist/esm/tools/search/tavily-search.mjs.map +1 -1
  506. package/dist/esm/tools/search/tool.mjs +259 -297
  507. package/dist/esm/tools/search/tool.mjs.map +1 -1
  508. package/dist/esm/tools/search/utils.mjs +74 -115
  509. package/dist/esm/tools/search/utils.mjs.map +1 -1
  510. package/dist/esm/tools/skillCatalog.mjs +54 -70
  511. package/dist/esm/tools/skillCatalog.mjs.map +1 -1
  512. package/dist/esm/tools/streamedToolCallSeals.mjs +42 -31
  513. package/dist/esm/tools/streamedToolCallSeals.mjs.map +1 -1
  514. package/dist/esm/tools/subagent/SubagentExecutor.mjs +612 -768
  515. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  516. package/dist/esm/tools/subagent/index.mjs +2 -0
  517. package/dist/esm/tools/toolOutputReferences.mjs +523 -624
  518. package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
  519. package/dist/esm/utils/callbacks.mjs +11 -19
  520. package/dist/esm/utils/callbacks.mjs.map +1 -1
  521. package/dist/esm/utils/errors.mjs +70 -93
  522. package/dist/esm/utils/errors.mjs.map +1 -1
  523. package/dist/esm/utils/events.mjs +32 -40
  524. package/dist/esm/utils/events.mjs.map +1 -1
  525. package/dist/esm/utils/graph.mjs +8 -10
  526. package/dist/esm/utils/graph.mjs.map +1 -1
  527. package/dist/esm/utils/handlers.mjs +60 -80
  528. package/dist/esm/utils/handlers.mjs.map +1 -1
  529. package/dist/esm/utils/index.mjs +10 -0
  530. package/dist/esm/utils/llm.mjs +19 -25
  531. package/dist/esm/utils/llm.mjs.map +1 -1
  532. package/dist/esm/utils/misc.mjs +30 -44
  533. package/dist/esm/utils/misc.mjs.map +1 -1
  534. package/dist/esm/utils/run.mjs +50 -64
  535. package/dist/esm/utils/run.mjs.map +1 -1
  536. package/dist/esm/utils/schema.mjs +11 -17
  537. package/dist/esm/utils/schema.mjs.map +1 -1
  538. package/dist/esm/utils/title.mjs +71 -104
  539. package/dist/esm/utils/title.mjs.map +1 -1
  540. package/dist/esm/utils/tokens.mjs +186 -281
  541. package/dist/esm/utils/tokens.mjs.map +1 -1
  542. package/dist/esm/utils/truncation.mjs +95 -112
  543. package/dist/esm/utils/truncation.mjs.map +1 -1
  544. package/dist/types/llm/bedrock/utils/index.d.ts +1 -1
  545. package/dist/types/llm/bedrock/utils/message_outputs.d.ts +9 -0
  546. package/dist/types/llm/vertexai/index.d.ts +10 -0
  547. package/dist/types/tools/ToolNode.d.ts +8 -0
  548. package/dist/types/tools/search/tool.d.ts +17 -0
  549. package/dist/types/tools/search/types.d.ts +4 -0
  550. package/dist/types/tools/streamedToolCallSeals.d.ts +5 -1
  551. package/dist/types/types/tools.d.ts +10 -0
  552. package/package.json +4 -10
  553. package/src/__tests__/stream.eagerEventExecution.test.ts +703 -0
  554. package/src/llm/bedrock/index.ts +40 -0
  555. package/src/llm/bedrock/streamSealDispatch.test.ts +158 -0
  556. package/src/llm/bedrock/utils/index.ts +1 -0
  557. package/src/llm/bedrock/utils/message_outputs.test.ts +85 -0
  558. package/src/llm/bedrock/utils/message_outputs.ts +43 -0
  559. package/src/llm/google/utils/common.test.ts +64 -0
  560. package/src/llm/google/utils/common.ts +18 -0
  561. package/src/llm/openai/index.ts +95 -1
  562. package/src/llm/openai/sequentialToolCallSeals.test.ts +199 -0
  563. package/src/llm/vertexai/index.ts +31 -0
  564. package/src/llm/vertexai/sealStreamedToolCalls.test.ts +88 -0
  565. package/src/llm/vertexai/streamSealDispatch.test.ts +148 -0
  566. package/src/stream.ts +40 -6
  567. package/src/tools/ToolNode.ts +85 -3
  568. package/src/tools/__tests__/ToolNode.onResultCompletion.test.ts +368 -0
  569. package/src/tools/search/highlights.ts +9 -1
  570. package/src/tools/search/search.ts +41 -3
  571. package/src/tools/search/source-processing.test.ts +373 -0
  572. package/src/tools/search/tool.ts +22 -2
  573. package/src/tools/search/types.ts +4 -0
  574. package/src/tools/streamedToolCallSeals.ts +37 -9
  575. package/src/types/tools.ts +10 -0
  576. package/dist/cjs/langchain/google-common.cjs.map +0 -1
  577. package/dist/cjs/langchain/index.cjs.map +0 -1
  578. package/dist/cjs/langchain/language_models/chat_models.cjs.map +0 -1
  579. package/dist/cjs/langchain/messages/tool.cjs.map +0 -1
  580. package/dist/cjs/langchain/messages.cjs.map +0 -1
  581. package/dist/cjs/langchain/openai.cjs.map +0 -1
  582. package/dist/cjs/langchain/prompts.cjs.map +0 -1
  583. package/dist/cjs/langchain/runnables.cjs.map +0 -1
  584. package/dist/cjs/langchain/tools.cjs.map +0 -1
  585. package/dist/cjs/langchain/utils/env.cjs.map +0 -1
  586. package/dist/cjs/main.cjs.map +0 -1
  587. package/dist/esm/langchain/google-common.mjs.map +0 -1
  588. package/dist/esm/langchain/index.mjs.map +0 -1
  589. package/dist/esm/langchain/language_models/chat_models.mjs.map +0 -1
  590. package/dist/esm/langchain/messages/tool.mjs.map +0 -1
  591. package/dist/esm/langchain/messages.mjs.map +0 -1
  592. package/dist/esm/langchain/openai.mjs.map +0 -1
  593. package/dist/esm/langchain/prompts.mjs.map +0 -1
  594. package/dist/esm/langchain/runnables.mjs.map +0 -1
  595. package/dist/esm/langchain/tools.mjs.map +0 -1
  596. package/dist/esm/langchain/utils/env.mjs.map +0 -1
  597. package/dist/esm/main.mjs.map +0 -1
@@ -1,20 +1,17 @@
1
- import { config } from 'dotenv';
2
- import fetch from 'node-fetch';
3
- import { HttpsProxyAgent } from 'https-proxy-agent';
4
- import { tool } from '@langchain/core/tools';
5
- import { CODE_ARTIFACT_PATH_GUIDANCE, getCodeBaseURL, appendFailedExecutionFileReminder, resolveCodeApiAuthHeaders, buildCodeApiHttpErrorMessage, emptyOutputMessage, appendTmpScratchReminder } from './CodeExecutor.mjs';
6
- import { resolveCodeApiRunTimeoutMs, createCodeApiRunTimeoutSchema, clampCodeApiRunTimeoutMs } from './ptcTimeout.mjs';
7
- import { Constants } from '../common/enum.mjs';
8
- import { appendCodeSessionFileSummary } from './CodeSessionFileSummary.mjs';
9
-
10
- // src/tools/ProgrammaticToolCalling.ts
1
+ import "../common/enum.mjs";
2
+ import "../common/index.mjs";
3
+ import { appendCodeSessionFileSummary } from "./CodeSessionFileSummary.mjs";
4
+ import { CODE_ARTIFACT_PATH_GUIDANCE, appendFailedExecutionFileReminder, appendTmpScratchReminder, buildCodeApiHttpErrorMessage, emptyOutputMessage, getCodeBaseURL, resolveCodeApiAuthHeaders } from "./CodeExecutor.mjs";
5
+ import { clampCodeApiRunTimeoutMs, createCodeApiRunTimeoutSchema, resolveCodeApiRunTimeoutMs } from "./ptcTimeout.mjs";
6
+ import { tool } from "@langchain/core/tools";
7
+ import { config } from "dotenv";
8
+ import fetch from "node-fetch";
9
+ import { HttpsProxyAgent } from "https-proxy-agent";
10
+ //#region src/tools/ProgrammaticToolCalling.ts
11
11
  config();
12
12
  /** Default max round-trips to prevent infinite loops */
13
13
  const DEFAULT_MAX_ROUND_TRIPS = 20;
14
14
  const DEFAULT_RUN_TIMEOUT_MS = resolveCodeApiRunTimeoutMs();
15
- // ============================================================================
16
- // Description Components (Single Source of Truth)
17
- // ============================================================================
18
15
  const STATELESS_WARNING = `CRITICAL - STATELESS EXECUTION:
19
16
  Each call is a fresh Python interpreter. Variables, imports, and data do NOT persist between calls.
20
17
  You MUST complete your entire workflow in ONE code block: query → process → output.
@@ -28,7 +25,7 @@ const CORE_RULES = `Rules:
28
25
  - Only print() output returns to the model
29
26
  - ${CODE_ARTIFACT_PATH_GUIDANCE}
30
27
  - timeout caps one sandbox run/replay iteration, not the total multi-round-trip workflow`;
31
- const ADDITIONAL_RULES = '- Tool names normalized: hyphens→underscores, keywords get `_tool` suffix';
28
+ const ADDITIONAL_RULES = "- Tool names normalized: hyphens→underscores, keywords get `_tool` suffix";
32
29
  const EXAMPLES = `Example (Complete workflow in one call):
33
30
  # Query data
34
31
  data = await query_database(sql="SELECT * FROM users")
@@ -42,9 +39,6 @@ const EXAMPLES = `Example (Complete workflow in one call):
42
39
  Example (Parallel calls):
43
40
  sf, ny = await asyncio.gather(get_weather(city="SF"), get_weather(city="NY"))
44
41
  print(f"SF: {sf}, NY: {ny}")`;
45
- // ============================================================================
46
- // Schema
47
- // ============================================================================
48
42
  const CODE_PARAM_DESCRIPTION = `Python code that calls tools programmatically. Tools are available as async functions.
49
43
 
50
44
  ${STATELESS_WARNING}
@@ -55,21 +49,21 @@ ${EXAMPLES}
55
49
 
56
50
  ${CORE_RULES}`;
57
51
  function createProgrammaticToolCallingSchema(maxRunTimeoutMs = DEFAULT_RUN_TIMEOUT_MS) {
58
- return {
59
- type: 'object',
60
- properties: {
61
- code: {
62
- type: 'string',
63
- minLength: 1,
64
- description: CODE_PARAM_DESCRIPTION,
65
- },
66
- timeout: createCodeApiRunTimeoutSchema(maxRunTimeoutMs),
67
- },
68
- required: ['code'],
69
- };
52
+ return {
53
+ type: "object",
54
+ properties: {
55
+ code: {
56
+ type: "string",
57
+ minLength: 1,
58
+ description: CODE_PARAM_DESCRIPTION
59
+ },
60
+ timeout: createCodeApiRunTimeoutSchema(maxRunTimeoutMs)
61
+ },
62
+ required: ["code"]
63
+ };
70
64
  }
71
65
  const ProgrammaticToolCallingSchema = createProgrammaticToolCallingSchema();
72
- const ProgrammaticToolCallingName = Constants.PROGRAMMATIC_TOOL_CALLING;
66
+ const ProgrammaticToolCallingName = "run_tools_with_code";
73
67
  const ProgrammaticToolCallingDescription = `
74
68
  Run tools via Python code. Auto-wrapped in async context—just use \`await\` directly.
75
69
 
@@ -83,662 +77,478 @@ When to use: loops, conditionals, parallel (\`asyncio.gather\`), multi-step pipe
83
77
  ${EXAMPLES}
84
78
  `.trim();
85
79
  const ProgrammaticToolCallingDefinition = {
86
- name: ProgrammaticToolCallingName,
87
- description: ProgrammaticToolCallingDescription,
88
- schema: ProgrammaticToolCallingSchema,
80
+ name: ProgrammaticToolCallingName,
81
+ description: ProgrammaticToolCallingDescription,
82
+ schema: ProgrammaticToolCallingSchema
89
83
  };
90
- // ============================================================================
91
- // Helper Functions
92
- // ============================================================================
93
84
  /** Python reserved keywords that get `_tool` suffix in Code API */
94
85
  const PYTHON_KEYWORDS = new Set([
95
- 'False',
96
- 'None',
97
- 'True',
98
- 'and',
99
- 'as',
100
- 'assert',
101
- 'async',
102
- 'await',
103
- 'break',
104
- 'class',
105
- 'continue',
106
- 'def',
107
- 'del',
108
- 'elif',
109
- 'else',
110
- 'except',
111
- 'finally',
112
- 'for',
113
- 'from',
114
- 'global',
115
- 'if',
116
- 'import',
117
- 'in',
118
- 'is',
119
- 'lambda',
120
- 'nonlocal',
121
- 'not',
122
- 'or',
123
- 'pass',
124
- 'raise',
125
- 'return',
126
- 'try',
127
- 'while',
128
- 'with',
129
- 'yield',
86
+ "False",
87
+ "None",
88
+ "True",
89
+ "and",
90
+ "as",
91
+ "assert",
92
+ "async",
93
+ "await",
94
+ "break",
95
+ "class",
96
+ "continue",
97
+ "def",
98
+ "del",
99
+ "elif",
100
+ "else",
101
+ "except",
102
+ "finally",
103
+ "for",
104
+ "from",
105
+ "global",
106
+ "if",
107
+ "import",
108
+ "in",
109
+ "is",
110
+ "lambda",
111
+ "nonlocal",
112
+ "not",
113
+ "or",
114
+ "pass",
115
+ "raise",
116
+ "return",
117
+ "try",
118
+ "while",
119
+ "with",
120
+ "yield"
130
121
  ]);
131
122
  function isFetchSessionFilesScope(value) {
132
- if (value == null || typeof value !== 'object') {
133
- return false;
134
- }
135
- const scope = value;
136
- if ((scope.kind === 'agent' || scope.kind === 'user') &&
137
- typeof scope.id === 'string') {
138
- return true;
139
- }
140
- return (scope.kind === 'skill' &&
141
- typeof scope.id === 'string' &&
142
- typeof scope.version === 'number');
123
+ if (value == null || typeof value !== "object") return false;
124
+ const scope = value;
125
+ if ((scope.kind === "agent" || scope.kind === "user") && typeof scope.id === "string") return true;
126
+ return scope.kind === "skill" && typeof scope.id === "string" && typeof scope.version === "number";
143
127
  }
144
128
  function isCodeApiAuthHeaders(value) {
145
- return value != null && typeof value !== 'string';
129
+ return value != null && typeof value !== "string";
146
130
  }
147
131
  function isCodeApiSessionFileWire(value) {
148
- return value != null && typeof value === 'object';
132
+ return value != null && typeof value === "object";
149
133
  }
150
134
  function isCodeApiSessionFileMetadata(value) {
151
- return value != null && typeof value === 'object';
135
+ return value != null && typeof value === "object";
152
136
  }
153
137
  function normalizeSessionFile(file, sessionId, scope) {
154
- const metadata = isCodeApiSessionFileMetadata(file.metadata)
155
- ? file.metadata
156
- : undefined;
157
- const rawName = typeof file.name === 'string' ? file.name : '';
158
- const nameParts = rawName.split('/');
159
- const fallbackId = nameParts.length > 1 ? nameParts[1].split('.')[0] : '';
160
- const id = typeof file.id === 'string' && file.id !== '' ? file.id : fallbackId;
161
- const originalFilename = metadata?.['original-filename'];
162
- const name = typeof originalFilename === 'string' ? originalFilename : rawName;
163
- const storage_session_id = typeof file.storage_session_id === 'string'
164
- ? file.storage_session_id
165
- : sessionId;
166
- const resource_id = typeof file.resource_id === 'string' && file.resource_id !== ''
167
- ? file.resource_id
168
- : (scope?.id ?? id);
169
- if (scope?.kind === 'skill') {
170
- return {
171
- storage_session_id,
172
- kind: 'skill',
173
- id,
174
- resource_id,
175
- name,
176
- version: scope.version,
177
- };
178
- }
179
- if (scope != null) {
180
- return {
181
- storage_session_id,
182
- kind: scope.kind,
183
- id,
184
- resource_id,
185
- name,
186
- };
187
- }
188
- return {
189
- storage_session_id,
190
- kind: 'user',
191
- id,
192
- resource_id: id,
193
- name,
194
- };
138
+ const metadata = isCodeApiSessionFileMetadata(file.metadata) ? file.metadata : void 0;
139
+ const rawName = typeof file.name === "string" ? file.name : "";
140
+ const nameParts = rawName.split("/");
141
+ const fallbackId = nameParts.length > 1 ? nameParts[1].split(".")[0] : "";
142
+ const id = typeof file.id === "string" && file.id !== "" ? file.id : fallbackId;
143
+ const originalFilename = metadata?.["original-filename"];
144
+ const name = typeof originalFilename === "string" ? originalFilename : rawName;
145
+ const storage_session_id = typeof file.storage_session_id === "string" ? file.storage_session_id : sessionId;
146
+ const resource_id = typeof file.resource_id === "string" && file.resource_id !== "" ? file.resource_id : scope?.id ?? id;
147
+ if (scope?.kind === "skill") return {
148
+ storage_session_id,
149
+ kind: "skill",
150
+ id,
151
+ resource_id,
152
+ name,
153
+ version: scope.version
154
+ };
155
+ if (scope != null) return {
156
+ storage_session_id,
157
+ kind: scope.kind,
158
+ id,
159
+ resource_id,
160
+ name
161
+ };
162
+ return {
163
+ storage_session_id,
164
+ kind: "user",
165
+ id,
166
+ resource_id: id,
167
+ name
168
+ };
195
169
  }
196
170
  /**
197
- * Normalizes a tool name to Python identifier format.
198
- * Must match the Code API's `normalizePythonFunctionName` exactly:
199
- * 1. Replace hyphens and spaces with underscores
200
- * 2. Remove any other invalid characters
201
- * 3. Prefix with underscore if starts with number
202
- * 4. Append `_tool` if it's a Python keyword
203
- * @param name - The tool name to normalize
204
- * @returns Normalized Python-safe identifier
205
- */
171
+ * Normalizes a tool name to Python identifier format.
172
+ * Must match the Code API's `normalizePythonFunctionName` exactly:
173
+ * 1. Replace hyphens and spaces with underscores
174
+ * 2. Remove any other invalid characters
175
+ * 3. Prefix with underscore if starts with number
176
+ * 4. Append `_tool` if it's a Python keyword
177
+ * @param name - The tool name to normalize
178
+ * @returns Normalized Python-safe identifier
179
+ */
206
180
  function normalizeToPythonIdentifier(name) {
207
- let normalized = name.replace(/[-\s]/g, '_');
208
- normalized = normalized.replace(/[^a-zA-Z0-9_]/g, '');
209
- if (/^[0-9]/.test(normalized)) {
210
- normalized = '_' + normalized;
211
- }
212
- if (PYTHON_KEYWORDS.has(normalized)) {
213
- normalized = normalized + '_tool';
214
- }
215
- return normalized;
181
+ let normalized = name.replace(/[-\s]/g, "_");
182
+ normalized = normalized.replace(/[^a-zA-Z0-9_]/g, "");
183
+ if (/^[0-9]/.test(normalized)) normalized = "_" + normalized;
184
+ if (PYTHON_KEYWORDS.has(normalized)) normalized = normalized + "_tool";
185
+ return normalized;
216
186
  }
217
187
  /**
218
- * Extracts tool names that are actually called in the Python code.
219
- * Handles hyphen/underscore conversion since Python identifiers use underscores.
220
- * @param code - The Python code to analyze
221
- * @param toolNameMap - Map from normalized Python name to original tool name
222
- * @returns Set of original tool names found in the code
223
- */
188
+ * Extracts tool names that are actually called in the Python code.
189
+ * Handles hyphen/underscore conversion since Python identifiers use underscores.
190
+ * @param code - The Python code to analyze
191
+ * @param toolNameMap - Map from normalized Python name to original tool name
192
+ * @returns Set of original tool names found in the code
193
+ */
224
194
  function extractUsedToolNames(code, toolNameMap) {
225
- const usedTools = new Set();
226
- for (const [pythonName, originalName] of toolNameMap) {
227
- const escapedName = pythonName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
228
- const pattern = new RegExp(`\\b${escapedName}\\s*\\(`, 'g');
229
- if (pattern.test(code)) {
230
- usedTools.add(originalName);
231
- }
232
- }
233
- return usedTools;
195
+ const usedTools = /* @__PURE__ */ new Set();
196
+ for (const [pythonName, originalName] of toolNameMap) {
197
+ const escapedName = pythonName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
198
+ if (new RegExp(`\\b${escapedName}\\s*\\(`, "g").test(code)) usedTools.add(originalName);
199
+ }
200
+ return usedTools;
234
201
  }
235
202
  /**
236
- * Filters tool definitions to only include tools actually used in the code.
237
- * Handles the hyphen-to-underscore conversion for Python compatibility.
238
- * @param toolDefs - All available tool definitions
239
- * @param code - The Python code to analyze
240
- * @param debug - Enable debug logging
241
- * @returns Filtered array of tool definitions
242
- */
203
+ * Filters tool definitions to only include tools actually used in the code.
204
+ * Handles the hyphen-to-underscore conversion for Python compatibility.
205
+ * @param toolDefs - All available tool definitions
206
+ * @param code - The Python code to analyze
207
+ * @param debug - Enable debug logging
208
+ * @returns Filtered array of tool definitions
209
+ */
243
210
  function filterToolsByUsage(toolDefs, code, debug = false) {
244
- const toolNameMap = new Map();
245
- for (const tool of toolDefs) {
246
- const pythonName = normalizeToPythonIdentifier(tool.name);
247
- toolNameMap.set(pythonName, tool.name);
248
- }
249
- const usedToolNames = extractUsedToolNames(code, toolNameMap);
250
- if (debug) {
251
- // eslint-disable-next-line no-console
252
- console.log(`[PTC Debug] Tool filtering: found ${usedToolNames.size}/${toolDefs.length} tools in code`);
253
- if (usedToolNames.size > 0) {
254
- // eslint-disable-next-line no-console
255
- console.log(`[PTC Debug] Matched tools: ${Array.from(usedToolNames).join(', ')}`);
256
- }
257
- }
258
- if (usedToolNames.size === 0) {
259
- if (debug) {
260
- // eslint-disable-next-line no-console
261
- console.log('[PTC Debug] No tools detected in code - sending all tools as fallback');
262
- }
263
- return toolDefs;
264
- }
265
- return toolDefs.filter((tool) => usedToolNames.has(tool.name));
211
+ const toolNameMap = /* @__PURE__ */ new Map();
212
+ for (const tool of toolDefs) {
213
+ const pythonName = normalizeToPythonIdentifier(tool.name);
214
+ toolNameMap.set(pythonName, tool.name);
215
+ }
216
+ const usedToolNames = extractUsedToolNames(code, toolNameMap);
217
+ if (debug) {
218
+ console.log(`[PTC Debug] Tool filtering: found ${usedToolNames.size}/${toolDefs.length} tools in code`);
219
+ if (usedToolNames.size > 0) console.log(`[PTC Debug] Matched tools: ${Array.from(usedToolNames).join(", ")}`);
220
+ }
221
+ if (usedToolNames.size === 0) {
222
+ if (debug) console.log("[PTC Debug] No tools detected in code - sending all tools as fallback");
223
+ return toolDefs;
224
+ }
225
+ return toolDefs.filter((tool) => usedToolNames.has(tool.name));
266
226
  }
267
227
  async function fetchSessionFiles(baseUrl, sessionId, scopeOrProxy, proxyOrAuthHeaders, scopedAuthHeaders) {
268
- try {
269
- const scope = isFetchSessionFilesScope(scopeOrProxy)
270
- ? scopeOrProxy
271
- : undefined;
272
- let proxy;
273
- let authHeaders;
274
- if (scope == null) {
275
- proxy = typeof scopeOrProxy === 'string' ? scopeOrProxy : undefined;
276
- authHeaders = isCodeApiAuthHeaders(proxyOrAuthHeaders)
277
- ? proxyOrAuthHeaders
278
- : undefined;
279
- }
280
- else if (typeof proxyOrAuthHeaders === 'string') {
281
- proxy = proxyOrAuthHeaders;
282
- authHeaders = scopedAuthHeaders;
283
- }
284
- else {
285
- authHeaders = proxyOrAuthHeaders ?? scopedAuthHeaders;
286
- }
287
- const query = new URLSearchParams({ detail: 'full' });
288
- if (scope != null) {
289
- query.set('kind', scope.kind);
290
- query.set('id', scope.id);
291
- if (scope.kind === 'skill') {
292
- query.set('version', String(scope.version));
293
- }
294
- }
295
- const filesEndpoint = `${baseUrl}/files/${encodeURIComponent(sessionId)}?${query.toString()}`;
296
- const resolvedAuthHeaders = await resolveCodeApiAuthHeaders(authHeaders);
297
- const fetchOptions = {
298
- method: 'GET',
299
- headers: {
300
- 'User-Agent': 'LibreChat/1.0',
301
- ...resolvedAuthHeaders,
302
- },
303
- };
304
- if (proxy != null && proxy !== '') {
305
- fetchOptions.agent = new HttpsProxyAgent(proxy);
306
- }
307
- const response = await fetch(filesEndpoint, fetchOptions);
308
- if (!response.ok) {
309
- throw new Error(await buildCodeApiHttpErrorMessage('GET', filesEndpoint, response));
310
- }
311
- const files = await response.json();
312
- if (!Array.isArray(files) || files.length === 0) {
313
- return [];
314
- }
315
- return files
316
- .filter(isCodeApiSessionFileWire)
317
- .map((file) => normalizeSessionFile(file, sessionId, scope));
318
- }
319
- catch (error) {
320
- // eslint-disable-next-line no-console
321
- console.warn(`Failed to fetch files for session: ${sessionId}, ${error.message}`);
322
- return [];
323
- }
228
+ try {
229
+ const scope = isFetchSessionFilesScope(scopeOrProxy) ? scopeOrProxy : void 0;
230
+ let proxy;
231
+ let authHeaders;
232
+ if (scope == null) {
233
+ proxy = typeof scopeOrProxy === "string" ? scopeOrProxy : void 0;
234
+ authHeaders = isCodeApiAuthHeaders(proxyOrAuthHeaders) ? proxyOrAuthHeaders : void 0;
235
+ } else if (typeof proxyOrAuthHeaders === "string") {
236
+ proxy = proxyOrAuthHeaders;
237
+ authHeaders = scopedAuthHeaders;
238
+ } else authHeaders = proxyOrAuthHeaders ?? scopedAuthHeaders;
239
+ const query = new URLSearchParams({ detail: "full" });
240
+ if (scope != null) {
241
+ query.set("kind", scope.kind);
242
+ query.set("id", scope.id);
243
+ if (scope.kind === "skill") query.set("version", String(scope.version));
244
+ }
245
+ const filesEndpoint = `${baseUrl}/files/${encodeURIComponent(sessionId)}?${query.toString()}`;
246
+ const fetchOptions = {
247
+ method: "GET",
248
+ headers: {
249
+ "User-Agent": "LibreChat/1.0",
250
+ ...await resolveCodeApiAuthHeaders(authHeaders)
251
+ }
252
+ };
253
+ if (proxy != null && proxy !== "") fetchOptions.agent = new HttpsProxyAgent(proxy);
254
+ const response = await fetch(filesEndpoint, fetchOptions);
255
+ if (!response.ok) throw new Error(await buildCodeApiHttpErrorMessage("GET", filesEndpoint, response));
256
+ const files = await response.json();
257
+ if (!Array.isArray(files) || files.length === 0) return [];
258
+ return files.filter(isCodeApiSessionFileWire).map((file) => normalizeSessionFile(file, sessionId, scope));
259
+ } catch (error) {
260
+ console.warn(`Failed to fetch files for session: ${sessionId}, ${error.message}`);
261
+ return [];
262
+ }
324
263
  }
325
264
  /**
326
- * Makes an HTTP request to the Code API.
327
- * @param endpoint - The API endpoint URL
328
- * @param body - The request body
329
- * @param proxy - Optional HTTP proxy URL
330
- * @returns The parsed API response
331
- */
265
+ * Makes an HTTP request to the Code API.
266
+ * @param endpoint - The API endpoint URL
267
+ * @param body - The request body
268
+ * @param proxy - Optional HTTP proxy URL
269
+ * @returns The parsed API response
270
+ */
332
271
  async function makeRequest(endpoint, body, proxy, authHeaders) {
333
- const resolvedAuthHeaders = await resolveCodeApiAuthHeaders(authHeaders);
334
- const fetchOptions = {
335
- method: 'POST',
336
- headers: {
337
- 'Content-Type': 'application/json',
338
- 'User-Agent': 'LibreChat/1.0',
339
- ...resolvedAuthHeaders,
340
- },
341
- body: JSON.stringify(body),
342
- };
343
- if (proxy != null && proxy !== '') {
344
- fetchOptions.agent = new HttpsProxyAgent(proxy);
345
- }
346
- const response = await fetch(endpoint, fetchOptions);
347
- if (!response.ok) {
348
- throw new Error(await buildCodeApiHttpErrorMessage('POST', endpoint, response));
349
- }
350
- return (await response.json());
272
+ const fetchOptions = {
273
+ method: "POST",
274
+ headers: {
275
+ "Content-Type": "application/json",
276
+ "User-Agent": "LibreChat/1.0",
277
+ ...await resolveCodeApiAuthHeaders(authHeaders)
278
+ },
279
+ body: JSON.stringify(body)
280
+ };
281
+ if (proxy != null && proxy !== "") fetchOptions.agent = new HttpsProxyAgent(proxy);
282
+ const response = await fetch(endpoint, fetchOptions);
283
+ if (!response.ok) throw new Error(await buildCodeApiHttpErrorMessage("POST", endpoint, response));
284
+ return await response.json();
351
285
  }
352
286
  /**
353
- * Unwraps tool responses that may be formatted as tuples or content blocks.
354
- * MCP tools return [content, artifacts], we need to extract the raw data.
355
- * @param result - The raw result from tool.invoke()
356
- * @param isMCPTool - Whether this is an MCP tool (has mcp property)
357
- * @returns Unwrapped raw data (string, object, or parsed JSON)
358
- */
287
+ * Unwraps tool responses that may be formatted as tuples or content blocks.
288
+ * MCP tools return [content, artifacts], we need to extract the raw data.
289
+ * @param result - The raw result from tool.invoke()
290
+ * @param isMCPTool - Whether this is an MCP tool (has mcp property)
291
+ * @returns Unwrapped raw data (string, object, or parsed JSON)
292
+ */
359
293
  function unwrapToolResponse(result, isMCPTool) {
360
- // Only unwrap if this is an MCP tool and result is a tuple
361
- if (!isMCPTool) {
362
- return result;
363
- }
364
- /**
365
- * Checks if a value is a content block object (has type and text).
366
- */
367
- const isContentBlock = (value) => {
368
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
369
- return false;
370
- }
371
- const obj = value;
372
- return typeof obj.type === 'string';
373
- };
374
- /**
375
- * Checks if an array is an array of content blocks.
376
- */
377
- const isContentBlockArray = (arr) => {
378
- return arr.length > 0 && arr.every(isContentBlock);
379
- };
380
- /**
381
- * Extracts text from a single content block object.
382
- * Returns the text if it's a text block, otherwise returns null.
383
- */
384
- const extractTextFromBlock = (block) => {
385
- if (typeof block !== 'object' || block === null)
386
- return null;
387
- const b = block;
388
- if (b.type === 'text' && typeof b.text === 'string') {
389
- return b.text;
390
- }
391
- return null;
392
- };
393
- /**
394
- * Extracts text from content blocks (array or single object).
395
- * Returns combined text or null if no text blocks found.
396
- */
397
- const extractTextFromContent = (content) => {
398
- // Single content block object: { type: 'text', text: '...' }
399
- if (typeof content === 'object' &&
400
- content !== null &&
401
- !Array.isArray(content)) {
402
- const text = extractTextFromBlock(content);
403
- if (text !== null)
404
- return text;
405
- }
406
- // Array of content blocks: [{ type: 'text', text: '...' }, ...]
407
- if (Array.isArray(content) && content.length > 0) {
408
- const texts = content
409
- .map(extractTextFromBlock)
410
- .filter((t) => t !== null);
411
- if (texts.length > 0) {
412
- return texts.join('\n');
413
- }
414
- }
415
- return null;
416
- };
417
- /**
418
- * Tries to parse a string as JSON if it looks like JSON.
419
- */
420
- const maybeParseJSON = (str) => {
421
- const trimmed = str.trim();
422
- if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
423
- try {
424
- return JSON.parse(trimmed);
425
- }
426
- catch {
427
- return str;
428
- }
429
- }
430
- return str;
431
- };
432
- // Handle array of content blocks at top level FIRST
433
- // (before checking for tuple, since both are arrays)
434
- if (Array.isArray(result) && isContentBlockArray(result)) {
435
- const extractedText = extractTextFromContent(result);
436
- if (extractedText !== null) {
437
- return maybeParseJSON(extractedText);
438
- }
439
- }
440
- // Check if result is a tuple/array with [content, artifacts]
441
- if (Array.isArray(result) && result.length >= 1) {
442
- const [content] = result;
443
- // If first element is a string, return it (possibly parsed as JSON)
444
- if (typeof content === 'string') {
445
- return maybeParseJSON(content);
446
- }
447
- // Try to extract text from content blocks
448
- const extractedText = extractTextFromContent(content);
449
- if (extractedText !== null) {
450
- return maybeParseJSON(extractedText);
451
- }
452
- // If first element is an object (but not a text block), return it
453
- if (typeof content === 'object' && content !== null) {
454
- return content;
455
- }
456
- }
457
- // Handle single content block object at top level (not in tuple)
458
- const extractedText = extractTextFromContent(result);
459
- if (extractedText !== null) {
460
- return maybeParseJSON(extractedText);
461
- }
462
- // Not a formatted response, return as-is
463
- return result;
294
+ if (!isMCPTool) return result;
295
+ /**
296
+ * Checks if a value is a content block object (has type and text).
297
+ */
298
+ const isContentBlock = (value) => {
299
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
300
+ return typeof value.type === "string";
301
+ };
302
+ /**
303
+ * Checks if an array is an array of content blocks.
304
+ */
305
+ const isContentBlockArray = (arr) => {
306
+ return arr.length > 0 && arr.every(isContentBlock);
307
+ };
308
+ /**
309
+ * Extracts text from a single content block object.
310
+ * Returns the text if it's a text block, otherwise returns null.
311
+ */
312
+ const extractTextFromBlock = (block) => {
313
+ if (typeof block !== "object" || block === null) return null;
314
+ const b = block;
315
+ if (b.type === "text" && typeof b.text === "string") return b.text;
316
+ return null;
317
+ };
318
+ /**
319
+ * Extracts text from content blocks (array or single object).
320
+ * Returns combined text or null if no text blocks found.
321
+ */
322
+ const extractTextFromContent = (content) => {
323
+ if (typeof content === "object" && content !== null && !Array.isArray(content)) {
324
+ const text = extractTextFromBlock(content);
325
+ if (text !== null) return text;
326
+ }
327
+ if (Array.isArray(content) && content.length > 0) {
328
+ const texts = content.map(extractTextFromBlock).filter((t) => t !== null);
329
+ if (texts.length > 0) return texts.join("\n");
330
+ }
331
+ return null;
332
+ };
333
+ /**
334
+ * Tries to parse a string as JSON if it looks like JSON.
335
+ */
336
+ const maybeParseJSON = (str) => {
337
+ const trimmed = str.trim();
338
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) try {
339
+ return JSON.parse(trimmed);
340
+ } catch {
341
+ return str;
342
+ }
343
+ return str;
344
+ };
345
+ if (Array.isArray(result) && isContentBlockArray(result)) {
346
+ const extractedText = extractTextFromContent(result);
347
+ if (extractedText !== null) return maybeParseJSON(extractedText);
348
+ }
349
+ if (Array.isArray(result) && result.length >= 1) {
350
+ const [content] = result;
351
+ if (typeof content === "string") return maybeParseJSON(content);
352
+ const extractedText = extractTextFromContent(content);
353
+ if (extractedText !== null) return maybeParseJSON(extractedText);
354
+ if (typeof content === "object" && content !== null) return content;
355
+ }
356
+ const extractedText = extractTextFromContent(result);
357
+ if (extractedText !== null) return maybeParseJSON(extractedText);
358
+ return result;
464
359
  }
465
360
  function detectSchemaKind(schema) {
466
- const kind = { object: false, string: false };
467
- if (!schema || typeof schema !== 'object') {
468
- return kind;
469
- }
470
- const jsonSchemaType = schema.type;
471
- if (jsonSchemaType === 'object') {
472
- kind.object = true;
473
- }
474
- else if (jsonSchemaType === 'string') {
475
- kind.string = true;
476
- }
477
- else if (Array.isArray(jsonSchemaType)) {
478
- kind.object = jsonSchemaType.includes('object');
479
- kind.string = jsonSchemaType.includes('string');
480
- }
481
- const zodDef = schema._def;
482
- if (!zodDef || typeof zodDef !== 'object') {
483
- return kind;
484
- }
485
- const zodType = zodDef.type;
486
- const zodTypeName = zodDef
487
- .typeName;
488
- if (zodType === 'object' || zodTypeName === 'ZodObject') {
489
- kind.object = true;
490
- }
491
- else if (zodType === 'string' || zodTypeName === 'ZodString') {
492
- kind.string = true;
493
- }
494
- const innerSchema = zodDef.innerType ?? zodDef.schema;
495
- if (innerSchema) {
496
- const innerKind = detectSchemaKind(innerSchema);
497
- kind.object ||= innerKind.object;
498
- kind.string ||= innerKind.string;
499
- }
500
- const options = zodDef.options;
501
- if (Array.isArray(options)) {
502
- for (const option of options) {
503
- const optionKind = detectSchemaKind(option);
504
- kind.object ||= optionKind.object;
505
- kind.string ||= optionKind.string;
506
- }
507
- }
508
- return kind;
361
+ const kind = {
362
+ object: false,
363
+ string: false
364
+ };
365
+ if (!schema || typeof schema !== "object") return kind;
366
+ const jsonSchemaType = schema.type;
367
+ if (jsonSchemaType === "object") kind.object = true;
368
+ else if (jsonSchemaType === "string") kind.string = true;
369
+ else if (Array.isArray(jsonSchemaType)) {
370
+ kind.object = jsonSchemaType.includes("object");
371
+ kind.string = jsonSchemaType.includes("string");
372
+ }
373
+ const zodDef = schema._def;
374
+ if (!zodDef || typeof zodDef !== "object") return kind;
375
+ const zodType = zodDef.type;
376
+ const zodTypeName = zodDef.typeName;
377
+ if (zodType === "object" || zodTypeName === "ZodObject") kind.object = true;
378
+ else if (zodType === "string" || zodTypeName === "ZodString") kind.string = true;
379
+ const innerSchema = zodDef.innerType ?? zodDef.schema;
380
+ if (innerSchema) {
381
+ const innerKind = detectSchemaKind(innerSchema);
382
+ kind.object ||= innerKind.object;
383
+ kind.string ||= innerKind.string;
384
+ }
385
+ const options = zodDef.options;
386
+ if (Array.isArray(options)) for (const option of options) {
387
+ const optionKind = detectSchemaKind(option);
388
+ kind.object ||= optionKind.object;
389
+ kind.string ||= optionKind.string;
390
+ }
391
+ return kind;
509
392
  }
510
393
  function getToolInputSchemaKind(tool) {
511
- if (tool.constructor.name === 'DynamicTool') {
512
- return { object: false, string: true };
513
- }
514
- const schema = tool.schema;
515
- return detectSchemaKind(schema);
394
+ if (tool.constructor.name === "DynamicTool") return {
395
+ object: false,
396
+ string: true
397
+ };
398
+ const schema = tool.schema;
399
+ return detectSchemaKind(schema);
516
400
  }
517
401
  function normalizeToolInput(input, tool) {
518
- const schemaKind = getToolInputSchemaKind(tool);
519
- if (typeof input !== 'string') {
520
- if (!schemaKind.string || schemaKind.object) {
521
- return input;
522
- }
523
- const inputValue = input.input;
524
- if (typeof inputValue === 'string') {
525
- return input;
526
- }
527
- return JSON.stringify(input);
528
- }
529
- if (!schemaKind.object || schemaKind.string) {
530
- return input;
531
- }
532
- const trimmed = input.trim();
533
- if (!trimmed.startsWith('{')) {
534
- return input;
535
- }
536
- try {
537
- const parsed = JSON.parse(trimmed);
538
- if (typeof parsed === 'object' &&
539
- parsed !== null &&
540
- !Array.isArray(parsed)) {
541
- return parsed;
542
- }
543
- }
544
- catch {
545
- return input;
546
- }
547
- return input;
402
+ const schemaKind = getToolInputSchemaKind(tool);
403
+ if (typeof input !== "string") {
404
+ if (!schemaKind.string || schemaKind.object) return input;
405
+ if (typeof input.input === "string") return input;
406
+ return JSON.stringify(input);
407
+ }
408
+ if (!schemaKind.object || schemaKind.string) return input;
409
+ const trimmed = input.trim();
410
+ if (!trimmed.startsWith("{")) return input;
411
+ try {
412
+ const parsed = JSON.parse(trimmed);
413
+ if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) return parsed;
414
+ } catch {
415
+ return input;
416
+ }
417
+ return input;
548
418
  }
549
419
  /**
550
- * Executes tools in parallel when requested by the API.
551
- * Uses Promise.all for parallel execution, catching individual errors.
552
- * Unwraps formatted responses (e.g., MCP tool tuples) to raw data.
553
- * @param toolCalls - Array of tool calls from the API
554
- * @param toolMap - Map of tool names to executable tools
555
- * @returns Array of tool results
556
- */
557
- async function executeTools(toolCalls, toolMap, programmaticToolName = Constants.PROGRAMMATIC_TOOL_CALLING) {
558
- const executions = toolCalls.map(async (call) => {
559
- const tool = toolMap.get(call.name);
560
- if (!tool) {
561
- return {
562
- call_id: call.id,
563
- result: null,
564
- is_error: true,
565
- error_message: `Tool '${call.name}' not found. Available tools: ${Array.from(toolMap.keys()).join(', ')}`,
566
- };
567
- }
568
- try {
569
- const result = await tool.invoke(normalizeToolInput(call.input, tool), {
570
- metadata: { [programmaticToolName]: true },
571
- });
572
- const isMCPTool = tool.mcp === true;
573
- const unwrappedResult = unwrapToolResponse(result, isMCPTool);
574
- return {
575
- call_id: call.id,
576
- result: unwrappedResult,
577
- is_error: false,
578
- };
579
- }
580
- catch (error) {
581
- return {
582
- call_id: call.id,
583
- result: null,
584
- is_error: true,
585
- error_message: error.message || 'Tool execution failed',
586
- };
587
- }
588
- });
589
- return await Promise.all(executions);
420
+ * Executes tools in parallel when requested by the API.
421
+ * Uses Promise.all for parallel execution, catching individual errors.
422
+ * Unwraps formatted responses (e.g., MCP tool tuples) to raw data.
423
+ * @param toolCalls - Array of tool calls from the API
424
+ * @param toolMap - Map of tool names to executable tools
425
+ * @returns Array of tool results
426
+ */
427
+ async function executeTools(toolCalls, toolMap, programmaticToolName = "run_tools_with_code") {
428
+ const executions = toolCalls.map(async (call) => {
429
+ const tool = toolMap.get(call.name);
430
+ if (!tool) return {
431
+ call_id: call.id,
432
+ result: null,
433
+ is_error: true,
434
+ error_message: `Tool '${call.name}' not found. Available tools: ${Array.from(toolMap.keys()).join(", ")}`
435
+ };
436
+ try {
437
+ const unwrappedResult = unwrapToolResponse(await tool.invoke(normalizeToolInput(call.input, tool), { metadata: { [programmaticToolName]: true } }), tool.mcp === true);
438
+ return {
439
+ call_id: call.id,
440
+ result: unwrappedResult,
441
+ is_error: false
442
+ };
443
+ } catch (error) {
444
+ return {
445
+ call_id: call.id,
446
+ result: null,
447
+ is_error: true,
448
+ error_message: error.message || "Tool execution failed"
449
+ };
450
+ }
451
+ });
452
+ return await Promise.all(executions);
590
453
  }
591
454
  /**
592
- * Formats the completed response for the agent.
593
- *
594
- * Output includes stdout/stderr plus a compact session-file summary
595
- * when artifacts were persisted. The artifact still carries every
596
- * file so the host's session map stays in sync.
597
- *
598
- * @param response - The completed API response
599
- * @returns Tuple of [formatted string, artifact]
600
- */
601
- function formatCompletedResponse(response, sourceCode = '') {
602
- let formatted = '';
603
- if (response.stdout != null && response.stdout !== '') {
604
- formatted += `stdout:\n${response.stdout}\n`;
605
- }
606
- else {
607
- formatted += emptyOutputMessage;
608
- }
609
- if (response.stderr != null && response.stderr !== '') {
610
- formatted += `stderr:\n${response.stderr}\n`;
611
- }
612
- const outputWithReminder = appendTmpScratchReminder(formatted, sourceCode);
613
- return [
614
- appendCodeSessionFileSummary(outputWithReminder, response.files),
615
- {
616
- session_id: response.session_id,
617
- files: response.files,
618
- },
619
- ];
455
+ * Formats the completed response for the agent.
456
+ *
457
+ * Output includes stdout/stderr plus a compact session-file summary
458
+ * when artifacts were persisted. The artifact still carries every
459
+ * file so the host's session map stays in sync.
460
+ *
461
+ * @param response - The completed API response
462
+ * @returns Tuple of [formatted string, artifact]
463
+ */
464
+ function formatCompletedResponse(response, sourceCode = "") {
465
+ let formatted = "";
466
+ if (response.stdout != null && response.stdout !== "") formatted += `stdout:\n${response.stdout}\n`;
467
+ else formatted += emptyOutputMessage;
468
+ if (response.stderr != null && response.stderr !== "") formatted += `stderr:\n${response.stderr}\n`;
469
+ return [appendCodeSessionFileSummary(appendTmpScratchReminder(formatted, sourceCode), response.files), {
470
+ session_id: response.session_id,
471
+ files: response.files
472
+ }];
620
473
  }
621
- // ============================================================================
622
- // Tool Factory
623
- // ============================================================================
624
474
  /**
625
- * Creates a Programmatic Tool Calling tool for complex multi-tool workflows.
626
- *
627
- * This tool enables AI agents to write Python code that orchestrates multiple
628
- * tool calls programmatically, reducing LLM round-trips and token usage.
629
- *
630
- * The tool map must be provided at runtime via config.configurable.toolMap.
631
- *
632
- * @param params - Configuration parameters (baseUrl, maxRoundTrips, proxy)
633
- * @returns A LangChain DynamicStructuredTool for programmatic tool calling
634
- *
635
- * @example
636
- * const ptcTool = createProgrammaticToolCallingTool({ maxRoundTrips: 20 });
637
- *
638
- * const [output, artifact] = await ptcTool.invoke(
639
- * { code, tools },
640
- * { configurable: { toolMap } }
641
- * );
642
- */
475
+ * Creates a Programmatic Tool Calling tool for complex multi-tool workflows.
476
+ *
477
+ * This tool enables AI agents to write Python code that orchestrates multiple
478
+ * tool calls programmatically, reducing LLM round-trips and token usage.
479
+ *
480
+ * The tool map must be provided at runtime via config.configurable.toolMap.
481
+ *
482
+ * @param params - Configuration parameters (baseUrl, maxRoundTrips, proxy)
483
+ * @returns A LangChain DynamicStructuredTool for programmatic tool calling
484
+ *
485
+ * @example
486
+ * const ptcTool = createProgrammaticToolCallingTool({ maxRoundTrips: 20 });
487
+ *
488
+ * const [output, artifact] = await ptcTool.invoke(
489
+ * { code, tools },
490
+ * { configurable: { toolMap } }
491
+ * );
492
+ */
643
493
  function createProgrammaticToolCallingTool(initParams = {}) {
644
- const baseUrl = initParams.baseUrl ?? getCodeBaseURL();
645
- const maxRoundTrips = initParams.maxRoundTrips ?? DEFAULT_MAX_ROUND_TRIPS;
646
- const maxRunTimeoutMs = resolveCodeApiRunTimeoutMs(initParams.runTimeoutMs);
647
- const proxy = initParams.proxy ?? process.env.PROXY;
648
- const debug = initParams.debug ?? process.env.PTC_DEBUG === 'true';
649
- const EXEC_ENDPOINT = `${baseUrl}/exec/programmatic`;
650
- return tool(async (rawParams, config) => {
651
- const params = rawParams;
652
- const { code } = params;
653
- const timeout = clampCodeApiRunTimeoutMs(params.timeout, maxRunTimeoutMs);
654
- // Extra params injected by ToolNode (follows web_search pattern).
655
- const toolCall = (config.toolCall ?? {});
656
- const { toolMap, toolDefs, session_id, _injected_files } = toolCall;
657
- if (toolMap == null || toolMap.size === 0) {
658
- throw new Error('No toolMap provided. ' +
659
- 'ToolNode should inject this from AgentContext when invoked through the graph.');
660
- }
661
- if (toolDefs == null || toolDefs.length === 0) {
662
- throw new Error('No tool definitions provided. ' +
663
- 'Either pass tools in the input or ensure ToolNode injects toolDefs.');
664
- }
665
- let roundTrip = 0;
666
- try {
667
- // ====================================================================
668
- // Phase 1: Filter tools and make initial request
669
- // ====================================================================
670
- const effectiveTools = filterToolsByUsage(toolDefs, code, debug);
671
- if (debug) {
672
- // eslint-disable-next-line no-console
673
- console.log(`[PTC Debug] Sending ${effectiveTools.length} tools to API ` +
674
- `(filtered from ${toolDefs.length})`);
675
- }
676
- /**
677
- * File injection: `_injected_files` from ToolNode session
678
- * context. The legacy `/files/<session_id>` HTTP fallback was
679
- * removed (see `CodeExecutor.ts`) codeapi's sessionAuth now
680
- * requires kind/id query params unavailable at this point.
681
- */
682
- let files;
683
- if (_injected_files && _injected_files.length > 0) {
684
- files = _injected_files;
685
- }
686
- else if (session_id != null && session_id.length > 0) {
687
- // eslint-disable-next-line no-console
688
- console.debug(`[ProgrammaticToolCalling] No injected files for session_id=${session_id} exec will run without input files`);
689
- }
690
- let response = await makeRequest(EXEC_ENDPOINT, {
691
- code,
692
- tools: effectiveTools,
693
- session_id,
694
- timeout,
695
- ...(files && files.length > 0 ? { files } : {}),
696
- }, proxy, initParams.authHeaders);
697
- // ====================================================================
698
- // Phase 2: Handle response loop
699
- // ====================================================================
700
- while (response.status === 'tool_call_required') {
701
- roundTrip++;
702
- if (roundTrip > maxRoundTrips) {
703
- throw new Error(`Exceeded maximum round trips (${maxRoundTrips}). ` +
704
- 'This may indicate an infinite loop, excessive tool calls, ' +
705
- 'or a logic error in your code.');
706
- }
707
- if (debug) {
708
- // eslint-disable-next-line no-console
709
- console.log(`[PTC Debug] Round trip ${roundTrip}: ${response.tool_calls?.length ?? 0} tool(s) to execute`);
710
- }
711
- const toolResults = await executeTools(response.tool_calls ?? [], toolMap);
712
- response = await makeRequest(EXEC_ENDPOINT, {
713
- continuation_token: response.continuation_token,
714
- tool_results: toolResults,
715
- }, proxy, initParams.authHeaders);
716
- }
717
- // ====================================================================
718
- // Phase 3: Handle final state
719
- // ====================================================================
720
- if (response.status === 'completed') {
721
- return formatCompletedResponse(response, code);
722
- }
723
- if (response.status === 'error') {
724
- throw new Error(`Execution error: ${response.error}` +
725
- (response.stderr != null && response.stderr !== ''
726
- ? `\n\nStderr:\n${response.stderr}`
727
- : ''));
728
- }
729
- throw new Error(`Unexpected response status: ${response.status}`);
730
- }
731
- catch (error) {
732
- const messageWithReminder = appendFailedExecutionFileReminder(error.message, code);
733
- throw new Error(`Programmatic execution failed: ${messageWithReminder}`);
734
- }
735
- }, {
736
- name: Constants.PROGRAMMATIC_TOOL_CALLING,
737
- description: ProgrammaticToolCallingDescription,
738
- schema: createProgrammaticToolCallingSchema(maxRunTimeoutMs),
739
- responseFormat: Constants.CONTENT_AND_ARTIFACT,
740
- });
494
+ const baseUrl = initParams.baseUrl ?? getCodeBaseURL();
495
+ const maxRoundTrips = initParams.maxRoundTrips ?? DEFAULT_MAX_ROUND_TRIPS;
496
+ const maxRunTimeoutMs = resolveCodeApiRunTimeoutMs(initParams.runTimeoutMs);
497
+ const proxy = initParams.proxy ?? process.env.PROXY;
498
+ const debug = initParams.debug ?? process.env.PTC_DEBUG === "true";
499
+ const EXEC_ENDPOINT = `${baseUrl}/exec/programmatic`;
500
+ return tool(async (rawParams, config) => {
501
+ const params = rawParams;
502
+ const { code } = params;
503
+ const timeout = clampCodeApiRunTimeoutMs(params.timeout, maxRunTimeoutMs);
504
+ const { toolMap, toolDefs, session_id, _injected_files } = config.toolCall ?? {};
505
+ if (toolMap == null || toolMap.size === 0) throw new Error("No toolMap provided. ToolNode should inject this from AgentContext when invoked through the graph.");
506
+ if (toolDefs == null || toolDefs.length === 0) throw new Error("No tool definitions provided. Either pass tools in the input or ensure ToolNode injects toolDefs.");
507
+ let roundTrip = 0;
508
+ try {
509
+ const effectiveTools = filterToolsByUsage(toolDefs, code, debug);
510
+ if (debug) console.log(`[PTC Debug] Sending ${effectiveTools.length} tools to API (filtered from ${toolDefs.length})`);
511
+ /**
512
+ * File injection: `_injected_files` from ToolNode session
513
+ * context. The legacy `/files/<session_id>` HTTP fallback was
514
+ * removed (see `CodeExecutor.ts`) — codeapi's sessionAuth now
515
+ * requires kind/id query params unavailable at this point.
516
+ */
517
+ let files;
518
+ if (_injected_files && _injected_files.length > 0) files = _injected_files;
519
+ else if (session_id != null && session_id.length > 0) console.debug(`[ProgrammaticToolCalling] No injected files for session_id=${session_id} — exec will run without input files`);
520
+ let response = await makeRequest(EXEC_ENDPOINT, {
521
+ code,
522
+ tools: effectiveTools,
523
+ session_id,
524
+ timeout,
525
+ ...files && files.length > 0 ? { files } : {}
526
+ }, proxy, initParams.authHeaders);
527
+ while (response.status === "tool_call_required") {
528
+ roundTrip++;
529
+ if (roundTrip > maxRoundTrips) throw new Error(`Exceeded maximum round trips (${maxRoundTrips}). This may indicate an infinite loop, excessive tool calls, or a logic error in your code.`);
530
+ if (debug) console.log(`[PTC Debug] Round trip ${roundTrip}: ${response.tool_calls?.length ?? 0} tool(s) to execute`);
531
+ const toolResults = await executeTools(response.tool_calls ?? [], toolMap);
532
+ response = await makeRequest(EXEC_ENDPOINT, {
533
+ continuation_token: response.continuation_token,
534
+ tool_results: toolResults
535
+ }, proxy, initParams.authHeaders);
536
+ }
537
+ if (response.status === "completed") return formatCompletedResponse(response, code);
538
+ if (response.status === "error") throw new Error(`Execution error: ${response.error}` + (response.stderr != null && response.stderr !== "" ? `\n\nStderr:\n${response.stderr}` : ""));
539
+ throw new Error(`Unexpected response status: ${response.status}`);
540
+ } catch (error) {
541
+ const messageWithReminder = appendFailedExecutionFileReminder(error.message, code);
542
+ throw new Error(`Programmatic execution failed: ${messageWithReminder}`);
543
+ }
544
+ }, {
545
+ name: "run_tools_with_code",
546
+ description: ProgrammaticToolCallingDescription,
547
+ schema: createProgrammaticToolCallingSchema(maxRunTimeoutMs),
548
+ responseFormat: "content_and_artifact"
549
+ });
741
550
  }
742
-
551
+ //#endregion
743
552
  export { ProgrammaticToolCallingDefinition, ProgrammaticToolCallingDescription, ProgrammaticToolCallingName, ProgrammaticToolCallingSchema, createProgrammaticToolCallingSchema, createProgrammaticToolCallingTool, executeTools, extractUsedToolNames, fetchSessionFiles, filterToolsByUsage, formatCompletedResponse, makeRequest, normalizeToPythonIdentifier, unwrapToolResponse };
744
- //# sourceMappingURL=ProgrammaticToolCalling.mjs.map
553
+
554
+ //# sourceMappingURL=ProgrammaticToolCalling.mjs.map