@librechat/agents 3.2.31 → 3.2.33

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 (582) 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 -696
  53. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  54. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +171 -252
  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 +195 -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 +105 -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 +398 -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 +991 -1276
  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 +427 -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 +308 -401
  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 -1382
  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 +856 -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 +2109 -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 +19 -36
  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 -690
  324. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  325. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +171 -249
  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 +195 -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 +105 -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 +397 -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 +991 -1271
  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 +427 -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 +308 -399
  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 -1378
  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 +854 -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 +2107 -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 +19 -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/messages/format.d.ts +5 -0
  545. package/dist/types/tools/search/tool.d.ts +17 -0
  546. package/dist/types/tools/search/types.d.ts +4 -0
  547. package/package.json +11 -17
  548. package/src/llm/anthropic/llm.spec.ts +36 -0
  549. package/src/llm/anthropic/utils/message_inputs.ts +45 -3
  550. package/src/llm/anthropic/utils/message_outputs.ts +6 -2
  551. package/src/llm/anthropic/utils/streaming-tool-input.test.ts +186 -0
  552. package/src/messages/cache.test.ts +122 -0
  553. package/src/messages/cache.ts +25 -1
  554. package/src/messages/format.ts +9 -0
  555. package/src/messages/formatAgentMessages.skills.test.ts +100 -0
  556. package/src/tools/search/highlights.ts +9 -1
  557. package/src/tools/search/search.ts +41 -3
  558. package/src/tools/search/source-processing.test.ts +373 -0
  559. package/src/tools/search/tool.ts +22 -2
  560. package/src/tools/search/types.ts +4 -0
  561. package/dist/cjs/langchain/google-common.cjs.map +0 -1
  562. package/dist/cjs/langchain/index.cjs.map +0 -1
  563. package/dist/cjs/langchain/language_models/chat_models.cjs.map +0 -1
  564. package/dist/cjs/langchain/messages/tool.cjs.map +0 -1
  565. package/dist/cjs/langchain/messages.cjs.map +0 -1
  566. package/dist/cjs/langchain/openai.cjs.map +0 -1
  567. package/dist/cjs/langchain/prompts.cjs.map +0 -1
  568. package/dist/cjs/langchain/runnables.cjs.map +0 -1
  569. package/dist/cjs/langchain/tools.cjs.map +0 -1
  570. package/dist/cjs/langchain/utils/env.cjs.map +0 -1
  571. package/dist/cjs/main.cjs.map +0 -1
  572. package/dist/esm/langchain/google-common.mjs.map +0 -1
  573. package/dist/esm/langchain/index.mjs.map +0 -1
  574. package/dist/esm/langchain/language_models/chat_models.mjs.map +0 -1
  575. package/dist/esm/langchain/messages/tool.mjs.map +0 -1
  576. package/dist/esm/langchain/messages.mjs.map +0 -1
  577. package/dist/esm/langchain/openai.mjs.map +0 -1
  578. package/dist/esm/langchain/prompts.mjs.map +0 -1
  579. package/dist/esm/langchain/runnables.mjs.map +0 -1
  580. package/dist/esm/langchain/tools.mjs.map +0 -1
  581. package/dist/esm/langchain/utils/env.mjs.map +0 -1
  582. package/dist/esm/main.mjs.map +0 -1
@@ -0,0 +1,186 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { AIMessage, HumanMessage } from '@langchain/core/messages';
3
+ import type { BaseMessage } from '@langchain/core/messages';
4
+ import { _convertMessagesToAnthropicPayload } from './message_inputs';
5
+ import { _makeMessageChunkFromAnthropicEvent } from './message_outputs';
6
+
7
+ /**
8
+ * Regression for @langchain/core >= 1.1.46 streaming aggregation: a tool call's
9
+ * input_json_delta is kept as a separate content block and v1-cast to a `text`
10
+ * block carrying `input` but no `text`, leaving the sibling tool_use block with an
11
+ * empty inline input. The assembled arguments live on `message.tool_calls`.
12
+ * Re-serializing such a message previously threw "Unsupported message content format".
13
+ */
14
+ describe('_convertMessagesToAnthropicPayload — aggregated streaming tool input', () => {
15
+ const buildHistory = (): BaseMessage[] => [
16
+ new HumanMessage('what is 12345 * 6789?'),
17
+ new AIMessage({
18
+ content: [
19
+ { type: 'text', text: 'Let me calculate that.' },
20
+ // tool_use block left with empty inline input by aggregation
21
+ {
22
+ type: 'tool_use',
23
+ id: 'toolu_calc',
24
+ name: 'calculator',
25
+ input: '',
26
+ index: 0,
27
+ } as any,
28
+ // orphaned input delta, v1-cast to `text` with `input` and no `text`
29
+ { type: 'text', index: 0, input: '{"input": "12345 * 6789"}' } as any,
30
+ ],
31
+ tool_calls: [
32
+ {
33
+ id: 'toolu_calc',
34
+ name: 'calculator',
35
+ args: { input: '12345 * 6789' },
36
+ type: 'tool_call',
37
+ },
38
+ ],
39
+ }),
40
+ ];
41
+
42
+ it('does not throw on the orphaned text-with-input block', () => {
43
+ expect(() => _convertMessagesToAnthropicPayload(buildHistory())).not.toThrow();
44
+ });
45
+
46
+ it('restores tool_use input from message.tool_calls and drops the orphan block', () => {
47
+ const payload = _convertMessagesToAnthropicPayload(buildHistory());
48
+ const assistant = payload.messages.find((m: any) => m.role === 'assistant');
49
+ expect(assistant).toBeDefined();
50
+ const blocks = assistant!.content as any[];
51
+
52
+ const toolUse = blocks.find((b) => b.type === 'tool_use');
53
+ expect(toolUse).toMatchObject({
54
+ type: 'tool_use',
55
+ id: 'toolu_calc',
56
+ name: 'calculator',
57
+ input: { input: '12345 * 6789' },
58
+ });
59
+
60
+ // No leftover delta: no text block carrying `input`, no input_json_delta.
61
+ expect(
62
+ blocks.find(
63
+ (b) => (b.type === 'text' && 'input' in b) || b.type === 'input_json_delta'
64
+ )
65
+ ).toBeUndefined();
66
+
67
+ // The real assistant text is preserved.
68
+ expect(
69
+ blocks.some((b) => b.type === 'text' && b.text === 'Let me calculate that.')
70
+ ).toBe(true);
71
+ });
72
+
73
+ it('does not overwrite a tool_use block that already has inline input', () => {
74
+ const history: BaseMessage[] = [
75
+ new HumanMessage('hi'),
76
+ new AIMessage({
77
+ content: [
78
+ {
79
+ type: 'tool_use',
80
+ id: 'toolu_x',
81
+ name: 'calculator',
82
+ input: { input: '2 + 2' },
83
+ } as any,
84
+ ],
85
+ tool_calls: [
86
+ {
87
+ id: 'toolu_x',
88
+ name: 'calculator',
89
+ args: { input: '999' },
90
+ type: 'tool_call',
91
+ },
92
+ ],
93
+ }),
94
+ ];
95
+ const payload = _convertMessagesToAnthropicPayload(history);
96
+ const assistant = payload.messages.find((m: any) => m.role === 'assistant');
97
+ const toolUse = (assistant!.content as any[]).find((b) => b.type === 'tool_use');
98
+ expect(toolUse.input).toEqual({ input: '2 + 2' });
99
+ });
100
+
101
+ // Adapted from @langchain/anthropic's
102
+ // "partial tool input is correctly merged before calling Anthropic API".
103
+ it('merges sibling input_json_delta blocks into tool_use input (persisted, no tool_calls)', () => {
104
+ const messages: BaseMessage[] = [
105
+ new HumanMessage('What\'s the weather in Seattle tomorrow?'),
106
+ new AIMessage({
107
+ content: [
108
+ { type: 'text', index: 1, text: 'I need to call the get_weather tool' },
109
+ { type: 'tool_use', index: 2, name: 'get_weather', id: 'tool_call_id', input: '' },
110
+ { type: 'input_json_delta', index: 2, input: '{"city": "' },
111
+ { type: 'input_json_delta', index: 2, input: 'Seattle", "da' },
112
+ { type: 'input_json_delta', index: 2, input: 'te": "to' },
113
+ { type: 'input_json_delta', index: 2, input: 'morrow"}' },
114
+ ] as any,
115
+ }),
116
+ ];
117
+
118
+ const payload = _convertMessagesToAnthropicPayload(messages);
119
+ const assistant = payload.messages.find((m: any) => m.role === 'assistant');
120
+ const blocks = assistant!.content as any[];
121
+ expect(blocks.filter((b) => b.type === 'input_json_delta')).toHaveLength(0);
122
+ const toolUse = blocks.find((b) => b.type === 'tool_use');
123
+ expect(toolUse).toMatchObject({
124
+ type: 'tool_use',
125
+ name: 'get_weather',
126
+ id: 'tool_call_id',
127
+ input: { city: 'Seattle', date: 'tomorrow' },
128
+ });
129
+ });
130
+ });
131
+
132
+ describe('_makeMessageChunkFromAnthropicEvent — streamed tool input merges into content', () => {
133
+ const fields = { streamUsage: true, coerceContentToString: false };
134
+
135
+ it('emits input deltas without a type so aggregation merges them into the tool_use block', () => {
136
+ const events: any[] = [
137
+ {
138
+ type: 'content_block_start',
139
+ index: 0,
140
+ content_block: { type: 'tool_use', id: 'toolu_1', name: 'calculator', input: {} },
141
+ },
142
+ {
143
+ type: 'content_block_delta',
144
+ index: 0,
145
+ delta: { type: 'input_json_delta', partial_json: '{"input"' },
146
+ },
147
+ {
148
+ type: 'content_block_delta',
149
+ index: 0,
150
+ delta: { type: 'input_json_delta', partial_json: ': "2 + 2"}' },
151
+ },
152
+ ];
153
+ const chunks = events
154
+ .map((e) => _makeMessageChunkFromAnthropicEvent(e, fields)?.chunk)
155
+ .filter((c): c is NonNullable<typeof c> => c != null);
156
+
157
+ // input-delta chunks must not carry a `type` (so core merges them by index
158
+ // into the sibling tool_use/server_tool_use block rather than orphaning them)
159
+ const deltaBlocks = chunks
160
+ .slice(1)
161
+ .flatMap((c) => (Array.isArray(c.content) ? (c.content as any[]) : []))
162
+ .filter((b) => 'input' in b);
163
+ expect(deltaBlocks.length).toBeGreaterThan(0);
164
+ deltaBlocks.forEach((b) => expect('type' in b).toBe(false));
165
+
166
+ // aggregate the chunks the way core does during streaming
167
+ const merged = chunks.reduce((acc, c) => acc.concat(c));
168
+ const blocks = merged.content as any[];
169
+
170
+ const toolUse = blocks.find((b) => b.type === 'tool_use');
171
+ expect(toolUse).toMatchObject({ type: 'tool_use', id: 'toolu_1', name: 'calculator' });
172
+ const parsed =
173
+ typeof toolUse.input === 'string' ? JSON.parse(toolUse.input) : toolUse.input;
174
+ expect(parsed).toEqual({ input: '2 + 2' });
175
+
176
+ // no orphaned delta block survives aggregation
177
+ expect(blocks.filter((b) => b.type !== 'tool_use' && 'input' in b)).toHaveLength(0);
178
+
179
+ // tool_calls remain correctly aggregated
180
+ expect(merged.tool_calls?.[0]).toMatchObject({
181
+ id: 'toolu_1',
182
+ name: 'calculator',
183
+ args: { input: '2 + 2' },
184
+ });
185
+ });
186
+ });
@@ -13,6 +13,7 @@ import {
13
13
  stripBedrockCacheControl,
14
14
  addBedrockCacheControl,
15
15
  addCacheControl,
16
+ addCacheControlToStablePrefixMessages,
16
17
  } from './cache';
17
18
  import { _convertMessagesToOpenAIParams } from '@/llm/openai/utils';
18
19
  import { toLangChainContent } from './langchain';
@@ -767,6 +768,127 @@ describe('addBedrockCacheControl (Bedrock cache checkpoints)', () => {
767
768
  });
768
769
  });
769
770
 
771
+ describe('synthetic skill/meta messages are not cache-anchored', () => {
772
+ const hasAnthropicMarker = (m: BaseMessage): boolean =>
773
+ Array.isArray(m.content) &&
774
+ m.content.some((block) => 'cache_control' in block);
775
+
776
+ const hasBedrockCachePoint = (m: BaseMessage): boolean =>
777
+ Array.isArray(m.content) &&
778
+ m.content.some((block) => 'cachePoint' in block);
779
+
780
+ const skillBody = (skillName: string, content = 'SKILL BODY'): HumanMessage =>
781
+ new HumanMessage({
782
+ content,
783
+ additional_kwargs: { isMeta: true, source: 'skill', skillName },
784
+ });
785
+
786
+ it('Anthropic: skips a trailing synthetic skill message; markers land on the real user messages', () => {
787
+ const messages: BaseMessage[] = [
788
+ new HumanMessage('First real question'),
789
+ new AIMessage('Answer'),
790
+ new HumanMessage('Second real question'),
791
+ skillBody('pdf-analyzer'),
792
+ ];
793
+
794
+ const result = addCacheControl<BaseMessage>(messages);
795
+
796
+ expect(hasAnthropicMarker(result[3])).toBe(false);
797
+ expect(hasAnthropicMarker(result[2])).toBe(true);
798
+ expect(hasAnthropicMarker(result[0])).toBe(true);
799
+ });
800
+
801
+ it('Anthropic: strips a stale marker from a synthetic skill message without re-adding one', () => {
802
+ const stale = new HumanMessage({
803
+ content: toLangChainContent([
804
+ {
805
+ type: 'text',
806
+ text: 'SKILL BODY',
807
+ cache_control: { type: 'ephemeral' },
808
+ } as MessageContentComplex,
809
+ ]),
810
+ additional_kwargs: {
811
+ isMeta: true,
812
+ source: 'skill',
813
+ skillName: 'pdf-analyzer',
814
+ },
815
+ });
816
+ const messages: BaseMessage[] = [
817
+ new HumanMessage('Real question'),
818
+ new AIMessage('Answer'),
819
+ stale,
820
+ ];
821
+
822
+ const result = addCacheControl<BaseMessage>(messages);
823
+
824
+ expect(hasAnthropicMarker(result[2])).toBe(false);
825
+ expect(hasAnthropicMarker(result[0])).toBe(true);
826
+ });
827
+
828
+ it('Anthropic: detects skill messages by additional_kwargs.source even without isMeta', () => {
829
+ const messages: BaseMessage[] = [
830
+ new HumanMessage('Real question'),
831
+ new AIMessage('Answer'),
832
+ new HumanMessage({
833
+ content: 'SKILL BODY',
834
+ additional_kwargs: { source: 'skill', skillName: 'pdf-analyzer' },
835
+ }),
836
+ ];
837
+
838
+ const result = addCacheControl<BaseMessage>(messages);
839
+
840
+ expect(hasAnthropicMarker(result[2])).toBe(false);
841
+ expect(hasAnthropicMarker(result[0])).toBe(true);
842
+ });
843
+
844
+ it('Bedrock: skips a trailing synthetic skill message; cachePoints land on the real user messages', () => {
845
+ const messages: BaseMessage[] = [
846
+ new HumanMessage('First real question'),
847
+ new AIMessage('Answer'),
848
+ new HumanMessage('Second real question'),
849
+ skillBody('pdf-analyzer'),
850
+ ];
851
+
852
+ const result = addBedrockCacheControl<BaseMessage>(messages);
853
+
854
+ expect(hasBedrockCachePoint(result[3])).toBe(false);
855
+ expect(hasBedrockCachePoint(result[2])).toBe(true);
856
+ expect(hasBedrockCachePoint(result[0])).toBe(true);
857
+ });
858
+
859
+ it('stable-prefix fallback: anchors the real user message, not a synthetic skill message', () => {
860
+ // Mirrors AgentContext's dynamic-tail path: the only assistant message is a
861
+ // skill-only tool call (no text), so the assistant-only pass adds no marker
862
+ // and the cacheable fallback runs. It must skip the reconstructed skill
863
+ // HumanMessage and anchor the real user message instead.
864
+ const messages: BaseMessage[] = [
865
+ new HumanMessage('Real stable question'),
866
+ new AIMessage({
867
+ content: toLangChainContent([
868
+ {
869
+ type: 'tool_use',
870
+ id: 'call_1',
871
+ name: 'skill',
872
+ input: { skillName: 'pdf-analyzer' },
873
+ } as MessageContentComplex,
874
+ ]),
875
+ tool_calls: [
876
+ { id: 'call_1', name: 'skill', args: { skillName: 'pdf-analyzer' } },
877
+ ],
878
+ }),
879
+ skillBody('pdf-analyzer'),
880
+ ];
881
+
882
+ const result = addCacheControlToStablePrefixMessages<BaseMessage>(
883
+ messages,
884
+ 2
885
+ );
886
+
887
+ expect(hasAnthropicMarker(result[2])).toBe(false);
888
+ expect(hasAnthropicMarker(result[0])).toBe(true);
889
+ });
890
+ });
891
+
770
892
  describe('stripAnthropicCacheControl', () => {
771
893
  it('removes cache_control fields from content blocks', () => {
772
894
  const messages: TestMsg[] = [
@@ -182,6 +182,7 @@ export function addCacheControl<T extends AnthropicMessage | BaseMessage>(
182
182
  const needsCacheAdd =
183
183
  userMessagesModified < 2 &&
184
184
  isUserMessage &&
185
+ !isSyntheticMetaMessage(originalMessage) &&
185
186
  (typeof content === 'string' || hasArrayContent);
186
187
 
187
188
  // Skip messages that don't need any work
@@ -263,6 +264,26 @@ function getMessageRole(message: MessageWithContent): string | undefined {
263
264
  return undefined;
264
265
  }
265
266
 
267
+ const SKILL_MESSAGE_SOURCE = 'skill';
268
+
269
+ /**
270
+ * Synthetic skill/meta messages (reconstructed skill bodies, primed SKILL.md
271
+ * instructions) are re-injected every turn and are not stable conversation
272
+ * turns. They must not anchor a fresh prompt-cache marker — doing so pins the
273
+ * cache to a volatile/duplicated prefix. Stale markers are still stripped from
274
+ * them; only the *adding* of new markers is suppressed. Detected via
275
+ * `additional_kwargs.isMeta === true` or `additional_kwargs.source === 'skill'`.
276
+ */
277
+ function isSyntheticMetaMessage(message: MessageWithContent): boolean {
278
+ const { additional_kwargs: kwargs } = message as {
279
+ additional_kwargs?: { isMeta?: unknown; source?: unknown };
280
+ };
281
+ if (kwargs == null) {
282
+ return false;
283
+ }
284
+ return kwargs.isMeta === true || kwargs.source === SKILL_MESSAGE_SOURCE;
285
+ }
286
+
266
287
  function isCacheableConversationMessage(message: MessageWithContent): boolean {
267
288
  const role = getMessageRole(message);
268
289
  return (
@@ -305,7 +326,9 @@ function addCacheControlToRecentMessages<
305
326
  const content = originalMessage.content;
306
327
  const hasArrayContent = Array.isArray(content);
307
328
  const canAddCache =
308
- cachePointsAdded < maxCachePoints && canUseMessage(originalMessage);
329
+ cachePointsAdded < maxCachePoints &&
330
+ canUseMessage(originalMessage) &&
331
+ !isSyntheticMetaMessage(originalMessage);
309
332
 
310
333
  if (!canAddCache && !hasArrayContent) {
311
334
  continue;
@@ -536,6 +559,7 @@ export function addBedrockCacheControl<
536
559
  isUserMessage &&
537
560
  !isToolMessage &&
538
561
  !isEmptyString &&
562
+ !isSyntheticMetaMessage(originalMessage) &&
539
563
  (typeof content === 'string' || hasArrayContent);
540
564
 
541
565
  if (!needsCacheAdd && !hasArrayContent && !hasSerializationProps) {
@@ -334,6 +334,10 @@ interface FormatAssistantMessageOptions {
334
334
 
335
335
  interface FormatAgentMessagesOptions {
336
336
  provider?: Providers;
337
+ /** Skill names already primed fresh this turn (manual/always-apply). Their
338
+ * historical `skill` tool_calls are not reconstructed into a HumanMessage,
339
+ * so the same SKILL.md body is not injected twice in one request. */
340
+ skipSkillBodyNames?: Set<string>;
337
341
  }
338
342
 
339
343
  function extractReasoningContent(
@@ -1159,6 +1163,7 @@ function extractSkillName(args: unknown): string | undefined {
1159
1163
  * @param indexTokenCountMap - Optional map of message indices to token counts.
1160
1164
  * @param tools - Optional set of tool names that are allowed in the request.
1161
1165
  * @param skills - Optional map of skill name to body for reconstructing skill HumanMessages.
1166
+ * @param options - Optional formatting options (provider, skipSkillBodyNames).
1162
1167
  * @returns - Object containing formatted messages and updated indexTokenCountMap if provided.
1163
1168
  */
1164
1169
  export const formatAgentMessages = (
@@ -1445,7 +1450,11 @@ export const formatAgentMessages = (
1445
1450
  const endMessageIndex = messages.length;
1446
1451
 
1447
1452
  if (pendingSkillNames?.size != null && pendingSkillNames.size > 0) {
1453
+ const skipSkillBodyNames = options?.skipSkillBodyNames;
1448
1454
  for (const skillName of pendingSkillNames) {
1455
+ if (skipSkillBodyNames != null && skipSkillBodyNames.has(skillName)) {
1456
+ continue;
1457
+ }
1449
1458
  const body = skills?.get(skillName) ?? '';
1450
1459
  if (body) {
1451
1460
  messages.push(
@@ -410,4 +410,104 @@ describe('formatAgentMessages skill body reconstruction', () => {
410
410
  expect(assistantTotal).toBe(500);
411
411
  });
412
412
  });
413
+
414
+ describe('skipSkillBodyNames (fresh-prime dedupe)', () => {
415
+ const tools = new Set([Constants.SKILL_TOOL]);
416
+
417
+ const injectedSkillBodies = (
418
+ messages: ReturnType<typeof formatAgentMessages>['messages']
419
+ ) =>
420
+ messages.filter(
421
+ (m) =>
422
+ m instanceof HumanMessage &&
423
+ (m as HumanMessage).additional_kwargs.source === 'skill'
424
+ );
425
+
426
+ it('does NOT reconstruct body when skill name is in skipSkillBodyNames', () => {
427
+ const payload: TPayload = [
428
+ { role: 'user', content: 'Review my code' },
429
+ {
430
+ role: 'assistant',
431
+ content: [skillToolCall('call_1', 'code-review')],
432
+ },
433
+ ];
434
+
435
+ const { messages } = formatAgentMessages(
436
+ payload,
437
+ undefined,
438
+ tools,
439
+ skillBodies,
440
+ { skipSkillBodyNames: new Set(['code-review']) }
441
+ );
442
+
443
+ expect(injectedSkillBodies(messages)).toHaveLength(0);
444
+ });
445
+
446
+ it('reconstructs only names NOT in skipSkillBodyNames', () => {
447
+ const payload: TPayload = [
448
+ { role: 'user', content: 'Go' },
449
+ {
450
+ role: 'assistant',
451
+ content: [
452
+ skillToolCall('call_1', 'pdf-analyzer'),
453
+ skillToolCall('call_2', 'code-review'),
454
+ ],
455
+ },
456
+ ];
457
+
458
+ const { messages } = formatAgentMessages(
459
+ payload,
460
+ undefined,
461
+ tools,
462
+ skillBodies,
463
+ { skipSkillBodyNames: new Set(['code-review']) }
464
+ );
465
+
466
+ const injected = injectedSkillBodies(messages);
467
+ expect(injected).toHaveLength(1);
468
+ expect((injected[0] as HumanMessage).additional_kwargs.skillName).toBe(
469
+ 'pdf-analyzer'
470
+ );
471
+ });
472
+
473
+ it('reconstructs normally when skipSkillBodyNames is empty', () => {
474
+ const payload: TPayload = [
475
+ { role: 'user', content: 'Review my code' },
476
+ {
477
+ role: 'assistant',
478
+ content: [skillToolCall('call_1', 'code-review')],
479
+ },
480
+ ];
481
+
482
+ const { messages } = formatAgentMessages(
483
+ payload,
484
+ undefined,
485
+ tools,
486
+ skillBodies,
487
+ { skipSkillBodyNames: new Set() }
488
+ );
489
+
490
+ expect(injectedSkillBodies(messages)).toHaveLength(1);
491
+ });
492
+
493
+ it('skips in the non-tools-filtering path too', () => {
494
+ const payload: TPayload = [
495
+ { role: 'user', content: 'Review my code' },
496
+ {
497
+ role: 'assistant',
498
+ content: [skillToolCall('call_1', 'code-review')],
499
+ },
500
+ ];
501
+
502
+ const { messages } = formatAgentMessages(
503
+ payload,
504
+ undefined,
505
+ undefined,
506
+ skillBodies,
507
+ { skipSkillBodyNames: new Set(['code-review']) }
508
+ );
509
+
510
+ expect(injectedSkillBodies(messages)).toHaveLength(0);
511
+ });
512
+ });
413
513
  });
@@ -240,7 +240,15 @@ export function expandHighlights(
240
240
  !result.highlights ||
241
241
  result.highlights.length === 0
242
242
  ) {
243
- return result; // No modification needed
243
+ if (result.content == null && result.references == null) {
244
+ return result;
245
+ }
246
+ /** Raw scraped content must never leave this function — without
247
+ * highlights to expand, strip it instead of passing it downstream */
248
+ const strippedResult = { ...result };
249
+ delete strippedResult.content;
250
+ delete strippedResult.references;
251
+ return strippedResult;
244
252
  }
245
253
 
246
254
  // Create a shallow copy with expanded highlights
@@ -66,6 +66,25 @@ const chunker = {
66
66
  },
67
67
  };
68
68
 
69
+ const DEFAULT_MAX_CONTENT_LENGTH = 50000;
70
+
71
+ /** Resolves the per-source scraped content cap from config, the
72
+ * `SEARCH_MAX_CONTENT_LENGTH` env var, or the default (50,000 chars) */
73
+ function resolveMaxContentLength(maxContentLength?: number): number {
74
+ if (maxContentLength != null && maxContentLength > 0) {
75
+ return maxContentLength;
76
+ }
77
+ const envValue = Number(process.env.SEARCH_MAX_CONTENT_LENGTH);
78
+ if (Number.isFinite(envValue) && envValue > 0) {
79
+ return envValue;
80
+ }
81
+ return DEFAULT_MAX_CONTENT_LENGTH;
82
+ }
83
+
84
+ function truncateContent(content: string, maxLength: number): string {
85
+ return content.length > maxLength ? content.slice(0, maxLength) : content;
86
+ }
87
+
69
88
  function createSourceUpdateCallback(sourceMap: Map<string, t.ValidSource>) {
70
89
  return (link: string, update?: Partial<t.ValidSource>): void => {
71
90
  const source = sourceMap.get(link);
@@ -83,12 +102,14 @@ const getHighlights = async ({
83
102
  content,
84
103
  reranker,
85
104
  topResults = 5,
105
+ maxContentLength = DEFAULT_MAX_CONTENT_LENGTH,
86
106
  logger,
87
107
  }: {
88
108
  content: string;
89
109
  query: string;
90
110
  reranker?: BaseReranker;
91
111
  topResults?: number;
112
+ maxContentLength?: number;
92
113
  logger?: t.Logger;
93
114
  }): Promise<t.Highlight[] | undefined> => {
94
115
  const logger_ = logger || createDefaultLogger();
@@ -103,7 +124,9 @@ const getHighlights = async ({
103
124
  }
104
125
 
105
126
  try {
106
- const documents = await chunker.splitText(content);
127
+ const documents = await chunker.splitText(
128
+ truncateContent(content, maxContentLength)
129
+ );
107
130
  if (Array.isArray(documents)) {
108
131
  return await reranker.rerank(query, documents, topResults);
109
132
  } else {
@@ -457,6 +480,7 @@ export const createSourceProcessor = (
457
480
  logger,
458
481
  } = config;
459
482
 
483
+ const maxContentLength = resolveMaxContentLength(config.maxContentLength);
460
484
  const logger_ = logger || createDefaultLogger();
461
485
  const scraper = scraperInstance;
462
486
 
@@ -475,7 +499,7 @@ export const createSourceProcessor = (
475
499
  url,
476
500
  references,
477
501
  attribution,
478
- content: chunker.cleanText(content),
502
+ content: truncateContent(chunker.cleanText(content), maxContentLength),
479
503
  };
480
504
  }
481
505
 
@@ -498,6 +522,7 @@ export const createSourceProcessor = (
498
522
  query,
499
523
  reranker,
500
524
  content: result.content,
525
+ maxContentLength,
501
526
  logger: logger_,
502
527
  });
503
528
  if (onGetHighlights) {
@@ -606,7 +631,20 @@ export const createSourceProcessor = (
606
631
  images: [],
607
632
  relatedSearches: [],
608
633
  };
609
- } else if (!result.data.organic) {
634
+ }
635
+
636
+ if (
637
+ result.data.topStories != null &&
638
+ result.data.topStories.length > numElements
639
+ ) {
640
+ /** Merged news results can far exceed the requested source count;
641
+ * every entry is formatted into the LLM output, so cap them up
642
+ * front — before any early return below and before scraping
643
+ * entries the cap would discard */
644
+ result.data.topStories = result.data.topStories.slice(0, numElements);
645
+ }
646
+
647
+ if (!result.data.organic) {
610
648
  return result.data;
611
649
  }
612
650