@librechat/agents 3.2.21 → 3.2.31

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 (398) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +3 -2
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/events.cjs.map +1 -1
  4. package/dist/cjs/graphs/Graph.cjs +200 -54
  5. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  6. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  7. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +13 -7
  8. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -1
  9. package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
  10. package/dist/cjs/hooks/types.cjs.map +1 -1
  11. package/dist/cjs/instrumentation.cjs +2 -2
  12. package/dist/cjs/instrumentation.cjs.map +1 -1
  13. package/dist/cjs/langfuse.cjs +17 -1
  14. package/dist/cjs/langfuse.cjs.map +1 -1
  15. package/dist/cjs/langfuseToolOutputTracing.cjs +2 -2
  16. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  17. package/dist/cjs/llm/anthropic/index.cjs +1 -1
  18. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  19. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  20. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +1 -1
  21. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  22. package/dist/cjs/llm/bedrock/index.cjs +2 -2
  23. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  24. package/dist/cjs/llm/bedrock/toolCache.cjs +8 -5
  25. package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
  26. package/dist/cjs/llm/fake.cjs +16 -14
  27. package/dist/cjs/llm/fake.cjs.map +1 -1
  28. package/dist/cjs/llm/google/index.cjs +22 -0
  29. package/dist/cjs/llm/google/index.cjs.map +1 -1
  30. package/dist/cjs/llm/google/utils/common.cjs +88 -27
  31. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  32. package/dist/cjs/llm/init.cjs +2 -2
  33. package/dist/cjs/llm/invoke.cjs +108 -11
  34. package/dist/cjs/llm/invoke.cjs.map +1 -1
  35. package/dist/cjs/llm/openai/index.cjs +1 -1
  36. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  37. package/dist/cjs/llm/openai/utils/index.cjs +1 -1
  38. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  39. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  40. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  41. package/dist/cjs/main.cjs +1 -0
  42. package/dist/cjs/main.cjs.map +1 -1
  43. package/dist/cjs/messages/cache.cjs +8 -7
  44. package/dist/cjs/messages/cache.cjs.map +1 -1
  45. package/dist/cjs/messages/content.cjs.map +1 -1
  46. package/dist/cjs/messages/contextPruning.cjs.map +1 -1
  47. package/dist/cjs/messages/format.cjs +124 -17
  48. package/dist/cjs/messages/format.cjs.map +1 -1
  49. package/dist/cjs/messages/prune.cjs.map +1 -1
  50. package/dist/cjs/messages/reducer.cjs +1 -1
  51. package/dist/cjs/messages/reducer.cjs.map +1 -1
  52. package/dist/cjs/messages/tools.cjs +1 -1
  53. package/dist/cjs/messages/tools.cjs.map +1 -1
  54. package/dist/cjs/openai/index.cjs.map +1 -1
  55. package/dist/cjs/responses/index.cjs.map +1 -1
  56. package/dist/cjs/run.cjs +41 -20
  57. package/dist/cjs/run.cjs.map +1 -1
  58. package/dist/cjs/session/AgentSession.cjs +4 -4
  59. package/dist/cjs/session/AgentSession.cjs.map +1 -1
  60. package/dist/cjs/session/JsonlSessionStore.cjs +2 -2
  61. package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
  62. package/dist/cjs/session/handlers.cjs +2 -2
  63. package/dist/cjs/session/handlers.cjs.map +1 -1
  64. package/dist/cjs/stream.cjs +248 -25
  65. package/dist/cjs/stream.cjs.map +1 -1
  66. package/dist/cjs/summarization/node.cjs.map +1 -1
  67. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +1 -1
  68. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  69. package/dist/cjs/tools/Calculator.cjs +1 -1
  70. package/dist/cjs/tools/Calculator.cjs.map +1 -1
  71. package/dist/cjs/tools/CodeExecutor.cjs +1 -1
  72. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  73. package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
  74. package/dist/cjs/tools/ToolNode.cjs +37 -18
  75. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  76. package/dist/cjs/tools/ToolSearch.cjs +1 -1
  77. package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
  78. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs +7 -4
  79. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs.map +1 -1
  80. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs +4 -4
  81. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs.map +1 -1
  82. package/dist/cjs/tools/handlers.cjs +2 -1
  83. package/dist/cjs/tools/handlers.cjs.map +1 -1
  84. package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -1
  85. package/dist/cjs/tools/local/FileCheckpointer.cjs +2 -1
  86. package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -1
  87. package/dist/cjs/tools/local/LocalCodingTools.cjs +45 -19
  88. package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -1
  89. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +3 -3
  90. package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
  91. package/dist/cjs/tools/local/LocalExecutionTools.cjs +2 -2
  92. package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -1
  93. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +4 -3
  94. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
  95. package/dist/cjs/tools/local/attachments.cjs +0 -5
  96. package/dist/cjs/tools/local/attachments.cjs.map +1 -1
  97. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +4 -4
  98. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
  99. package/dist/cjs/tools/search/firecrawl.cjs +1 -1
  100. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  101. package/dist/cjs/tools/search/rerankers.cjs +7 -3
  102. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  103. package/dist/cjs/tools/search/tavily-search.cjs +1 -1
  104. package/dist/cjs/tools/search/tavily-search.cjs.map +1 -1
  105. package/dist/cjs/tools/search/utils.cjs +76 -8
  106. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  107. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +1 -1
  108. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  109. package/dist/cjs/utils/handlers.cjs +1 -1
  110. package/dist/cjs/utils/handlers.cjs.map +1 -1
  111. package/dist/cjs/utils/run.cjs +1 -1
  112. package/dist/cjs/utils/run.cjs.map +1 -1
  113. package/dist/esm/agents/AgentContext.mjs +3 -2
  114. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  115. package/dist/esm/events.mjs.map +1 -1
  116. package/dist/esm/graphs/Graph.mjs +200 -54
  117. package/dist/esm/graphs/Graph.mjs.map +1 -1
  118. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  119. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +13 -7
  120. package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -1
  121. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  122. package/dist/esm/hooks/types.mjs.map +1 -1
  123. package/dist/esm/instrumentation.mjs +2 -2
  124. package/dist/esm/instrumentation.mjs.map +1 -1
  125. package/dist/esm/langfuse.mjs +17 -2
  126. package/dist/esm/langfuse.mjs.map +1 -1
  127. package/dist/esm/langfuseToolOutputTracing.mjs +2 -2
  128. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  129. package/dist/esm/llm/anthropic/index.mjs +1 -1
  130. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  131. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  132. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +1 -1
  133. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  134. package/dist/esm/llm/bedrock/index.mjs +2 -2
  135. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  136. package/dist/esm/llm/bedrock/toolCache.mjs +8 -5
  137. package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
  138. package/dist/esm/llm/fake.mjs +16 -14
  139. package/dist/esm/llm/fake.mjs.map +1 -1
  140. package/dist/esm/llm/google/index.mjs +23 -1
  141. package/dist/esm/llm/google/index.mjs.map +1 -1
  142. package/dist/esm/llm/google/utils/common.mjs +88 -27
  143. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  144. package/dist/esm/llm/init.mjs +2 -2
  145. package/dist/esm/llm/invoke.mjs +104 -7
  146. package/dist/esm/llm/invoke.mjs.map +1 -1
  147. package/dist/esm/llm/openai/index.mjs +1 -1
  148. package/dist/esm/llm/openai/index.mjs.map +1 -1
  149. package/dist/esm/llm/openai/utils/index.mjs +1 -1
  150. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  151. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  152. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  153. package/dist/esm/main.mjs +1 -1
  154. package/dist/esm/messages/cache.mjs +8 -7
  155. package/dist/esm/messages/cache.mjs.map +1 -1
  156. package/dist/esm/messages/content.mjs.map +1 -1
  157. package/dist/esm/messages/contextPruning.mjs.map +1 -1
  158. package/dist/esm/messages/format.mjs +124 -18
  159. package/dist/esm/messages/format.mjs.map +1 -1
  160. package/dist/esm/messages/prune.mjs.map +1 -1
  161. package/dist/esm/messages/reducer.mjs +1 -1
  162. package/dist/esm/messages/reducer.mjs.map +1 -1
  163. package/dist/esm/messages/tools.mjs +1 -1
  164. package/dist/esm/messages/tools.mjs.map +1 -1
  165. package/dist/esm/openai/index.mjs.map +1 -1
  166. package/dist/esm/responses/index.mjs.map +1 -1
  167. package/dist/esm/run.mjs +41 -20
  168. package/dist/esm/run.mjs.map +1 -1
  169. package/dist/esm/session/AgentSession.mjs +4 -4
  170. package/dist/esm/session/AgentSession.mjs.map +1 -1
  171. package/dist/esm/session/JsonlSessionStore.mjs +2 -2
  172. package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
  173. package/dist/esm/session/handlers.mjs +2 -2
  174. package/dist/esm/session/handlers.mjs.map +1 -1
  175. package/dist/esm/stream.mjs +248 -25
  176. package/dist/esm/stream.mjs.map +1 -1
  177. package/dist/esm/summarization/node.mjs.map +1 -1
  178. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +1 -1
  179. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  180. package/dist/esm/tools/Calculator.mjs +1 -1
  181. package/dist/esm/tools/Calculator.mjs.map +1 -1
  182. package/dist/esm/tools/CodeExecutor.mjs +1 -1
  183. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  184. package/dist/esm/tools/SubagentTool.mjs.map +1 -1
  185. package/dist/esm/tools/ToolNode.mjs +37 -18
  186. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  187. package/dist/esm/tools/ToolSearch.mjs +1 -1
  188. package/dist/esm/tools/ToolSearch.mjs.map +1 -1
  189. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs +7 -4
  190. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs.map +1 -1
  191. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs +4 -4
  192. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs.map +1 -1
  193. package/dist/esm/tools/handlers.mjs +2 -1
  194. package/dist/esm/tools/handlers.mjs.map +1 -1
  195. package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -1
  196. package/dist/esm/tools/local/FileCheckpointer.mjs +2 -1
  197. package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -1
  198. package/dist/esm/tools/local/LocalCodingTools.mjs +45 -19
  199. package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -1
  200. package/dist/esm/tools/local/LocalExecutionEngine.mjs +3 -3
  201. package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
  202. package/dist/esm/tools/local/LocalExecutionTools.mjs +2 -2
  203. package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -1
  204. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +4 -3
  205. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
  206. package/dist/esm/tools/local/attachments.mjs +0 -5
  207. package/dist/esm/tools/local/attachments.mjs.map +1 -1
  208. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +4 -4
  209. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
  210. package/dist/esm/tools/search/firecrawl.mjs +1 -1
  211. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  212. package/dist/esm/tools/search/rerankers.mjs +8 -4
  213. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  214. package/dist/esm/tools/search/tavily-search.mjs +1 -1
  215. package/dist/esm/tools/search/tavily-search.mjs.map +1 -1
  216. package/dist/esm/tools/search/utils.mjs +76 -9
  217. package/dist/esm/tools/search/utils.mjs.map +1 -1
  218. package/dist/esm/tools/subagent/SubagentExecutor.mjs +1 -1
  219. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  220. package/dist/esm/utils/handlers.mjs +1 -1
  221. package/dist/esm/utils/handlers.mjs.map +1 -1
  222. package/dist/esm/utils/run.mjs +1 -1
  223. package/dist/esm/utils/run.mjs.map +1 -1
  224. package/dist/types/agents/__tests__/promptCacheLiveHelpers.d.ts +1 -1
  225. package/dist/types/events.d.ts +1 -1
  226. package/dist/types/graphs/Graph.d.ts +7 -1
  227. package/dist/types/hooks/executeHooks.d.ts +1 -1
  228. package/dist/types/hooks/types.d.ts +5 -0
  229. package/dist/types/langfuse.d.ts +4 -0
  230. package/dist/types/llm/anthropic/utils/message_inputs.d.ts +1 -1
  231. package/dist/types/llm/anthropic/utils/message_outputs.d.ts +1 -1
  232. package/dist/types/llm/anthropic/utils/output_parsers.d.ts +2 -2
  233. package/dist/types/llm/bedrock/index.d.ts +2 -2
  234. package/dist/types/llm/fake.d.ts +3 -3
  235. package/dist/types/llm/google/index.d.ts +1 -0
  236. package/dist/types/llm/google/types.d.ts +1 -1
  237. package/dist/types/llm/google/utils/common.d.ts +2 -2
  238. package/dist/types/llm/google/utils/tools.d.ts +1 -1
  239. package/dist/types/llm/google/utils/zod_to_genai_parameters.d.ts +1 -1
  240. package/dist/types/llm/openai/index.d.ts +2 -2
  241. package/dist/types/llm/openai/utils/index.d.ts +1 -1
  242. package/dist/types/llm/openrouter/index.d.ts +4 -4
  243. package/dist/types/messages/contextPruning.d.ts +1 -1
  244. package/dist/types/messages/format.d.ts +9 -4
  245. package/dist/types/messages/prune.d.ts +1 -1
  246. package/dist/types/session/JsonlSessionStore.d.ts +1 -1
  247. package/dist/types/session/handlers.d.ts +1 -1
  248. package/dist/types/session/types.d.ts +1 -1
  249. package/dist/types/summarization/node.d.ts +1 -1
  250. package/dist/types/tools/SubagentTool.d.ts +2 -2
  251. package/dist/types/tools/ToolNode.d.ts +9 -2
  252. package/dist/types/tools/cloudflare/CloudflareSandboxExecutionEngine.d.ts +1 -1
  253. package/dist/types/tools/search/types.d.ts +1 -1
  254. package/dist/types/tools/search/utils.d.ts +11 -0
  255. package/dist/types/types/graph.d.ts +4 -4
  256. package/dist/types/types/llm.d.ts +4 -3
  257. package/dist/types/types/messages.d.ts +1 -1
  258. package/dist/types/types/run.d.ts +6 -6
  259. package/dist/types/types/stream.d.ts +2 -2
  260. package/dist/types/types/tools.d.ts +5 -1
  261. package/dist/types/utils/handlers.d.ts +2 -2
  262. package/dist/types/utils/run.d.ts +1 -1
  263. package/package.json +6 -3
  264. package/src/__tests__/stream.eagerEventExecution.test.ts +543 -6
  265. package/src/agents/AgentContext.ts +2 -2
  266. package/src/agents/__tests__/AgentContext.test.ts +3 -3
  267. package/src/agents/__tests__/promptCacheLiveHelpers.ts +1 -1
  268. package/src/events.ts +1 -1
  269. package/src/graphs/Graph.ts +329 -72
  270. package/src/graphs/MultiAgentGraph.ts +1 -1
  271. package/src/graphs/__tests__/Graph.reasoning.test.ts +919 -6
  272. package/src/graphs/__tests__/MultiAgentGraph.test.ts +1 -1
  273. package/src/graphs/__tests__/composition.smoke.test.ts +1 -1
  274. package/src/hooks/__tests__/HookRegistry.test.ts +1 -1
  275. package/src/hooks/__tests__/compactHooks.test.ts +8 -8
  276. package/src/hooks/__tests__/createWorkspacePolicyHook.test.ts +34 -22
  277. package/src/hooks/__tests__/executeHooks.test.ts +3 -3
  278. package/src/hooks/__tests__/integration.test.ts +3 -3
  279. package/src/hooks/__tests__/toolHooks.test.ts +10 -10
  280. package/src/hooks/createWorkspacePolicyHook.ts +17 -14
  281. package/src/hooks/executeHooks.ts +1 -1
  282. package/src/hooks/types.ts +5 -0
  283. package/src/instrumentation.ts +11 -11
  284. package/src/langfuse.ts +35 -1
  285. package/src/langfuseToolOutputTracing.ts +2 -2
  286. package/src/llm/anthropic/index.ts +1 -1
  287. package/src/llm/anthropic/utils/message_inputs.ts +1 -1
  288. package/src/llm/anthropic/utils/message_outputs.ts +3 -5
  289. package/src/llm/anthropic/utils/output_parsers.ts +5 -5
  290. package/src/llm/bedrock/index.ts +4 -4
  291. package/src/llm/bedrock/toolCache.test.ts +48 -9
  292. package/src/llm/bedrock/toolCache.ts +11 -6
  293. package/src/llm/fake.ts +30 -25
  294. package/src/llm/google/index.ts +43 -1
  295. package/src/llm/google/llm.spec.ts +173 -1
  296. package/src/llm/google/types.ts +1 -1
  297. package/src/llm/google/utils/common.ts +154 -45
  298. package/src/llm/google/utils/tools.ts +8 -8
  299. package/src/llm/google/utils/zod_to_genai_parameters.ts +4 -4
  300. package/src/llm/invoke.test.ts +3 -3
  301. package/src/llm/invoke.ts +170 -10
  302. package/src/llm/openai/index.ts +4 -4
  303. package/src/llm/openai/utils/index.ts +14 -14
  304. package/src/llm/openrouter/index.ts +4 -4
  305. package/src/llm/openrouter/reasoning.test.ts +2 -2
  306. package/src/llm/vertexai/fixThoughtSignatures.test.ts +1 -1
  307. package/src/llm/vertexai/index.ts +1 -1
  308. package/src/messages/cache.test.ts +22 -0
  309. package/src/messages/cache.ts +25 -12
  310. package/src/messages/content.ts +1 -1
  311. package/src/messages/contextPruning.ts +1 -1
  312. package/src/messages/format.ts +227 -43
  313. package/src/messages/formatAgentMessages.skills.test.ts +105 -26
  314. package/src/messages/formatAgentMessages.test.ts +841 -10
  315. package/src/messages/labelContentByAgent.test.ts +2 -2
  316. package/src/messages/prune.ts +1 -1
  317. package/src/messages/reducer.ts +1 -1
  318. package/src/messages/tools.ts +1 -1
  319. package/src/openai/__tests__/openai.test.ts +2 -2
  320. package/src/openai/index.ts +1 -1
  321. package/src/responses/__tests__/responses.test.ts +2 -2
  322. package/src/responses/index.ts +1 -1
  323. package/src/run.ts +68 -41
  324. package/src/session/AgentSession.ts +6 -6
  325. package/src/session/JsonlSessionStore.ts +3 -3
  326. package/src/session/__tests__/JsonlSessionStore.test.ts +5 -5
  327. package/src/session/__tests__/handlers.test.ts +2 -2
  328. package/src/session/handlers.ts +5 -5
  329. package/src/session/types.ts +1 -1
  330. package/src/specs/agent-handoffs.test.ts +1 -1
  331. package/src/specs/langfuse-callbacks.test.ts +2 -2
  332. package/src/specs/langfuse-metadata.test.ts +39 -0
  333. package/src/specs/langfuse-tool-output-tracing.test.ts +1 -1
  334. package/src/specs/multi-agent-summarization.test.ts +4 -4
  335. package/src/specs/subagent.test.ts +3 -3
  336. package/src/specs/summarization-unit.test.ts +1 -1
  337. package/src/specs/thinking-handoff.test.ts +1 -1
  338. package/src/splitStream.test.ts +48 -0
  339. package/src/stream.test.ts +53 -3
  340. package/src/stream.ts +450 -39
  341. package/src/summarization/__tests__/aggregator.test.ts +2 -2
  342. package/src/summarization/__tests__/node.test.ts +2 -2
  343. package/src/summarization/node.ts +1 -1
  344. package/src/tools/BashProgrammaticToolCalling.ts +5 -5
  345. package/src/tools/Calculator.ts +1 -1
  346. package/src/tools/CodeExecutor.ts +2 -4
  347. package/src/tools/SubagentTool.ts +2 -2
  348. package/src/tools/ToolNode.ts +37 -16
  349. package/src/tools/ToolSearch.ts +1 -1
  350. package/src/tools/__tests__/CloudflareSandboxExecution.test.ts +4 -4
  351. package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +12 -12
  352. package/src/tools/__tests__/LocalExecutionTools.test.ts +125 -93
  353. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +29 -5
  354. package/src/tools/__tests__/ReadFile.test.ts +1 -1
  355. package/src/tools/__tests__/SkillTool.test.ts +4 -4
  356. package/src/tools/__tests__/SubagentExecutor.test.ts +17 -13
  357. package/src/tools/__tests__/SubagentTool.test.ts +2 -2
  358. package/src/tools/__tests__/ToolNode.eagerEventExecution.test.ts +1 -1
  359. package/src/tools/__tests__/ToolNode.outputReferences.test.ts +2 -5
  360. package/src/tools/__tests__/ToolNode.session.test.ts +1 -1
  361. package/src/tools/__tests__/ToolSearch.test.ts +1 -1
  362. package/src/tools/__tests__/annotateMessagesForLLM.test.ts +1 -1
  363. package/src/tools/__tests__/directToolHITLResumeScope.test.ts +35 -32
  364. package/src/tools/__tests__/directToolHooks.test.ts +41 -0
  365. package/src/tools/__tests__/handlers.test.ts +2 -2
  366. package/src/tools/__tests__/hitl.test.ts +11 -11
  367. package/src/tools/__tests__/localToolNames.test.ts +8 -6
  368. package/src/tools/__tests__/skillCatalog.test.ts +1 -1
  369. package/src/tools/__tests__/subagentHooks.test.ts +20 -10
  370. package/src/tools/__tests__/workspaceSeam.test.ts +20 -7
  371. package/src/tools/cloudflare/CloudflareSandboxExecutionEngine.ts +9 -6
  372. package/src/tools/cloudflare/CloudflareSandboxTools.ts +19 -19
  373. package/src/tools/handlers.ts +5 -5
  374. package/src/tools/local/CompileCheckTool.ts +4 -7
  375. package/src/tools/local/FileCheckpointer.ts +6 -5
  376. package/src/tools/local/LocalCodingTools.ts +100 -45
  377. package/src/tools/local/LocalExecutionEngine.ts +5 -5
  378. package/src/tools/local/LocalExecutionTools.ts +9 -9
  379. package/src/tools/local/LocalProgrammaticToolCalling.ts +5 -4
  380. package/src/tools/local/attachments.ts +0 -6
  381. package/src/tools/local/resolveLocalExecutionTools.ts +15 -15
  382. package/src/tools/search/firecrawl.ts +1 -1
  383. package/src/tools/search/jina-reranker.test.ts +148 -37
  384. package/src/tools/search/rerankers.ts +14 -4
  385. package/src/tools/search/tavily-search.ts +2 -2
  386. package/src/tools/search/types.ts +1 -1
  387. package/src/tools/search/utils.ts +99 -9
  388. package/src/tools/subagent/SubagentExecutor.ts +12 -6
  389. package/src/types/graph.ts +12 -12
  390. package/src/types/llm.ts +7 -6
  391. package/src/types/messages.ts +1 -1
  392. package/src/types/run.ts +7 -7
  393. package/src/types/stream.ts +2 -2
  394. package/src/types/tools.ts +5 -1
  395. package/src/utils/handlers.ts +2 -2
  396. package/src/utils/llmConfig.ts +1 -1
  397. package/src/utils/logging.ts +20 -10
  398. package/src/utils/run.ts +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"cache.mjs","sources":["../../../src/messages/cache.ts"],"sourcesContent":["import {\n AIMessage,\n BaseMessage,\n ToolMessage,\n HumanMessage,\n SystemMessage,\n MessageContentComplex,\n} from '@langchain/core/messages';\nimport type { AnthropicMessage } from '@/types/messages';\nimport type Anthropic from '@anthropic-ai/sdk';\nimport { ContentTypes } from '@/common/enum';\nimport { toLangChainContent } from './langchain';\n\ntype MessageWithContent = {\n content?: string | MessageContentComplex[];\n};\n\ntype MessageContentWithCacheControl = MessageContentComplex & {\n cache_control?: unknown;\n};\n\n/**\n * Deep clones a message's content to prevent mutation of the original.\n */\nfunction deepCloneContent<T extends string | MessageContentComplex[]>(\n content: T\n): T {\n if (typeof content === 'string') {\n return content;\n }\n if (Array.isArray(content)) {\n return content.map((block) => ({ ...block })) as T;\n }\n return content;\n}\n\n/**\n * Clones a message with new content. For LangChain BaseMessage instances,\n * constructs a proper class instance so that `instanceof` checks are preserved\n * in downstream code (e.g., ensureThinkingBlockInMessages).\n * For plain objects (AnthropicMessage), uses object spread.\n */\nfunction cloneMessage<T extends MessageWithContent>(\n message: T,\n content: string | MessageContentComplex[]\n): T {\n if (message instanceof BaseMessage) {\n const baseParams = {\n content: toLangChainContent(content),\n additional_kwargs: { ...message.additional_kwargs },\n response_metadata: { ...message.response_metadata },\n id: message.id,\n name: message.name,\n };\n\n const msgType = message.getType();\n switch (msgType) {\n case 'ai':\n return new AIMessage({\n ...baseParams,\n tool_calls: (message as unknown as AIMessage).tool_calls,\n }) as unknown as T;\n case 'human':\n return new HumanMessage(baseParams) as unknown as T;\n case 'system':\n return new SystemMessage(baseParams) as unknown as T;\n case 'tool':\n return new ToolMessage({\n ...baseParams,\n tool_call_id: (message as unknown as ToolMessage).tool_call_id,\n }) as unknown as T;\n default:\n break;\n }\n }\n\n const {\n lc_kwargs: _lc_kwargs,\n lc_serializable: _lc_serializable,\n lc_namespace: _lc_namespace,\n ...rest\n } = message as T & {\n lc_kwargs?: unknown;\n lc_serializable?: unknown;\n lc_namespace?: unknown;\n };\n\n const cloned = { ...rest, content } as T;\n\n // LangChain messages don't have a direct 'role' property - derive it from getType()\n if (\n 'getType' in message &&\n typeof message.getType === 'function' &&\n !('role' in cloned)\n ) {\n const msgType = (message as unknown as BaseMessage).getType();\n const roleMap: Record<string, string> = {\n human: 'user',\n ai: 'assistant',\n system: 'system',\n tool: 'tool',\n };\n (cloned as Record<string, unknown>).role = roleMap[msgType] || msgType;\n }\n\n return cloned;\n}\n\nfunction stripAnthropicCacheControlFromBlocks(\n content: MessageContentComplex[]\n): { content: MessageContentComplex[]; modified: boolean } {\n let modified = false;\n const strippedContent = content.map((block) => {\n if (!('cache_control' in block)) {\n return block;\n }\n\n const cloned: MessageContentWithCacheControl = { ...block };\n delete cloned.cache_control;\n modified = true;\n return cloned;\n });\n\n return { content: strippedContent, modified };\n}\n\nfunction sanitizeBedrockSystemMessage<T extends MessageWithContent>(\n message: T\n): T {\n const content = message.content;\n if (!Array.isArray(content)) {\n return message;\n }\n\n const stripped = stripAnthropicCacheControlFromBlocks(content);\n if (!stripped.modified) {\n return message;\n }\n\n return cloneMessage(message, stripped.content);\n}\n\n/**\n * Anthropic API: Adds cache control to the appropriate user messages in the payload.\n * Strips ALL existing cache control (both Anthropic and Bedrock formats) from all messages,\n * then adds fresh cache control to the last 2 user messages in a single backward pass.\n * This ensures we don't accumulate stale cache points across multiple turns.\n * Returns a new array - only clones messages that require modification.\n * @param messages - The array of message objects.\n * @returns - A new array of message objects with cache control added.\n */\nexport function addCacheControl<T extends AnthropicMessage | BaseMessage>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages) || messages.length < 2) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n let userMessagesModified = 0;\n\n for (let i = updatedMessages.length - 1; i >= 0; i--) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n const isUserMessage =\n ('getType' in originalMessage && originalMessage.getType() === 'human') ||\n ('role' in originalMessage && originalMessage.role === 'user');\n const hasArrayContent = Array.isArray(content);\n const needsCacheAdd =\n userMessagesModified < 2 &&\n isUserMessage &&\n (typeof content === 'string' || hasArrayContent);\n\n // Skip messages that don't need any work\n if (!needsCacheAdd && !hasArrayContent) {\n continue;\n }\n\n let workingContent: MessageContentComplex[];\n let modified = false;\n\n if (hasArrayContent) {\n // Single pass: clone blocks, strip cache markers and cache points,\n // find last text block index for cache insertion — all at once.\n const src = content as MessageContentComplex[];\n workingContent = [];\n let lastTextIndex = -1;\n for (let j = 0; j < src.length; j++) {\n const block = src[j];\n if (isCachePoint(block)) {\n modified = true;\n continue; // skip cache point blocks\n }\n const cloned = { ...block };\n if ('cache_control' in cloned) {\n delete (cloned as Record<string, unknown>).cache_control;\n modified = true;\n }\n if ('type' in cloned && cloned.type === 'text') {\n lastTextIndex = workingContent.length;\n }\n workingContent.push(cloned as MessageContentComplex);\n }\n\n if (!modified && !needsCacheAdd) {\n continue; // nothing to strip and no cache to add\n }\n\n // Add cache control to the last text block for user messages\n if (needsCacheAdd && lastTextIndex >= 0) {\n (\n workingContent[lastTextIndex] as Anthropic.TextBlockParam\n ).cache_control = {\n type: 'ephemeral',\n };\n userMessagesModified++;\n }\n } else if (typeof content === 'string' && needsCacheAdd) {\n workingContent = [\n { type: 'text', text: content, cache_control: { type: 'ephemeral' } },\n ] as unknown as MessageContentComplex[];\n userMessagesModified++;\n } else {\n continue;\n }\n\n updatedMessages[i] = cloneMessage(\n originalMessage as MessageWithContent,\n workingContent\n ) as T;\n }\n\n return updatedMessages;\n}\n\n/**\n * Checks if a content block is a cache point\n */\nfunction isCachePoint(block: MessageContentComplex): boolean {\n return 'cachePoint' in block && !('type' in block);\n}\n\nfunction getMessageRole(message: MessageWithContent): string | undefined {\n if (message instanceof BaseMessage) {\n return message.getType();\n }\n if ('role' in message && typeof message.role === 'string') {\n return message.role;\n }\n return undefined;\n}\n\nfunction isCacheableConversationMessage(message: MessageWithContent): boolean {\n const role = getMessageRole(message);\n return (\n role === 'human' || role === 'user' || role === 'ai' || role === 'assistant'\n );\n}\n\nfunction isAssistantConversationMessage(message: MessageWithContent): boolean {\n const role = getMessageRole(message);\n return role === 'ai' || role === 'assistant';\n}\n\nfunction hasCacheMarker(message: MessageWithContent): boolean {\n return (\n Array.isArray(message.content) &&\n message.content.some((block) => 'cache_control' in block)\n );\n}\n\nfunction addCacheControlToRecentMessages<\n T extends AnthropicMessage | BaseMessage,\n>(\n messages: T[],\n maxCachePoints: number,\n canUseMessage: (message: MessageWithContent) => boolean\n): T[] {\n if (\n !Array.isArray(messages) ||\n messages.length === 0 ||\n maxCachePoints <= 0\n ) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n let cachePointsAdded = 0;\n\n for (let i = updatedMessages.length - 1; i >= 0; i--) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n const hasArrayContent = Array.isArray(content);\n const canAddCache =\n cachePointsAdded < maxCachePoints && canUseMessage(originalMessage);\n\n if (!canAddCache && !hasArrayContent) {\n continue;\n }\n\n let workingContent: MessageContentComplex[];\n let modified = false;\n\n if (hasArrayContent) {\n const src = content as MessageContentComplex[];\n workingContent = [];\n let lastNonEmptyTextIndex = -1;\n\n for (let j = 0; j < src.length; j++) {\n const block = src[j];\n if (isCachePoint(block)) {\n modified = true;\n continue;\n }\n\n const cloned = { ...block };\n if ('cache_control' in cloned) {\n delete (cloned as Record<string, unknown>).cache_control;\n modified = true;\n }\n\n if ('type' in cloned && cloned.type === 'text') {\n const text = (cloned as { text?: string }).text;\n if (text != null && text.trim() !== '') {\n lastNonEmptyTextIndex = workingContent.length;\n }\n }\n workingContent.push(cloned as MessageContentComplex);\n }\n\n if (canAddCache && lastNonEmptyTextIndex >= 0) {\n (\n workingContent[lastNonEmptyTextIndex] as Anthropic.TextBlockParam\n ).cache_control = {\n type: 'ephemeral',\n };\n cachePointsAdded++;\n modified = true;\n }\n\n if (!modified) {\n continue;\n }\n } else if (\n typeof content === 'string' &&\n content.trim() !== '' &&\n canAddCache\n ) {\n workingContent = [\n { type: 'text', text: content, cache_control: { type: 'ephemeral' } },\n ] as unknown as MessageContentComplex[];\n cachePointsAdded++;\n } else {\n continue;\n }\n\n updatedMessages[i] = cloneMessage(\n originalMessage as MessageWithContent,\n workingContent\n ) as T;\n }\n\n return updatedMessages;\n}\n\nexport function addCacheControlToStablePrefixMessages<\n T extends AnthropicMessage | BaseMessage,\n>(messages: T[], maxCachePoints: number): T[] {\n const assistantMarked = addCacheControlToRecentMessages(\n messages,\n maxCachePoints,\n isAssistantConversationMessage\n );\n\n if (assistantMarked.some(hasCacheMarker)) {\n return assistantMarked;\n }\n\n return addCacheControlToRecentMessages(\n messages,\n maxCachePoints,\n isCacheableConversationMessage\n );\n}\n\n/**\n * Checks if a message's content has Anthropic cache_control fields.\n */\nfunction hasAnthropicCacheControl(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n if ('cache_control' in content[i]) return true;\n }\n return false;\n}\n\n/**\n * Removes all Anthropic cache_control fields from messages\n * Used when switching from Anthropic to Bedrock provider\n * Returns a new array - only clones messages that require modification.\n */\nexport function stripAnthropicCacheControl<T extends MessageWithContent>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages)) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n\n for (let i = 0; i < updatedMessages.length; i++) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n\n if (!Array.isArray(content) || !hasAnthropicCacheControl(content)) {\n continue;\n }\n\n const clonedContent = deepCloneContent(content);\n for (let j = 0; j < clonedContent.length; j++) {\n const block = clonedContent[j] as Record<string, unknown>;\n if ('cache_control' in block) {\n delete block.cache_control;\n }\n }\n updatedMessages[i] = cloneMessage(originalMessage, clonedContent);\n }\n\n return updatedMessages;\n}\n\n/**\n * Checks if a message's content has Bedrock cachePoint blocks.\n */\nfunction hasBedrockCachePoint(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n if (isCachePoint(content[i])) return true;\n }\n return false;\n}\n\n/**\n * Removes all Bedrock cachePoint blocks from messages\n * Used when switching from Bedrock to Anthropic provider\n * Returns a new array - only clones messages that require modification.\n */\nexport function stripBedrockCacheControl<T extends MessageWithContent>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages)) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n\n for (let i = 0; i < updatedMessages.length; i++) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n\n if (!Array.isArray(content) || !hasBedrockCachePoint(content)) {\n continue;\n }\n\n const clonedContent = deepCloneContent(content).filter(\n (block) => !isCachePoint(block as MessageContentComplex)\n );\n updatedMessages[i] = cloneMessage(originalMessage, clonedContent);\n }\n\n return updatedMessages;\n}\n\n/**\n * Adds Bedrock Converse API cache points to the latest two user messages.\n * Inserts `{ cachePoint: { type: 'default' } }` as a separate content block\n * immediately after the last text block in each targeted message.\n * Strips ALL existing cache control (both Bedrock and Anthropic formats) from all messages,\n * then adds fresh cache points to the latest two non-tool user messages in a single backward pass.\n * This ensures we don't accumulate stale cache points across multiple turns.\n * Returns a new array - only clones messages that require modification.\n * @param messages - The array of message objects.\n * @returns - A new array of message objects with cache points added.\n */\nexport function addBedrockCacheControl<\n T extends MessageWithContent & { getType?: () => string; role?: string },\n>(messages: T[]): T[] {\n if (!Array.isArray(messages) || messages.length === 0) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n let cachePointsAdded = 0;\n\n for (let i = updatedMessages.length - 1; i >= 0; i--) {\n const originalMessage = updatedMessages[i];\n const messageType =\n 'getType' in originalMessage &&\n typeof originalMessage.getType === 'function'\n ? originalMessage.getType()\n : undefined;\n const messageRole =\n 'role' in originalMessage && typeof originalMessage.role === 'string'\n ? originalMessage.role\n : undefined;\n\n const isSystemMessage =\n messageType === 'system' || messageRole === 'system';\n if (isSystemMessage) {\n updatedMessages[i] = sanitizeBedrockSystemMessage(originalMessage);\n continue;\n }\n\n const isToolMessage = messageType === 'tool' || messageRole === 'tool';\n const isUserMessage = messageType === 'human' || messageRole === 'user';\n const content = originalMessage.content;\n const hasSerializationProps =\n 'lc_kwargs' in originalMessage ||\n 'lc_serializable' in originalMessage ||\n 'lc_namespace' in originalMessage;\n const hasArrayContent = Array.isArray(content);\n const isEmptyString = typeof content === 'string' && content === '';\n const needsCacheAdd =\n cachePointsAdded < 2 &&\n isUserMessage &&\n !isToolMessage &&\n !isEmptyString &&\n (typeof content === 'string' || hasArrayContent);\n\n if (!needsCacheAdd && !hasArrayContent && !hasSerializationProps) {\n continue;\n }\n\n let workingContent: string | MessageContentComplex[];\n let modified = hasSerializationProps;\n\n if (hasArrayContent) {\n // Single pass: clone blocks, strip cache markers, find last\n // non-empty text block for cache point insertion — all at once.\n const src = content as MessageContentComplex[];\n workingContent = [];\n let lastNonEmptyTextIndex = -1;\n for (let j = 0; j < src.length; j++) {\n const block = src[j];\n if (isCachePoint(block)) {\n modified = true;\n continue;\n }\n const cloned = { ...block };\n if ('cache_control' in cloned) {\n delete (cloned as Record<string, unknown>).cache_control;\n modified = true;\n }\n const type = (cloned as { type?: string }).type;\n if (type === ContentTypes.TEXT || type === 'text') {\n const text = (cloned as { text?: string }).text;\n if (text != null && text.trim() !== '') {\n lastNonEmptyTextIndex = workingContent.length;\n }\n }\n workingContent.push(cloned as MessageContentComplex);\n }\n\n if (!modified && !needsCacheAdd) {\n continue;\n }\n\n // Insert cache point after the last non-empty text block.\n // Skip if no cacheable text content exists (whitespace-only messages).\n if (needsCacheAdd && lastNonEmptyTextIndex >= 0) {\n workingContent.splice(lastNonEmptyTextIndex + 1, 0, {\n cachePoint: { type: 'default' },\n } as MessageContentComplex);\n cachePointsAdded++;\n }\n } else if (typeof content === 'string' && needsCacheAdd) {\n workingContent = [\n { type: ContentTypes.TEXT, text: content },\n { cachePoint: { type: 'default' } } as MessageContentComplex,\n ];\n cachePointsAdded++;\n } else if (typeof content === 'string' && hasSerializationProps) {\n workingContent = content;\n } else {\n continue;\n }\n\n updatedMessages[i] = cloneMessage(originalMessage, workingContent);\n }\n\n return updatedMessages;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cache.mjs","sources":["../../../src/messages/cache.ts"],"sourcesContent":["import {\n AIMessage,\n BaseMessage,\n ToolMessage,\n HumanMessage,\n SystemMessage,\n MessageContentComplex,\n} from '@langchain/core/messages';\nimport type Anthropic from '@anthropic-ai/sdk';\nimport type { AnthropicMessage } from '@/types/messages';\nimport { toLangChainContent } from './langchain';\nimport { ContentTypes } from '@/common/enum';\nimport { withMessageRole } from './format';\n\ntype MessageWithContent = {\n content?: string | MessageContentComplex[];\n};\n\ntype MessageContentWithCacheControl = MessageContentComplex & {\n cache_control?: unknown;\n};\n\n/**\n * Deep clones a message's content to prevent mutation of the original.\n */\nfunction deepCloneContent<T extends string | MessageContentComplex[]>(\n content: T\n): T {\n if (typeof content === 'string') {\n return content;\n }\n if (Array.isArray(content)) {\n return content.map((block) => ({ ...block })) as T;\n }\n return content;\n}\n\n/**\n * Clones a message with new content. For LangChain BaseMessage instances,\n * constructs a proper class instance so that `instanceof` checks are preserved\n * in downstream code (e.g., ensureThinkingBlockInMessages).\n * For plain objects (AnthropicMessage), uses object spread.\n */\nfunction cloneMessage<T extends MessageWithContent>(\n message: T,\n content: string | MessageContentComplex[]\n): T {\n if (message instanceof BaseMessage) {\n const baseParams = {\n content: toLangChainContent(content),\n additional_kwargs: { ...message.additional_kwargs },\n response_metadata: { ...message.response_metadata },\n id: message.id,\n name: message.name,\n };\n\n const msgType = message.getType();\n switch (msgType) {\n case 'ai':\n return withMessageRole(\n new AIMessage({\n ...baseParams,\n tool_calls: (message as unknown as AIMessage).tool_calls,\n }),\n 'assistant'\n ) as unknown as T;\n case 'human':\n return withMessageRole(\n new HumanMessage(baseParams),\n 'user'\n ) as unknown as T;\n case 'system':\n return withMessageRole(\n new SystemMessage(baseParams),\n 'system'\n ) as unknown as T;\n case 'tool':\n return withMessageRole(\n new ToolMessage({\n ...baseParams,\n tool_call_id: (message as unknown as ToolMessage).tool_call_id,\n }),\n 'tool'\n ) as unknown as T;\n default:\n break;\n }\n }\n\n const {\n lc_kwargs: _lc_kwargs,\n lc_serializable: _lc_serializable,\n lc_namespace: _lc_namespace,\n ...rest\n } = message as T & {\n lc_kwargs?: unknown;\n lc_serializable?: unknown;\n lc_namespace?: unknown;\n };\n\n const cloned = { ...rest, content } as T;\n\n // LangChain messages don't have a direct 'role' property - derive it from getType()\n if (\n 'getType' in message &&\n typeof message.getType === 'function' &&\n !('role' in cloned)\n ) {\n const msgType = (message as unknown as BaseMessage).getType();\n const roleMap: Record<string, string> = {\n human: 'user',\n ai: 'assistant',\n system: 'system',\n tool: 'tool',\n };\n (cloned as Record<string, unknown>).role = roleMap[msgType] || msgType;\n }\n\n return cloned;\n}\n\nfunction stripAnthropicCacheControlFromBlocks(\n content: MessageContentComplex[]\n): { content: MessageContentComplex[]; modified: boolean } {\n let modified = false;\n const strippedContent = content.map((block) => {\n if (!('cache_control' in block)) {\n return block;\n }\n\n const cloned: MessageContentWithCacheControl = { ...block };\n delete cloned.cache_control;\n modified = true;\n return cloned;\n });\n\n return { content: strippedContent, modified };\n}\n\nfunction sanitizeBedrockSystemMessage<T extends MessageWithContent>(\n message: T\n): T {\n const content = message.content;\n if (!Array.isArray(content)) {\n return message;\n }\n\n const stripped = stripAnthropicCacheControlFromBlocks(content);\n if (!stripped.modified) {\n return message;\n }\n\n return cloneMessage(message, stripped.content);\n}\n\n/**\n * Anthropic API: Adds cache control to the appropriate user messages in the payload.\n * Strips ALL existing cache control (both Anthropic and Bedrock formats) from all messages,\n * then adds fresh cache control to the last 2 user messages in a single backward pass.\n * This ensures we don't accumulate stale cache points across multiple turns.\n * Returns a new array - only clones messages that require modification.\n * @param messages - The array of message objects.\n * @returns - A new array of message objects with cache control added.\n */\nexport function addCacheControl<T extends AnthropicMessage | BaseMessage>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages) || messages.length < 2) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n let userMessagesModified = 0;\n\n for (let i = updatedMessages.length - 1; i >= 0; i--) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n const isUserMessage =\n ('getType' in originalMessage && originalMessage.getType() === 'human') ||\n ('role' in originalMessage && originalMessage.role === 'user');\n const hasArrayContent = Array.isArray(content);\n const needsCacheAdd =\n userMessagesModified < 2 &&\n isUserMessage &&\n (typeof content === 'string' || hasArrayContent);\n\n // Skip messages that don't need any work\n if (!needsCacheAdd && !hasArrayContent) {\n continue;\n }\n\n let workingContent: MessageContentComplex[];\n let modified = false;\n\n if (hasArrayContent) {\n // Single pass: clone blocks, strip cache markers and cache points,\n // find last text block index for cache insertion — all at once.\n const src = content as MessageContentComplex[];\n workingContent = [];\n let lastTextIndex = -1;\n for (let j = 0; j < src.length; j++) {\n const block = src[j];\n if (isCachePoint(block)) {\n modified = true;\n continue; // skip cache point blocks\n }\n const cloned = { ...block };\n if ('cache_control' in cloned) {\n delete (cloned as Record<string, unknown>).cache_control;\n modified = true;\n }\n if ('type' in cloned && cloned.type === 'text') {\n lastTextIndex = workingContent.length;\n }\n workingContent.push(cloned as MessageContentComplex);\n }\n\n if (!modified && !needsCacheAdd) {\n continue; // nothing to strip and no cache to add\n }\n\n // Add cache control to the last text block for user messages\n if (needsCacheAdd && lastTextIndex >= 0) {\n (\n workingContent[lastTextIndex] as Anthropic.TextBlockParam\n ).cache_control = {\n type: 'ephemeral',\n };\n userMessagesModified++;\n }\n } else if (typeof content === 'string' && needsCacheAdd) {\n workingContent = [\n { type: 'text', text: content, cache_control: { type: 'ephemeral' } },\n ] as unknown as MessageContentComplex[];\n userMessagesModified++;\n } else {\n continue;\n }\n\n updatedMessages[i] = cloneMessage(\n originalMessage as MessageWithContent,\n workingContent\n ) as T;\n }\n\n return updatedMessages;\n}\n\n/**\n * Checks if a content block is a cache point\n */\nfunction isCachePoint(block: MessageContentComplex): boolean {\n return 'cachePoint' in block && !('type' in block);\n}\n\nfunction getMessageRole(message: MessageWithContent): string | undefined {\n if (message instanceof BaseMessage) {\n return message.getType();\n }\n if ('role' in message && typeof message.role === 'string') {\n return message.role;\n }\n return undefined;\n}\n\nfunction isCacheableConversationMessage(message: MessageWithContent): boolean {\n const role = getMessageRole(message);\n return (\n role === 'human' || role === 'user' || role === 'ai' || role === 'assistant'\n );\n}\n\nfunction isAssistantConversationMessage(message: MessageWithContent): boolean {\n const role = getMessageRole(message);\n return role === 'ai' || role === 'assistant';\n}\n\nfunction hasCacheMarker(message: MessageWithContent): boolean {\n return (\n Array.isArray(message.content) &&\n message.content.some((block) => 'cache_control' in block)\n );\n}\n\nfunction addCacheControlToRecentMessages<\n T extends AnthropicMessage | BaseMessage,\n>(\n messages: T[],\n maxCachePoints: number,\n canUseMessage: (message: MessageWithContent) => boolean\n): T[] {\n if (\n !Array.isArray(messages) ||\n messages.length === 0 ||\n maxCachePoints <= 0\n ) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n let cachePointsAdded = 0;\n\n for (let i = updatedMessages.length - 1; i >= 0; i--) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n const hasArrayContent = Array.isArray(content);\n const canAddCache =\n cachePointsAdded < maxCachePoints && canUseMessage(originalMessage);\n\n if (!canAddCache && !hasArrayContent) {\n continue;\n }\n\n let workingContent: MessageContentComplex[];\n let modified = false;\n\n if (hasArrayContent) {\n const src = content as MessageContentComplex[];\n workingContent = [];\n let lastNonEmptyTextIndex = -1;\n\n for (let j = 0; j < src.length; j++) {\n const block = src[j];\n if (isCachePoint(block)) {\n modified = true;\n continue;\n }\n\n const cloned = { ...block };\n if ('cache_control' in cloned) {\n delete (cloned as Record<string, unknown>).cache_control;\n modified = true;\n }\n\n if ('type' in cloned && cloned.type === 'text') {\n const text = (cloned as { text?: string }).text;\n if (text != null && text.trim() !== '') {\n lastNonEmptyTextIndex = workingContent.length;\n }\n }\n workingContent.push(cloned as MessageContentComplex);\n }\n\n if (canAddCache && lastNonEmptyTextIndex >= 0) {\n (\n workingContent[lastNonEmptyTextIndex] as Anthropic.TextBlockParam\n ).cache_control = {\n type: 'ephemeral',\n };\n cachePointsAdded++;\n modified = true;\n }\n\n if (!modified) {\n continue;\n }\n } else if (\n typeof content === 'string' &&\n content.trim() !== '' &&\n canAddCache\n ) {\n workingContent = [\n { type: 'text', text: content, cache_control: { type: 'ephemeral' } },\n ] as unknown as MessageContentComplex[];\n cachePointsAdded++;\n } else {\n continue;\n }\n\n updatedMessages[i] = cloneMessage(\n originalMessage as MessageWithContent,\n workingContent\n ) as T;\n }\n\n return updatedMessages;\n}\n\nexport function addCacheControlToStablePrefixMessages<\n T extends AnthropicMessage | BaseMessage,\n>(messages: T[], maxCachePoints: number): T[] {\n const assistantMarked = addCacheControlToRecentMessages(\n messages,\n maxCachePoints,\n isAssistantConversationMessage\n );\n\n if (assistantMarked.some(hasCacheMarker)) {\n return assistantMarked;\n }\n\n return addCacheControlToRecentMessages(\n messages,\n maxCachePoints,\n isCacheableConversationMessage\n );\n}\n\n/**\n * Checks if a message's content has Anthropic cache_control fields.\n */\nfunction hasAnthropicCacheControl(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n if ('cache_control' in content[i]) return true;\n }\n return false;\n}\n\n/**\n * Removes all Anthropic cache_control fields from messages\n * Used when switching from Anthropic to Bedrock provider\n * Returns a new array - only clones messages that require modification.\n */\nexport function stripAnthropicCacheControl<T extends MessageWithContent>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages)) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n\n for (let i = 0; i < updatedMessages.length; i++) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n\n if (!Array.isArray(content) || !hasAnthropicCacheControl(content)) {\n continue;\n }\n\n const clonedContent = deepCloneContent(content);\n for (let j = 0; j < clonedContent.length; j++) {\n const block = clonedContent[j] as Record<string, unknown>;\n if ('cache_control' in block) {\n delete block.cache_control;\n }\n }\n updatedMessages[i] = cloneMessage(originalMessage, clonedContent);\n }\n\n return updatedMessages;\n}\n\n/**\n * Checks if a message's content has Bedrock cachePoint blocks.\n */\nfunction hasBedrockCachePoint(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n if (isCachePoint(content[i])) return true;\n }\n return false;\n}\n\n/**\n * Removes all Bedrock cachePoint blocks from messages\n * Used when switching from Bedrock to Anthropic provider\n * Returns a new array - only clones messages that require modification.\n */\nexport function stripBedrockCacheControl<T extends MessageWithContent>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages)) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n\n for (let i = 0; i < updatedMessages.length; i++) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n\n if (!Array.isArray(content) || !hasBedrockCachePoint(content)) {\n continue;\n }\n\n const clonedContent = deepCloneContent(content).filter(\n (block) => !isCachePoint(block as MessageContentComplex)\n );\n updatedMessages[i] = cloneMessage(originalMessage, clonedContent);\n }\n\n return updatedMessages;\n}\n\n/**\n * Adds Bedrock Converse API cache points to the latest two user messages.\n * Inserts `{ cachePoint: { type: 'default' } }` as a separate content block\n * immediately after the last text block in each targeted message.\n * Strips ALL existing cache control (both Bedrock and Anthropic formats) from all messages,\n * then adds fresh cache points to the latest two non-tool user messages in a single backward pass.\n * This ensures we don't accumulate stale cache points across multiple turns.\n * Returns a new array - only clones messages that require modification.\n * @param messages - The array of message objects.\n * @returns - A new array of message objects with cache points added.\n */\nexport function addBedrockCacheControl<\n T extends MessageWithContent & { getType?: () => string; role?: string },\n>(messages: T[]): T[] {\n if (!Array.isArray(messages) || messages.length === 0) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n let cachePointsAdded = 0;\n\n for (let i = updatedMessages.length - 1; i >= 0; i--) {\n const originalMessage = updatedMessages[i];\n const messageType =\n 'getType' in originalMessage &&\n typeof originalMessage.getType === 'function'\n ? originalMessage.getType()\n : undefined;\n const messageRole =\n 'role' in originalMessage && typeof originalMessage.role === 'string'\n ? originalMessage.role\n : undefined;\n\n const isSystemMessage =\n messageType === 'system' || messageRole === 'system';\n if (isSystemMessage) {\n updatedMessages[i] = sanitizeBedrockSystemMessage(originalMessage);\n continue;\n }\n\n const isToolMessage = messageType === 'tool' || messageRole === 'tool';\n const isUserMessage = messageType === 'human' || messageRole === 'user';\n const content = originalMessage.content;\n const hasSerializationProps =\n 'lc_kwargs' in originalMessage ||\n 'lc_serializable' in originalMessage ||\n 'lc_namespace' in originalMessage;\n const hasArrayContent = Array.isArray(content);\n const isEmptyString = typeof content === 'string' && content === '';\n const needsCacheAdd =\n cachePointsAdded < 2 &&\n isUserMessage &&\n !isToolMessage &&\n !isEmptyString &&\n (typeof content === 'string' || hasArrayContent);\n\n if (!needsCacheAdd && !hasArrayContent && !hasSerializationProps) {\n continue;\n }\n\n let workingContent: string | MessageContentComplex[];\n let modified = hasSerializationProps;\n\n if (hasArrayContent) {\n // Single pass: clone blocks, strip cache markers, find last\n // non-empty text block for cache point insertion — all at once.\n const src = content as MessageContentComplex[];\n workingContent = [];\n let lastNonEmptyTextIndex = -1;\n for (let j = 0; j < src.length; j++) {\n const block = src[j];\n if (isCachePoint(block)) {\n modified = true;\n continue;\n }\n const cloned = { ...block };\n if ('cache_control' in cloned) {\n delete (cloned as Record<string, unknown>).cache_control;\n modified = true;\n }\n const type = (cloned as { type?: string }).type;\n if (type === ContentTypes.TEXT || type === 'text') {\n const text = (cloned as { text?: string }).text;\n if (text != null && text.trim() !== '') {\n lastNonEmptyTextIndex = workingContent.length;\n }\n }\n workingContent.push(cloned as MessageContentComplex);\n }\n\n if (!modified && !needsCacheAdd) {\n continue;\n }\n\n // Insert cache point after the last non-empty text block.\n // Skip if no cacheable text content exists (whitespace-only messages).\n if (needsCacheAdd && lastNonEmptyTextIndex >= 0) {\n workingContent.splice(lastNonEmptyTextIndex + 1, 0, {\n cachePoint: { type: 'default' },\n } as MessageContentComplex);\n cachePointsAdded++;\n }\n } else if (typeof content === 'string' && needsCacheAdd) {\n workingContent = [\n { type: ContentTypes.TEXT, text: content },\n { cachePoint: { type: 'default' } } as MessageContentComplex,\n ];\n cachePointsAdded++;\n } else if (typeof content === 'string' && hasSerializationProps) {\n workingContent = content;\n } else {\n continue;\n }\n\n updatedMessages[i] = cloneMessage(originalMessage, workingContent);\n }\n\n return updatedMessages;\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"content.mjs","sources":["../../../src/messages/content.ts"],"sourcesContent":["import { ContentTypes } from '@/common';\nimport type { BaseMessage } from '@langchain/core/messages';\n\n/**\n * Formats an array of messages for LangChain, making sure all content fields are strings\n * @param {Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>} payload - The array of messages to format.\n * @returns {Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>} - The array of formatted LangChain messages, including ToolMessages for tool calls.\n */\nexport const formatContentStrings = (\n payload: Array<BaseMessage>\n): Array<BaseMessage> => {\n // Create a new array to store the processed messages\n const result: Array<BaseMessage> = [];\n\n for (const message of payload) {\n const messageType = message.getType();\n const isValidMessage =\n messageType === 'human' ||\n messageType === 'ai' ||\n messageType === 'system';\n\n if (!isValidMessage) {\n result.push(message);\n continue;\n }\n\n // If content is already a string, add as-is\n if (typeof message.content === 'string') {\n result.push(message);\n continue;\n }\n\n // If content is not an array, add as-is\n if (!Array.isArray(message.content)) {\n result.push(message);\n continue;\n }\n\n // Check if all content blocks are text type\n const allTextBlocks = message.content.every(\n (block) => block.type === ContentTypes.TEXT\n );\n\n // Only convert to string if all blocks are text type\n if (!allTextBlocks) {\n result.push(message);\n continue;\n }\n\n // Reduce text types to a single string\n const content = message.content.reduce((acc, curr) => {\n if (curr.type === ContentTypes.TEXT) {\n return `${acc}${curr[ContentTypes.TEXT] || ''}\\n`;\n }\n return acc;\n }, '');\n\n message.content = content.trim();\n result.push(message);\n }\n\n return result;\n};\n"],"names":[],"mappings":";;AAGA;;;;AAIG;AACI,MAAM,oBAAoB,GAAG,CAClC,OAA2B,KACL;;IAEtB,MAAM,MAAM,GAAuB,EAAE;AAErC,IAAA,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE;AAC7B,QAAA,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE;AACrC,QAAA,MAAM,cAAc,GAClB,WAAW,KAAK,OAAO;AACvB,YAAA,WAAW,KAAK,IAAI;YACpB,WAAW,KAAK,QAAQ;QAE1B,IAAI,CAAC,cAAc,EAAE;AACnB,YAAA,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;YACpB;QACF;;AAGA,QAAA,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,EAAE;AACvC,YAAA,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;YACpB;QACF;;QAGA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;AACnC,YAAA,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;YACpB;QACF;;QAGA,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CACzC,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,IAAI,CAC5C;;QAGD,IAAI,CAAC,aAAa,EAAE;AAClB,YAAA,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;YACpB;QACF;;AAGA,QAAA,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,KAAI;YACnD,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,CAAC,IAAI,EAAE;AACnC,gBAAA,OAAO,CAAA,EAAG,GAAG,CAAA,EAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA,EAAA,CAAI;YACnD;AACA,YAAA,OAAO,GAAG;QACZ,CAAC,EAAE,EAAE,CAAC;AAEN,QAAA,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE;AAChC,QAAA,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;IACtB;AAEA,IAAA,OAAO,MAAM;AACf;;;;"}
1
+ {"version":3,"file":"content.mjs","sources":["../../../src/messages/content.ts"],"sourcesContent":["import type { BaseMessage } from '@langchain/core/messages';\nimport { ContentTypes } from '@/common';\n\n/**\n * Formats an array of messages for LangChain, making sure all content fields are strings\n * @param {Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>} payload - The array of messages to format.\n * @returns {Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>} - The array of formatted LangChain messages, including ToolMessages for tool calls.\n */\nexport const formatContentStrings = (\n payload: Array<BaseMessage>\n): Array<BaseMessage> => {\n // Create a new array to store the processed messages\n const result: Array<BaseMessage> = [];\n\n for (const message of payload) {\n const messageType = message.getType();\n const isValidMessage =\n messageType === 'human' ||\n messageType === 'ai' ||\n messageType === 'system';\n\n if (!isValidMessage) {\n result.push(message);\n continue;\n }\n\n // If content is already a string, add as-is\n if (typeof message.content === 'string') {\n result.push(message);\n continue;\n }\n\n // If content is not an array, add as-is\n if (!Array.isArray(message.content)) {\n result.push(message);\n continue;\n }\n\n // Check if all content blocks are text type\n const allTextBlocks = message.content.every(\n (block) => block.type === ContentTypes.TEXT\n );\n\n // Only convert to string if all blocks are text type\n if (!allTextBlocks) {\n result.push(message);\n continue;\n }\n\n // Reduce text types to a single string\n const content = message.content.reduce((acc, curr) => {\n if (curr.type === ContentTypes.TEXT) {\n return `${acc}${curr[ContentTypes.TEXT] || ''}\\n`;\n }\n return acc;\n }, '');\n\n message.content = content.trim();\n result.push(message);\n }\n\n return result;\n};\n"],"names":[],"mappings":";;AAGA;;;;AAIG;AACI,MAAM,oBAAoB,GAAG,CAClC,OAA2B,KACL;;IAEtB,MAAM,MAAM,GAAuB,EAAE;AAErC,IAAA,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE;AAC7B,QAAA,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE;AACrC,QAAA,MAAM,cAAc,GAClB,WAAW,KAAK,OAAO;AACvB,YAAA,WAAW,KAAK,IAAI;YACpB,WAAW,KAAK,QAAQ;QAE1B,IAAI,CAAC,cAAc,EAAE;AACnB,YAAA,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;YACpB;QACF;;AAGA,QAAA,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,EAAE;AACvC,YAAA,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;YACpB;QACF;;QAGA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;AACnC,YAAA,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;YACpB;QACF;;QAGA,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CACzC,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,IAAI,CAC5C;;QAGD,IAAI,CAAC,aAAa,EAAE;AAClB,YAAA,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;YACpB;QACF;;AAGA,QAAA,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,KAAI;YACnD,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,CAAC,IAAI,EAAE;AACnC,gBAAA,OAAO,CAAA,EAAG,GAAG,CAAA,EAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA,EAAA,CAAI;YACnD;AACA,YAAA,OAAO,GAAG;QACZ,CAAC,EAAE,EAAE,CAAC;AAEN,QAAA,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE;AAChC,QAAA,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;IACtB;AAEA,IAAA,OAAO,MAAM;AACf;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"contextPruning.mjs","sources":["../../../src/messages/contextPruning.ts"],"sourcesContent":["/**\n * Position-based context pruning for tool results.\n *\n * Uses position-based age: the distance of a message\n * from the conversation end as a fraction of total messages.\n *\n * Two degradation levels:\n * - Soft-trim: Keep head + tail of tool result content, drop middle.\n * - Hard-clear: Replace entire content with a placeholder.\n *\n * Messages in the \"protected zone\" (recent assistant turns, system/pre-first-human\n * messages, and messages with image content) are never pruned.\n */\n\nimport { ToolMessage, type BaseMessage } from '@langchain/core/messages';\nimport type { ContextPruningConfig } from '@/types/graph';\nimport type { TokenCounter } from '@/types/run';\nimport type { ContextPruningSettings } from './contextPruningSettings';\nimport { resolveContextPruningSettings } from './contextPruningSettings';\n\n/**\n * Checks if a message contains image content blocks.\n * Messages with images are skipped by position-based content degradation\n * because images cannot be meaningfully soft-trimmed or replaced with placeholders.\n */\nfunction hasImageContent(message: BaseMessage): boolean {\n if (!Array.isArray(message.content)) {\n return false;\n }\n return message.content.some(\n (block) =>\n typeof block === 'object' &&\n 'type' in block &&\n (block.type === 'image_url' || block.type === 'image')\n );\n}\n\n/**\n * Applies head+tail soft-trim to tool result content.\n */\nfunction softTrimContent(\n content: string,\n settings: ContextPruningSettings['softTrim']\n): string {\n const { headChars, tailChars } = settings;\n const indicator = `\\n\\n… [soft-trimmed: ${content.length} chars → ${headChars + tailChars} chars, middle removed] …\\n\\n`;\n return content.slice(0, headChars) + indicator + content.slice(-tailChars);\n}\n\nexport interface ContextPruningResult {\n /** Number of messages that were soft-trimmed. */\n softTrimmed: number;\n /** Number of messages that were hard-cleared. */\n hardCleared: number;\n}\n\n/**\n * Applies position-based context pruning to tool result messages.\n *\n * Modifies messages in-place and updates indexTokenCountMap with recounted\n * token values for modified messages.\n *\n * @param params.messages - The full message array (modified in-place).\n * @param params.indexTokenCountMap - Token count map (updated in-place).\n * @param params.tokenCounter - Function to recount tokens after modification.\n * @param params.config - Partial context pruning config (merged with defaults).\n * @returns Counts of soft-trimmed and hard-cleared messages.\n */\nexport function applyContextPruning(params: {\n messages: BaseMessage[];\n indexTokenCountMap: Record<string, number | undefined>;\n tokenCounter: TokenCounter;\n config?: ContextPruningConfig;\n resolvedSettings?: ContextPruningSettings;\n}): ContextPruningResult {\n const {\n messages,\n indexTokenCountMap,\n tokenCounter,\n config,\n resolvedSettings,\n } = params;\n const settings = resolvedSettings ?? resolveContextPruningSettings(config);\n\n if (!settings.enabled || messages.length === 0) {\n return { softTrimmed: 0, hardCleared: 0 };\n }\n\n const totalMessages = messages.length;\n let softTrimmed = 0;\n let hardCleared = 0;\n\n // Find the protected zone: last N assistant turns from the end.\n // An \"assistant turn\" is a contiguous sequence of AI + Tool messages.\n const protectedIndices = new Set<number>();\n\n // Always protect the system message (index 0 if present)\n if (messages[0]?.getType() === 'system') {\n protectedIndices.add(0);\n }\n\n // Protect messages before the first human message\n for (let i = 0; i < totalMessages; i++) {\n if (messages[i].getType() === 'human') {\n break;\n }\n protectedIndices.add(i);\n }\n\n // Protect the last N assistant turns (walking backwards)\n let assistantTurnsFound = 0;\n let inAssistantSequence = false;\n for (let i = totalMessages - 1; i >= 0; i--) {\n const type = messages[i].getType();\n if (type === 'ai' || type === 'tool') {\n protectedIndices.add(i);\n if (!inAssistantSequence) {\n inAssistantSequence = true;\n }\n } else {\n if (inAssistantSequence) {\n assistantTurnsFound++;\n inAssistantSequence = false;\n if (assistantTurnsFound >= settings.keepLastAssistants) {\n break;\n }\n }\n // Protect the human message between assistant turns in the protected zone\n if (assistantTurnsFound < settings.keepLastAssistants) {\n protectedIndices.add(i);\n }\n }\n }\n\n // Process each tool message outside the protected zone\n for (let i = 0; i < totalMessages; i++) {\n const message = messages[i];\n if (message.getType() !== 'tool') {\n continue;\n }\n if (protectedIndices.has(i)) {\n continue;\n }\n if (hasImageContent(message)) {\n continue;\n }\n\n const content = message.content;\n if (typeof content !== 'string') {\n continue;\n }\n if (content.length < settings.minPrunableToolChars) {\n continue;\n }\n\n // Compute age ratio: how far back from the end (0 = latest, 1 = oldest)\n const ageRatio = (totalMessages - i) / totalMessages;\n\n if (ageRatio >= settings.hardClearRatio && settings.hardClear.enabled) {\n // Hard-clear: replace with placeholder\n const cloned = new ToolMessage({\n content: settings.hardClear.placeholder,\n tool_call_id: (message as ToolMessage).tool_call_id,\n name: message.name,\n id: message.id,\n additional_kwargs: message.additional_kwargs,\n response_metadata: message.response_metadata,\n });\n messages[i] = cloned;\n indexTokenCountMap[i] = tokenCounter(cloned);\n hardCleared++;\n } else if (ageRatio >= settings.softTrimRatio) {\n // Soft-trim: keep head + tail\n if (content.length > settings.softTrim.maxChars) {\n const cloned = new ToolMessage({\n content: softTrimContent(content, settings.softTrim),\n tool_call_id: (message as ToolMessage).tool_call_id,\n name: message.name,\n id: message.id,\n additional_kwargs: message.additional_kwargs,\n response_metadata: message.response_metadata,\n });\n messages[i] = cloned;\n indexTokenCountMap[i] = tokenCounter(cloned);\n softTrimmed++;\n }\n }\n }\n\n return { softTrimmed, hardCleared };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contextPruning.mjs","sources":["../../../src/messages/contextPruning.ts"],"sourcesContent":["/**\n * Position-based context pruning for tool results.\n *\n * Uses position-based age: the distance of a message\n * from the conversation end as a fraction of total messages.\n *\n * Two degradation levels:\n * - Soft-trim: Keep head + tail of tool result content, drop middle.\n * - Hard-clear: Replace entire content with a placeholder.\n *\n * Messages in the \"protected zone\" (recent assistant turns, system/pre-first-human\n * messages, and messages with image content) are never pruned.\n */\n\nimport { ToolMessage, type BaseMessage } from '@langchain/core/messages';\nimport type { ContextPruningSettings } from './contextPruningSettings';\nimport type { ContextPruningConfig } from '@/types/graph';\nimport type { TokenCounter } from '@/types/run';\nimport { resolveContextPruningSettings } from './contextPruningSettings';\n\n/**\n * Checks if a message contains image content blocks.\n * Messages with images are skipped by position-based content degradation\n * because images cannot be meaningfully soft-trimmed or replaced with placeholders.\n */\nfunction hasImageContent(message: BaseMessage): boolean {\n if (!Array.isArray(message.content)) {\n return false;\n }\n return message.content.some(\n (block) =>\n typeof block === 'object' &&\n 'type' in block &&\n (block.type === 'image_url' || block.type === 'image')\n );\n}\n\n/**\n * Applies head+tail soft-trim to tool result content.\n */\nfunction softTrimContent(\n content: string,\n settings: ContextPruningSettings['softTrim']\n): string {\n const { headChars, tailChars } = settings;\n const indicator = `\\n\\n… [soft-trimmed: ${content.length} chars → ${headChars + tailChars} chars, middle removed] …\\n\\n`;\n return content.slice(0, headChars) + indicator + content.slice(-tailChars);\n}\n\nexport interface ContextPruningResult {\n /** Number of messages that were soft-trimmed. */\n softTrimmed: number;\n /** Number of messages that were hard-cleared. */\n hardCleared: number;\n}\n\n/**\n * Applies position-based context pruning to tool result messages.\n *\n * Modifies messages in-place and updates indexTokenCountMap with recounted\n * token values for modified messages.\n *\n * @param params.messages - The full message array (modified in-place).\n * @param params.indexTokenCountMap - Token count map (updated in-place).\n * @param params.tokenCounter - Function to recount tokens after modification.\n * @param params.config - Partial context pruning config (merged with defaults).\n * @returns Counts of soft-trimmed and hard-cleared messages.\n */\nexport function applyContextPruning(params: {\n messages: BaseMessage[];\n indexTokenCountMap: Record<string, number | undefined>;\n tokenCounter: TokenCounter;\n config?: ContextPruningConfig;\n resolvedSettings?: ContextPruningSettings;\n}): ContextPruningResult {\n const {\n messages,\n indexTokenCountMap,\n tokenCounter,\n config,\n resolvedSettings,\n } = params;\n const settings = resolvedSettings ?? resolveContextPruningSettings(config);\n\n if (!settings.enabled || messages.length === 0) {\n return { softTrimmed: 0, hardCleared: 0 };\n }\n\n const totalMessages = messages.length;\n let softTrimmed = 0;\n let hardCleared = 0;\n\n // Find the protected zone: last N assistant turns from the end.\n // An \"assistant turn\" is a contiguous sequence of AI + Tool messages.\n const protectedIndices = new Set<number>();\n\n // Always protect the system message (index 0 if present)\n if (messages[0]?.getType() === 'system') {\n protectedIndices.add(0);\n }\n\n // Protect messages before the first human message\n for (let i = 0; i < totalMessages; i++) {\n if (messages[i].getType() === 'human') {\n break;\n }\n protectedIndices.add(i);\n }\n\n // Protect the last N assistant turns (walking backwards)\n let assistantTurnsFound = 0;\n let inAssistantSequence = false;\n for (let i = totalMessages - 1; i >= 0; i--) {\n const type = messages[i].getType();\n if (type === 'ai' || type === 'tool') {\n protectedIndices.add(i);\n if (!inAssistantSequence) {\n inAssistantSequence = true;\n }\n } else {\n if (inAssistantSequence) {\n assistantTurnsFound++;\n inAssistantSequence = false;\n if (assistantTurnsFound >= settings.keepLastAssistants) {\n break;\n }\n }\n // Protect the human message between assistant turns in the protected zone\n if (assistantTurnsFound < settings.keepLastAssistants) {\n protectedIndices.add(i);\n }\n }\n }\n\n // Process each tool message outside the protected zone\n for (let i = 0; i < totalMessages; i++) {\n const message = messages[i];\n if (message.getType() !== 'tool') {\n continue;\n }\n if (protectedIndices.has(i)) {\n continue;\n }\n if (hasImageContent(message)) {\n continue;\n }\n\n const content = message.content;\n if (typeof content !== 'string') {\n continue;\n }\n if (content.length < settings.minPrunableToolChars) {\n continue;\n }\n\n // Compute age ratio: how far back from the end (0 = latest, 1 = oldest)\n const ageRatio = (totalMessages - i) / totalMessages;\n\n if (ageRatio >= settings.hardClearRatio && settings.hardClear.enabled) {\n // Hard-clear: replace with placeholder\n const cloned = new ToolMessage({\n content: settings.hardClear.placeholder,\n tool_call_id: (message as ToolMessage).tool_call_id,\n name: message.name,\n id: message.id,\n additional_kwargs: message.additional_kwargs,\n response_metadata: message.response_metadata,\n });\n messages[i] = cloned;\n indexTokenCountMap[i] = tokenCounter(cloned);\n hardCleared++;\n } else if (ageRatio >= settings.softTrimRatio) {\n // Soft-trim: keep head + tail\n if (content.length > settings.softTrim.maxChars) {\n const cloned = new ToolMessage({\n content: softTrimContent(content, settings.softTrim),\n tool_call_id: (message as ToolMessage).tool_call_id,\n name: message.name,\n id: message.id,\n additional_kwargs: message.additional_kwargs,\n response_metadata: message.response_metadata,\n });\n messages[i] = cloned;\n indexTokenCountMap[i] = tokenCounter(cloned);\n softTrimmed++;\n }\n }\n }\n\n return { softTrimmed, hardCleared };\n}\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import { HumanMessage, AIMessage, AIMessageChunk, SystemMessage, ToolMessage } from '@langchain/core/messages';
2
- import { emitAgentLog } from '../utils/events.mjs';
3
- import { ContentTypes, Constants, Providers } from '../common/enum.mjs';
2
+ import { normalizeAnthropicToolCallId } from '../llm/anthropic/utils/message_inputs.mjs';
4
3
  import { toLangChainContent, toLangChainMessageFields } from './langchain.mjs';
4
+ import { ContentTypes, Constants, Providers } from '../common/enum.mjs';
5
+ import { emitAgentLog } from '../utils/events.mjs';
5
6
 
6
7
  /* eslint-disable @typescript-eslint/no-explicit-any */
7
8
  /**
@@ -29,6 +30,19 @@ const formatMediaMessage = ({ message, endpoint, mediaParts, }) => {
29
30
  ];
30
31
  return result;
31
32
  };
33
+ function withMessageRole(message, role) {
34
+ const roleMessage = message;
35
+ if (roleMessage.role === role) {
36
+ return roleMessage;
37
+ }
38
+ Object.defineProperty(roleMessage, 'role', {
39
+ value: role,
40
+ writable: true,
41
+ enumerable: false,
42
+ configurable: true,
43
+ });
44
+ return roleMessage;
45
+ }
32
46
  /**
33
47
  * Formats a message to OpenAI payload format based on the provided options.
34
48
  *
@@ -103,19 +117,19 @@ const formatMessage = ({ message, userName, endpoint, assistantName, langChain =
103
117
  if (!langChain) {
104
118
  return mediaMessage;
105
119
  }
106
- return new HumanMessage(toLangChainMessageFields(mediaMessage));
120
+ return withMessageRole(new HumanMessage(toLangChainMessageFields(mediaMessage)), 'user');
107
121
  }
108
122
  if (!langChain) {
109
123
  return formattedMessage;
110
124
  }
111
125
  if (role === 'user') {
112
- return new HumanMessage(toLangChainMessageFields(formattedMessage));
126
+ return withMessageRole(new HumanMessage(toLangChainMessageFields(formattedMessage)), 'user');
113
127
  }
114
128
  else if (role === 'assistant') {
115
- return new AIMessage(toLangChainMessageFields(formattedMessage));
129
+ return withMessageRole(new AIMessage(toLangChainMessageFields(formattedMessage)), 'assistant');
116
130
  }
117
131
  else {
118
- return new SystemMessage(toLangChainMessageFields(formattedMessage));
132
+ return withMessageRole(new SystemMessage(toLangChainMessageFields(formattedMessage)), 'system');
119
133
  }
120
134
  };
121
135
  /**
@@ -216,6 +230,33 @@ function getToolUseId(part) {
216
230
  }
217
231
  return part.tool_use_id;
218
232
  }
233
+ function isValidServerToolResult(part) {
234
+ const toolUseId = getToolUseId(part);
235
+ if (toolUseId?.startsWith(Constants.ANTHROPIC_SERVER_TOOL_PREFIX) !== true ||
236
+ !('content' in part)) {
237
+ return false;
238
+ }
239
+ const { content } = part;
240
+ return (Array.isArray(content) ||
241
+ (content != null &&
242
+ typeof content === 'object' &&
243
+ 'type' in content &&
244
+ content.type === 'web_search_tool_result_error'));
245
+ }
246
+ function getToolCallId(part) {
247
+ if (part.type !== ContentTypes.TOOL_CALL) {
248
+ return undefined;
249
+ }
250
+ const id = part.tool_call?.id;
251
+ return typeof id === 'string' && id !== '' ? id : undefined;
252
+ }
253
+ function hasToolCallOutput(part) {
254
+ if (part.type !== ContentTypes.TOOL_CALL) {
255
+ return false;
256
+ }
257
+ const output = part.tool_call?.output;
258
+ return output != null && output !== '';
259
+ }
219
260
  /**
220
261
  * Helper function to format an assistant message
221
262
  * @param message The message to format
@@ -231,6 +272,8 @@ function formatAssistantMessage(message, options) {
231
272
  const emittedServerToolUseIds = new Set();
232
273
  const pendingServerToolUses = new Map();
233
274
  const shouldPreserveReasoningContent = options?.preserveReasoningContent === true;
275
+ const serverToolResultIds = new Set();
276
+ const preferredToolCallParts = new Map();
234
277
  const takePendingReasoningContent = () => {
235
278
  if (!shouldPreserveReasoningContent || !pendingReasoningContent) {
236
279
  return undefined;
@@ -241,12 +284,12 @@ function formatAssistantMessage(message, options) {
241
284
  };
242
285
  const createAIMessage = (content) => {
243
286
  const reasoningContent = takePendingReasoningContent();
244
- return new AIMessage({
287
+ return withMessageRole(new AIMessage({
245
288
  content,
246
289
  ...(reasoningContent != null && {
247
290
  additional_kwargs: { reasoning_content: reasoningContent },
248
291
  }),
249
- });
292
+ }), 'assistant');
250
293
  };
251
294
  const attachPendingReasoningContent = (aiMessage) => {
252
295
  const reasoningContent = takePendingReasoningContent();
@@ -270,16 +313,48 @@ function formatAssistantMessage(message, options) {
270
313
  };
271
314
  if (Array.isArray(message.content)) {
272
315
  const contentParts = message.content;
316
+ for (const part of contentParts) {
317
+ if (part == null) {
318
+ continue;
319
+ }
320
+ if (isValidServerToolResult(part)) {
321
+ serverToolResultIds.add(getToolUseId(part) ?? '');
322
+ }
323
+ if (options?.provider === Providers.ANTHROPIC) {
324
+ const toolCallId = getToolCallId(part);
325
+ if (toolCallId == null) {
326
+ continue;
327
+ }
328
+ const preferredPart = preferredToolCallParts.get(toolCallId);
329
+ if (preferredPart == null ||
330
+ (!hasToolCallOutput(preferredPart) && hasToolCallOutput(part))) {
331
+ preferredToolCallParts.set(toolCallId, part);
332
+ }
333
+ }
334
+ }
273
335
  for (const part of contentParts) {
274
336
  if (part == null) {
275
337
  continue;
276
338
  }
277
339
  const toolUseId = getToolUseId(part);
278
340
  if (toolUseId != null) {
341
+ const isServerToolResult = isValidServerToolResult(part);
342
+ if (toolUseId.startsWith(Constants.ANTHROPIC_SERVER_TOOL_PREFIX) &&
343
+ !isServerToolResult) {
344
+ continue;
345
+ }
279
346
  flushPendingServerToolUse(toolUseId);
347
+ if (isServerToolResult) {
348
+ currentContent.push(part);
349
+ continue;
350
+ }
280
351
  }
281
352
  else if (hasMeaningfulAssistantContent(part)) {
282
- pendingServerToolUses.clear();
353
+ for (const id of pendingServerToolUses.keys()) {
354
+ if (!serverToolResultIds.has(id)) {
355
+ pendingServerToolUses.delete(id);
356
+ }
357
+ }
283
358
  }
284
359
  if (part.type === ContentTypes.TEXT && part.tool_call_ids) {
285
360
  /*
@@ -287,6 +362,13 @@ function formatAssistantMessage(message, options) {
287
362
  For Anthropic models, the "tool_calls" field on a message is only respected if content is a string.
288
363
  */
289
364
  if (currentContent.length > 0) {
365
+ if (currentContent.some((content) => content.type !== ContentTypes.TEXT)) {
366
+ currentContent.push(part);
367
+ lastAIMessage = createAIMessage(toLangChainContent(currentContent));
368
+ formattedMessages.push(lastAIMessage);
369
+ currentContent = [];
370
+ continue;
371
+ }
290
372
  let content = currentContent.reduce((acc, curr) => {
291
373
  if (curr.type === ContentTypes.TEXT) {
292
374
  return `${acc}${getTextContent(curr)}\n`;
@@ -308,6 +390,12 @@ function formatAssistantMessage(message, options) {
308
390
  if (part.tool_call == null) {
309
391
  continue;
310
392
  }
393
+ const toolCallId = getToolCallId(part);
394
+ if (options?.provider === Providers.ANTHROPIC &&
395
+ toolCallId != null &&
396
+ preferredToolCallParts.get(toolCallId) !== part) {
397
+ continue;
398
+ }
311
399
  // Note: `tool_calls` list is defined when constructed by `AIMessage` class, and outputs should be excluded from it
312
400
  const { output, args: _args, ..._tool_call } = part.tool_call;
313
401
  // Skip invalid tool calls that have no name AND no output
@@ -318,6 +406,10 @@ function formatAssistantMessage(message, options) {
318
406
  if (options?.provider === Providers.ANTHROPIC &&
319
407
  typeof _tool_call.id === 'string' &&
320
408
  _tool_call.id.startsWith(Constants.ANTHROPIC_SERVER_TOOL_PREFIX)) {
409
+ if (!serverToolResultIds.has(_tool_call.id) &&
410
+ options.preserveUnpairedServerToolUses !== true) {
411
+ continue;
412
+ }
321
413
  if (emittedServerToolUseIds.has(_tool_call.id) ||
322
414
  pendingServerToolUses.has(_tool_call.id)) {
323
415
  continue;
@@ -352,15 +444,28 @@ function formatAssistantMessage(message, options) {
352
444
  }
353
445
  }
354
446
  tool_call.args = args;
355
- if (!lastAIMessage.tool_calls) {
356
- lastAIMessage.tool_calls = [];
447
+ if (options?.provider === Providers.ANTHROPIC &&
448
+ Array.isArray(lastAIMessage.content)) {
449
+ const content = lastAIMessage.content;
450
+ content.push({
451
+ type: 'tool_use',
452
+ id: normalizeAnthropicToolCallId(tool_call.id ?? ''),
453
+ name: tool_call.name,
454
+ input: args,
455
+ });
456
+ lastAIMessage.content = content;
457
+ }
458
+ else {
459
+ if (!lastAIMessage.tool_calls) {
460
+ lastAIMessage.tool_calls = [];
461
+ }
462
+ lastAIMessage.tool_calls.push(tool_call);
357
463
  }
358
- lastAIMessage.tool_calls.push(tool_call);
359
- formattedMessages.push(new ToolMessage({
464
+ formattedMessages.push(withMessageRole(new ToolMessage({
360
465
  tool_call_id: tool_call.id ?? '',
361
466
  name: tool_call.name,
362
467
  content: output != null ? output : '',
363
- }));
468
+ }), 'tool'));
364
469
  }
365
470
  else if (part.type === ContentTypes.THINK ||
366
471
  part.type === ContentTypes.THINKING ||
@@ -905,6 +1010,7 @@ skills, options) => {
905
1010
  }
906
1011
  }
907
1012
  const formattedMessages = formatAssistantMessage(processedMessage, {
1013
+ preserveUnpairedServerToolUses: i === payload.length - 1,
908
1014
  preserveReasoningContent: options?.provider === Providers.DEEPSEEK,
909
1015
  provider: options?.provider,
910
1016
  });
@@ -921,7 +1027,7 @@ skills, options) => {
921
1027
  for (const skillName of pendingSkillNames) {
922
1028
  const body = skills?.get(skillName) ?? '';
923
1029
  if (body) {
924
- messages.push(new HumanMessage({
1030
+ messages.push(withMessageRole(new HumanMessage({
925
1031
  content: body,
926
1032
  additional_kwargs: {
927
1033
  role: 'user',
@@ -929,7 +1035,7 @@ skills, options) => {
929
1035
  source: 'skill',
930
1036
  skillName,
931
1037
  },
932
- }));
1038
+ }), 'user'));
933
1039
  }
934
1040
  }
935
1041
  }
@@ -1285,7 +1391,7 @@ function ensureThinkingBlockInMessages(messages, _provider, config, runStartInde
1285
1391
  flushTextChunks(textChunks, parts);
1286
1392
  emitAgentLog(config, 'warn', 'format', 'ensureThinkingBlockInMessages: injecting [Previous agent context] HumanMessage' +
1287
1393
  ` (${parts.length} msgs at index ${i}, no thinking block in chain)`);
1288
- result.push(new HumanMessage({ content: toLangChainContent(parts) }));
1394
+ result.push(withMessageRole(new HumanMessage({ content: toLangChainContent(parts) }), 'user'));
1289
1395
  i = j;
1290
1396
  }
1291
1397
  else {
@@ -1341,5 +1447,5 @@ function chainHasThinkingBlock(messages, currentIndex) {
1341
1447
  return false;
1342
1448
  }
1343
1449
 
1344
- export { ensureThinkingBlockInMessages, formatAgentMessages, formatFromLangChain, formatLangChainMessages, formatMediaMessage, formatMessage, labelContentByAgent, shiftIndexTokenCountMap };
1450
+ export { ensureThinkingBlockInMessages, formatAgentMessages, formatFromLangChain, formatLangChainMessages, formatMediaMessage, formatMessage, labelContentByAgent, shiftIndexTokenCountMap, withMessageRole };
1345
1451
  //# sourceMappingURL=format.mjs.map