langchain 1.5.4 → 1.5.6

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 (360) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/agents/ReactAgent.cjs +6 -6
  3. package/dist/agents/ReactAgent.cjs.map +1 -1
  4. package/dist/agents/ReactAgent.d.cts +1 -1
  5. package/dist/agents/ReactAgent.d.cts.map +1 -1
  6. package/dist/agents/ReactAgent.d.ts +1 -1
  7. package/dist/agents/ReactAgent.d.ts.map +1 -1
  8. package/dist/agents/ReactAgent.js +6 -5
  9. package/dist/agents/ReactAgent.js.map +1 -1
  10. package/dist/agents/RunnableCallable.cjs +0 -1
  11. package/dist/agents/RunnableCallable.cjs.map +1 -1
  12. package/dist/agents/RunnableCallable.js.map +1 -1
  13. package/dist/agents/annotation.cjs +0 -1
  14. package/dist/agents/annotation.cjs.map +1 -1
  15. package/dist/agents/annotation.js.map +1 -1
  16. package/dist/agents/constants.d.cts +1 -1
  17. package/dist/agents/constants.d.cts.map +1 -1
  18. package/dist/agents/constants.d.ts +1 -1
  19. package/dist/agents/constants.d.ts.map +1 -1
  20. package/dist/agents/errors.cjs +6 -1
  21. package/dist/agents/errors.cjs.map +1 -1
  22. package/dist/agents/errors.d.cts +2 -1
  23. package/dist/agents/errors.d.cts.map +1 -1
  24. package/dist/agents/errors.d.ts +2 -1
  25. package/dist/agents/errors.d.ts.map +1 -1
  26. package/dist/agents/errors.js +6 -0
  27. package/dist/agents/errors.js.map +1 -1
  28. package/dist/agents/index.cjs +21 -7
  29. package/dist/agents/index.cjs.map +1 -1
  30. package/dist/agents/index.d.cts +2 -2
  31. package/dist/agents/index.d.cts.map +1 -1
  32. package/dist/agents/index.d.ts +2 -2
  33. package/dist/agents/index.d.ts.map +1 -1
  34. package/dist/agents/index.js +8 -8
  35. package/dist/agents/index.js.map +1 -1
  36. package/dist/agents/middleware/constants.cjs +3 -1
  37. package/dist/agents/middleware/constants.cjs.map +1 -1
  38. package/dist/agents/middleware/constants.js +3 -1
  39. package/dist/agents/middleware/constants.js.map +1 -1
  40. package/dist/agents/middleware/contextEditing.cjs +0 -1
  41. package/dist/agents/middleware/contextEditing.cjs.map +1 -1
  42. package/dist/agents/middleware/contextEditing.d.cts +1 -3
  43. package/dist/agents/middleware/contextEditing.d.cts.map +1 -1
  44. package/dist/agents/middleware/contextEditing.d.ts +1 -3
  45. package/dist/agents/middleware/contextEditing.d.ts.map +1 -1
  46. package/dist/agents/middleware/contextEditing.js.map +1 -1
  47. package/dist/agents/middleware/dynamicSystemPrompt.cjs +0 -1
  48. package/dist/agents/middleware/dynamicSystemPrompt.cjs.map +1 -1
  49. package/dist/agents/middleware/dynamicSystemPrompt.d.cts +1 -3
  50. package/dist/agents/middleware/dynamicSystemPrompt.d.cts.map +1 -1
  51. package/dist/agents/middleware/dynamicSystemPrompt.d.ts +1 -3
  52. package/dist/agents/middleware/dynamicSystemPrompt.d.ts.map +1 -1
  53. package/dist/agents/middleware/dynamicSystemPrompt.js.map +1 -1
  54. package/dist/agents/middleware/error.cjs +0 -1
  55. package/dist/agents/middleware/error.cjs.map +1 -1
  56. package/dist/agents/middleware/error.js.map +1 -1
  57. package/dist/agents/middleware/hitl.cjs +0 -1
  58. package/dist/agents/middleware/hitl.cjs.map +1 -1
  59. package/dist/agents/middleware/hitl.d.cts +1 -3
  60. package/dist/agents/middleware/hitl.d.cts.map +1 -1
  61. package/dist/agents/middleware/hitl.d.ts +1 -3
  62. package/dist/agents/middleware/hitl.d.ts.map +1 -1
  63. package/dist/agents/middleware/hitl.js.map +1 -1
  64. package/dist/agents/middleware/index.cjs +51 -20
  65. package/dist/agents/middleware/index.d.cts +2 -1
  66. package/dist/agents/middleware/index.d.ts +2 -1
  67. package/dist/agents/middleware/index.js +21 -21
  68. package/dist/agents/middleware/llmToolSelector.cjs +3 -1
  69. package/dist/agents/middleware/llmToolSelector.cjs.map +1 -1
  70. package/dist/agents/middleware/llmToolSelector.d.cts +9 -12
  71. package/dist/agents/middleware/llmToolSelector.d.cts.map +1 -1
  72. package/dist/agents/middleware/llmToolSelector.d.ts +9 -12
  73. package/dist/agents/middleware/llmToolSelector.d.ts.map +1 -1
  74. package/dist/agents/middleware/llmToolSelector.js +3 -1
  75. package/dist/agents/middleware/llmToolSelector.js.map +1 -1
  76. package/dist/agents/middleware/modelCallLimit.cjs +0 -1
  77. package/dist/agents/middleware/modelCallLimit.cjs.map +1 -1
  78. package/dist/agents/middleware/modelCallLimit.d.cts +1 -3
  79. package/dist/agents/middleware/modelCallLimit.d.cts.map +1 -1
  80. package/dist/agents/middleware/modelCallLimit.d.ts +1 -3
  81. package/dist/agents/middleware/modelCallLimit.d.ts.map +1 -1
  82. package/dist/agents/middleware/modelCallLimit.js.map +1 -1
  83. package/dist/agents/middleware/modelFallback.cjs.map +1 -1
  84. package/dist/agents/middleware/modelFallback.d.cts +1 -3
  85. package/dist/agents/middleware/modelFallback.d.cts.map +1 -1
  86. package/dist/agents/middleware/modelFallback.d.ts +1 -3
  87. package/dist/agents/middleware/modelFallback.d.ts.map +1 -1
  88. package/dist/agents/middleware/modelFallback.js.map +1 -1
  89. package/dist/agents/middleware/modelRetry.cjs +1 -1
  90. package/dist/agents/middleware/modelRetry.cjs.map +1 -1
  91. package/dist/agents/middleware/modelRetry.d.cts +2 -4
  92. package/dist/agents/middleware/modelRetry.d.cts.map +1 -1
  93. package/dist/agents/middleware/modelRetry.d.ts +2 -4
  94. package/dist/agents/middleware/modelRetry.d.ts.map +1 -1
  95. package/dist/agents/middleware/modelRetry.js +1 -1
  96. package/dist/agents/middleware/modelRetry.js.map +1 -1
  97. package/dist/agents/middleware/pii.cjs +2 -1
  98. package/dist/agents/middleware/pii.cjs.map +1 -1
  99. package/dist/agents/middleware/pii.d.cts +2 -4
  100. package/dist/agents/middleware/pii.d.cts.map +1 -1
  101. package/dist/agents/middleware/pii.d.ts +2 -4
  102. package/dist/agents/middleware/pii.d.ts.map +1 -1
  103. package/dist/agents/middleware/pii.js +2 -0
  104. package/dist/agents/middleware/pii.js.map +1 -1
  105. package/dist/agents/middleware/piiRedaction.cjs +0 -1
  106. package/dist/agents/middleware/piiRedaction.cjs.map +1 -1
  107. package/dist/agents/middleware/piiRedaction.d.cts +1 -3
  108. package/dist/agents/middleware/piiRedaction.d.cts.map +1 -1
  109. package/dist/agents/middleware/piiRedaction.d.ts +1 -3
  110. package/dist/agents/middleware/piiRedaction.d.ts.map +1 -1
  111. package/dist/agents/middleware/piiRedaction.js.map +1 -1
  112. package/dist/agents/middleware/provider/anthropic/promptCaching.cjs +0 -1
  113. package/dist/agents/middleware/provider/anthropic/promptCaching.cjs.map +1 -1
  114. package/dist/agents/middleware/provider/anthropic/promptCaching.d.cts +1 -3
  115. package/dist/agents/middleware/provider/anthropic/promptCaching.d.cts.map +1 -1
  116. package/dist/agents/middleware/provider/anthropic/promptCaching.d.ts +1 -3
  117. package/dist/agents/middleware/provider/anthropic/promptCaching.d.ts.map +1 -1
  118. package/dist/agents/middleware/provider/anthropic/promptCaching.js.map +1 -1
  119. package/dist/agents/middleware/provider/aws/promptCaching.cjs +0 -1
  120. package/dist/agents/middleware/provider/aws/promptCaching.cjs.map +1 -1
  121. package/dist/agents/middleware/provider/aws/promptCaching.d.cts +1 -3
  122. package/dist/agents/middleware/provider/aws/promptCaching.d.cts.map +1 -1
  123. package/dist/agents/middleware/provider/aws/promptCaching.d.ts +1 -3
  124. package/dist/agents/middleware/provider/aws/promptCaching.d.ts.map +1 -1
  125. package/dist/agents/middleware/provider/aws/promptCaching.js.map +1 -1
  126. package/dist/agents/middleware/provider/openai/moderation.cjs +1 -1
  127. package/dist/agents/middleware/provider/openai/moderation.cjs.map +1 -1
  128. package/dist/agents/middleware/provider/openai/moderation.d.cts +0 -4
  129. package/dist/agents/middleware/provider/openai/moderation.d.cts.map +1 -1
  130. package/dist/agents/middleware/provider/openai/moderation.d.ts +0 -4
  131. package/dist/agents/middleware/provider/openai/moderation.d.ts.map +1 -1
  132. package/dist/agents/middleware/provider/openai/moderation.js +1 -1
  133. package/dist/agents/middleware/provider/openai/moderation.js.map +1 -1
  134. package/dist/agents/middleware/providerToolSearch.cjs +0 -1
  135. package/dist/agents/middleware/providerToolSearch.cjs.map +1 -1
  136. package/dist/agents/middleware/providerToolSearch.d.cts +1 -2
  137. package/dist/agents/middleware/providerToolSearch.d.cts.map +1 -1
  138. package/dist/agents/middleware/providerToolSearch.d.ts +1 -2
  139. package/dist/agents/middleware/providerToolSearch.d.ts.map +1 -1
  140. package/dist/agents/middleware/providerToolSearch.js.map +1 -1
  141. package/dist/agents/middleware/summarization.cjs +8 -5
  142. package/dist/agents/middleware/summarization.cjs.map +1 -1
  143. package/dist/agents/middleware/summarization.d.cts +16 -20
  144. package/dist/agents/middleware/summarization.d.cts.map +1 -1
  145. package/dist/agents/middleware/summarization.d.ts +16 -20
  146. package/dist/agents/middleware/summarization.d.ts.map +1 -1
  147. package/dist/agents/middleware/summarization.js +8 -5
  148. package/dist/agents/middleware/summarization.js.map +1 -1
  149. package/dist/agents/middleware/todoListMiddleware.cjs +0 -1
  150. package/dist/agents/middleware/todoListMiddleware.cjs.map +1 -1
  151. package/dist/agents/middleware/todoListMiddleware.d.cts +2 -5
  152. package/dist/agents/middleware/todoListMiddleware.d.cts.map +1 -1
  153. package/dist/agents/middleware/todoListMiddleware.d.ts +2 -5
  154. package/dist/agents/middleware/todoListMiddleware.d.ts.map +1 -1
  155. package/dist/agents/middleware/todoListMiddleware.js.map +1 -1
  156. package/dist/agents/middleware/toolCallLimit.cjs +0 -1
  157. package/dist/agents/middleware/toolCallLimit.cjs.map +1 -1
  158. package/dist/agents/middleware/toolCallLimit.d.cts +2 -4
  159. package/dist/agents/middleware/toolCallLimit.d.cts.map +1 -1
  160. package/dist/agents/middleware/toolCallLimit.d.ts +2 -4
  161. package/dist/agents/middleware/toolCallLimit.d.ts.map +1 -1
  162. package/dist/agents/middleware/toolCallLimit.js.map +1 -1
  163. package/dist/agents/middleware/toolEmulator.cjs +8 -2
  164. package/dist/agents/middleware/toolEmulator.cjs.map +1 -1
  165. package/dist/agents/middleware/toolEmulator.d.cts +0 -1
  166. package/dist/agents/middleware/toolEmulator.d.cts.map +1 -1
  167. package/dist/agents/middleware/toolEmulator.d.ts +0 -1
  168. package/dist/agents/middleware/toolEmulator.d.ts.map +1 -1
  169. package/dist/agents/middleware/toolEmulator.js +8 -1
  170. package/dist/agents/middleware/toolEmulator.js.map +1 -1
  171. package/dist/agents/middleware/toolError.cjs +0 -1
  172. package/dist/agents/middleware/toolError.cjs.map +1 -1
  173. package/dist/agents/middleware/toolError.d.cts +0 -1
  174. package/dist/agents/middleware/toolError.d.cts.map +1 -1
  175. package/dist/agents/middleware/toolError.d.ts +0 -1
  176. package/dist/agents/middleware/toolError.d.ts.map +1 -1
  177. package/dist/agents/middleware/toolError.js.map +1 -1
  178. package/dist/agents/middleware/toolRetry.cjs +1 -1
  179. package/dist/agents/middleware/toolRetry.cjs.map +1 -1
  180. package/dist/agents/middleware/toolRetry.d.cts +1 -2
  181. package/dist/agents/middleware/toolRetry.d.cts.map +1 -1
  182. package/dist/agents/middleware/toolRetry.d.ts +1 -2
  183. package/dist/agents/middleware/toolRetry.d.ts.map +1 -1
  184. package/dist/agents/middleware/toolRetry.js +1 -1
  185. package/dist/agents/middleware/toolRetry.js.map +1 -1
  186. package/dist/agents/middleware/types.cjs.map +1 -1
  187. package/dist/agents/middleware/types.d.cts +1 -2
  188. package/dist/agents/middleware/types.d.cts.map +1 -1
  189. package/dist/agents/middleware/types.d.ts +1 -2
  190. package/dist/agents/middleware/types.d.ts.map +1 -1
  191. package/dist/agents/middleware/types.js.map +1 -1
  192. package/dist/agents/middleware/utils.cjs +0 -1
  193. package/dist/agents/middleware/utils.cjs.map +1 -1
  194. package/dist/agents/middleware/utils.d.cts +2 -1
  195. package/dist/agents/middleware/utils.d.cts.map +1 -1
  196. package/dist/agents/middleware/utils.d.ts +2 -1
  197. package/dist/agents/middleware/utils.d.ts.map +1 -1
  198. package/dist/agents/middleware/utils.js.map +1 -1
  199. package/dist/agents/middleware.cjs.map +1 -1
  200. package/dist/agents/middleware.d.cts +0 -1
  201. package/dist/agents/middleware.d.cts.map +1 -1
  202. package/dist/agents/middleware.d.ts +0 -1
  203. package/dist/agents/middleware.d.ts.map +1 -1
  204. package/dist/agents/middleware.js.map +1 -1
  205. package/dist/agents/model.cjs.map +1 -1
  206. package/dist/agents/model.d.cts +0 -1
  207. package/dist/agents/model.d.cts.map +1 -1
  208. package/dist/agents/model.d.ts +0 -1
  209. package/dist/agents/model.d.ts.map +1 -1
  210. package/dist/agents/model.js.map +1 -1
  211. package/dist/agents/nodes/AfterAgentNode.cjs +1 -0
  212. package/dist/agents/nodes/AfterAgentNode.cjs.map +1 -1
  213. package/dist/agents/nodes/AfterAgentNode.js +1 -0
  214. package/dist/agents/nodes/AfterAgentNode.js.map +1 -1
  215. package/dist/agents/nodes/AfterModelNode.cjs +1 -0
  216. package/dist/agents/nodes/AfterModelNode.cjs.map +1 -1
  217. package/dist/agents/nodes/AfterModelNode.js +1 -0
  218. package/dist/agents/nodes/AfterModelNode.js.map +1 -1
  219. package/dist/agents/nodes/AgentNode.cjs +0 -1
  220. package/dist/agents/nodes/AgentNode.cjs.map +1 -1
  221. package/dist/agents/nodes/AgentNode.js.map +1 -1
  222. package/dist/agents/nodes/BeforeAgentNode.cjs +1 -0
  223. package/dist/agents/nodes/BeforeAgentNode.cjs.map +1 -1
  224. package/dist/agents/nodes/BeforeAgentNode.js +1 -0
  225. package/dist/agents/nodes/BeforeAgentNode.js.map +1 -1
  226. package/dist/agents/nodes/BeforeModelNode.cjs +1 -0
  227. package/dist/agents/nodes/BeforeModelNode.cjs.map +1 -1
  228. package/dist/agents/nodes/BeforeModelNode.js +1 -0
  229. package/dist/agents/nodes/BeforeModelNode.js.map +1 -1
  230. package/dist/agents/nodes/ToolNode.cjs +2 -1
  231. package/dist/agents/nodes/ToolNode.cjs.map +1 -1
  232. package/dist/agents/nodes/ToolNode.js +2 -1
  233. package/dist/agents/nodes/ToolNode.js.map +1 -1
  234. package/dist/agents/nodes/middleware.cjs +0 -1
  235. package/dist/agents/nodes/middleware.cjs.map +1 -1
  236. package/dist/agents/nodes/middleware.js.map +1 -1
  237. package/dist/agents/nodes/types.d.cts +0 -1
  238. package/dist/agents/nodes/types.d.cts.map +1 -1
  239. package/dist/agents/nodes/types.d.ts +0 -1
  240. package/dist/agents/nodes/types.d.ts.map +1 -1
  241. package/dist/agents/nodes/utils.cjs +0 -1
  242. package/dist/agents/nodes/utils.cjs.map +1 -1
  243. package/dist/agents/nodes/utils.js.map +1 -1
  244. package/dist/agents/responses.cjs +11 -5
  245. package/dist/agents/responses.cjs.map +1 -1
  246. package/dist/agents/responses.d.cts +3 -3
  247. package/dist/agents/responses.d.cts.map +1 -1
  248. package/dist/agents/responses.d.ts +3 -3
  249. package/dist/agents/responses.d.ts.map +1 -1
  250. package/dist/agents/responses.js +11 -5
  251. package/dist/agents/responses.js.map +1 -1
  252. package/dist/agents/runtime.d.cts +2 -2
  253. package/dist/agents/runtime.d.cts.map +1 -1
  254. package/dist/agents/runtime.d.ts +2 -2
  255. package/dist/agents/runtime.d.ts.map +1 -1
  256. package/dist/agents/tests/utils.cjs +0 -1
  257. package/dist/agents/tests/utils.cjs.map +1 -1
  258. package/dist/agents/tests/utils.d.cts +2 -9
  259. package/dist/agents/tests/utils.d.cts.map +1 -1
  260. package/dist/agents/tests/utils.d.ts +2 -9
  261. package/dist/agents/tests/utils.d.ts.map +1 -1
  262. package/dist/agents/tests/utils.js.map +1 -1
  263. package/dist/agents/transformers/index.cjs +4 -2
  264. package/dist/agents/transformers/index.d.cts +2 -1
  265. package/dist/agents/transformers/index.d.ts +2 -1
  266. package/dist/agents/transformers/index.js +3 -3
  267. package/dist/agents/transformers/subagent.cjs +0 -1
  268. package/dist/agents/transformers/subagent.cjs.map +1 -1
  269. package/dist/agents/transformers/subagent.d.cts +0 -1
  270. package/dist/agents/transformers/subagent.d.cts.map +1 -1
  271. package/dist/agents/transformers/subagent.d.ts +0 -1
  272. package/dist/agents/transformers/subagent.d.ts.map +1 -1
  273. package/dist/agents/transformers/subagent.js.map +1 -1
  274. package/dist/agents/transformers/tool-call.cjs +0 -1
  275. package/dist/agents/transformers/tool-call.cjs.map +1 -1
  276. package/dist/agents/transformers/tool-call.d.cts +0 -1
  277. package/dist/agents/transformers/tool-call.d.cts.map +1 -1
  278. package/dist/agents/transformers/tool-call.d.ts +0 -1
  279. package/dist/agents/transformers/tool-call.d.ts.map +1 -1
  280. package/dist/agents/transformers/tool-call.js.map +1 -1
  281. package/dist/agents/transformers/types.d.cts +3 -3
  282. package/dist/agents/transformers/types.d.cts.map +1 -1
  283. package/dist/agents/transformers/types.d.ts +3 -3
  284. package/dist/agents/transformers/types.d.ts.map +1 -1
  285. package/dist/agents/types.d.cts +1 -2
  286. package/dist/agents/types.d.cts.map +1 -1
  287. package/dist/agents/types.d.ts +1 -2
  288. package/dist/agents/types.d.ts.map +1 -1
  289. package/dist/agents/utils.cjs +0 -1
  290. package/dist/agents/utils.cjs.map +1 -1
  291. package/dist/agents/utils.js.map +1 -1
  292. package/dist/agents/withAgentName.cjs +0 -1
  293. package/dist/agents/withAgentName.cjs.map +1 -1
  294. package/dist/agents/withAgentName.js.map +1 -1
  295. package/dist/browser.d.cts +2 -1
  296. package/dist/browser.d.ts +2 -1
  297. package/dist/chat_models/universal.cjs.map +1 -1
  298. package/dist/chat_models/universal.d.cts +0 -1
  299. package/dist/chat_models/universal.d.cts.map +1 -1
  300. package/dist/chat_models/universal.d.ts +0 -1
  301. package/dist/chat_models/universal.d.ts.map +1 -1
  302. package/dist/chat_models/universal.js.map +1 -1
  303. package/dist/hub/base.cjs +0 -1
  304. package/dist/hub/base.cjs.map +1 -1
  305. package/dist/hub/base.d.cts +1 -0
  306. package/dist/hub/base.d.cts.map +1 -1
  307. package/dist/hub/base.d.ts +1 -0
  308. package/dist/hub/base.d.ts.map +1 -1
  309. package/dist/hub/base.js.map +1 -1
  310. package/dist/hub/index.cjs.map +1 -1
  311. package/dist/hub/index.d.cts +0 -1
  312. package/dist/hub/index.d.cts.map +1 -1
  313. package/dist/hub/index.d.ts +0 -1
  314. package/dist/hub/index.d.ts.map +1 -1
  315. package/dist/hub/index.js.map +1 -1
  316. package/dist/hub/node.cjs.map +1 -1
  317. package/dist/hub/node.d.cts +0 -1
  318. package/dist/hub/node.d.cts.map +1 -1
  319. package/dist/hub/node.d.ts +0 -1
  320. package/dist/hub/node.d.ts.map +1 -1
  321. package/dist/hub/node.js.map +1 -1
  322. package/dist/index.d.cts +2 -1
  323. package/dist/index.d.ts +2 -1
  324. package/dist/load/import_constants.cjs.map +1 -1
  325. package/dist/load/import_constants.js.map +1 -1
  326. package/dist/load/import_map.cjs +56 -0
  327. package/dist/load/import_map.cjs.map +1 -1
  328. package/dist/load/import_map.js +1 -1
  329. package/dist/load/import_map.js.map +1 -1
  330. package/dist/load/import_type.d.cts.map +1 -1
  331. package/dist/load/import_type.d.ts.map +1 -1
  332. package/dist/load/index.cjs +0 -1
  333. package/dist/load/index.cjs.map +1 -1
  334. package/dist/load/index.d.cts +0 -1
  335. package/dist/load/index.d.cts.map +1 -1
  336. package/dist/load/index.d.ts +0 -1
  337. package/dist/load/index.d.ts.map +1 -1
  338. package/dist/load/index.js.map +1 -1
  339. package/dist/storage/encoder_backed.cjs.map +1 -1
  340. package/dist/storage/encoder_backed.d.cts +0 -1
  341. package/dist/storage/encoder_backed.d.cts.map +1 -1
  342. package/dist/storage/encoder_backed.d.ts +0 -1
  343. package/dist/storage/encoder_backed.d.ts.map +1 -1
  344. package/dist/storage/encoder_backed.js.map +1 -1
  345. package/dist/storage/file_system.cjs +4 -3
  346. package/dist/storage/file_system.cjs.map +1 -1
  347. package/dist/storage/file_system.d.cts +20 -1
  348. package/dist/storage/file_system.d.cts.map +1 -1
  349. package/dist/storage/file_system.d.ts +20 -1
  350. package/dist/storage/file_system.d.ts.map +1 -1
  351. package/dist/storage/file_system.js +4 -3
  352. package/dist/storage/file_system.js.map +1 -1
  353. package/dist/tools/headless.cjs +0 -1
  354. package/dist/tools/headless.cjs.map +1 -1
  355. package/dist/tools/headless.d.cts +5 -3
  356. package/dist/tools/headless.d.cts.map +1 -1
  357. package/dist/tools/headless.d.ts +5 -3
  358. package/dist/tools/headless.d.ts.map +1 -1
  359. package/dist/tools/headless.js.map +1 -1
  360. package/package.json +14 -14
@@ -1 +1 @@
1
- {"version":3,"file":"llmToolSelector.cjs","names":["z","BaseLanguageModel","createMiddleware","HumanMessage","initChatModel"],"sources":["../../../src/agents/middleware/llmToolSelector.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { BaseLanguageModel } from \"@langchain/core/language_models/base\";\nimport type { InferInteropZodInput } from \"@langchain/core/utils/types\";\nimport { HumanMessage } from \"@langchain/core/messages\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\n\nimport { createMiddleware } from \"../middleware.js\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport type { Runtime } from \"../runtime.js\";\nimport type { ModelRequest } from \"../nodes/types.js\";\nimport {\n mergeConfigs,\n pickRunnableConfigKeys,\n type RunnableConfig,\n} from \"@langchain/core/runnables\";\n\nconst DEFAULT_SYSTEM_PROMPT =\n \"Your goal is to select the most relevant tools for answering the user's query.\";\n\n/**\n * Prepared inputs for tool selection.\n */\ninterface SelectionRequest {\n availableTools: StructuredToolInterface[];\n systemMessage: string;\n lastUserMessage: HumanMessage;\n model: BaseLanguageModel;\n validToolNames: string[];\n}\n\n/**\n * Create a structured output schema for tool selection.\n *\n * @param tools - Available tools to include in the schema.\n * @returns Zod schema where each tool name is a literal with its description.\n */\nfunction createToolSelectionResponse(tools: StructuredToolInterface[]) {\n if (!tools || tools.length === 0) {\n throw new Error(\"Invalid usage: tools must be non-empty\");\n }\n\n // Create a union of literals for each tool name\n const toolLiterals = tools.map((tool) => z.literal(tool.name));\n const toolEnum = z.union(\n toolLiterals as [\n z.ZodLiteral<string>,\n z.ZodLiteral<string>,\n ...z.ZodLiteral<string>[],\n ]\n );\n\n return z.object({\n tools: z\n .array(toolEnum)\n .describe(\"Tools to use. Place the most relevant tools first.\"),\n });\n}\n\n/**\n * Options for configuring the LLM Tool Selector middleware.\n */\nexport const LLMToolSelectorOptionsSchema = z.object({\n /**\n * The language model to use for tool selection (default: the provided model from the agent options).\n */\n model: z.string().or(z.instanceof(BaseLanguageModel)).optional(),\n /**\n * System prompt for the tool selection model.\n */\n systemPrompt: z.string().optional(),\n /**\n * Maximum number of tools to select. If the model selects more,\n * only the first maxTools will be used. No limit if not specified.\n */\n maxTools: z.number().optional(),\n /**\n * Tool names to always include regardless of selection.\n * These do not count against the maxTools limit.\n */\n alwaysInclude: z.array(z.string()).optional(),\n});\nexport type LLMToolSelectorConfig = InferInteropZodInput<\n typeof LLMToolSelectorOptionsSchema\n>;\n\n/**\n * Middleware for selecting tools using an LLM-based strategy.\n *\n * When an agent has many tools available, this middleware filters them down\n * to only the most relevant ones for the user's query. This reduces token usage\n * and helps the main model focus on the right tools.\n *\n * @param options - Configuration options for the middleware\n * @param options.model - The language model to use for tool selection (default: the provided model from the agent options).\n * @param options.systemPrompt - Instructions for the selection model.\n * @param options.maxTools - Maximum number of tools to select. If the model selects more,\n * only the first maxTools will be used. No limit if not specified.\n * @param options.alwaysInclude - Tool names to always include regardless of selection.\n * These do not count against the maxTools limit.\n *\n * @example\n * Limit to 3 tools:\n * ```ts\n * import { llmToolSelectorMiddleware } from \"langchain/agents/middleware\";\n *\n * const middleware = llmToolSelectorMiddleware({ maxTools: 3 });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [tool1, tool2, tool3, tool4, tool5],\n * middleware: [middleware],\n * });\n * ```\n *\n * @example\n * Use a smaller model for selection:\n * ```ts\n * const middleware = llmToolSelectorMiddleware({\n * model: \"openai:gpt-4o-mini\",\n * maxTools: 2\n * });\n * ```\n */\nexport function llmToolSelectorMiddleware(options: LLMToolSelectorConfig) {\n return createMiddleware({\n name: \"LLMToolSelector\",\n contextSchema: LLMToolSelectorOptionsSchema,\n async wrapModelCall(request, handler) {\n const selectionRequest = await prepareSelectionRequest(\n request,\n options,\n request.runtime\n );\n if (!selectionRequest) {\n return handler(request);\n }\n\n // Create dynamic response model with union of literal tool names\n const toolSelectionSchema = createToolSelectionResponse(\n selectionRequest.availableTools\n );\n const structuredModel =\n await selectionRequest.model.withStructuredOutput?.(\n toolSelectionSchema\n );\n\n const baseConfig: RunnableConfig =\n pickRunnableConfigKeys(request.runtime) ?? {};\n const config = mergeConfigs(baseConfig, {\n metadata: { lc_source: \"llmToolSelector\" },\n callbacks: [],\n });\n\n const response = await structuredModel?.invoke(\n [\n { role: \"system\", content: selectionRequest.systemMessage },\n selectionRequest.lastUserMessage,\n ],\n config\n );\n\n // Response should be an object with a tools array\n if (!response || typeof response !== \"object\" || !(\"tools\" in response)) {\n throw new Error(\n `Expected object response with tools array, got ${typeof response}`\n );\n }\n\n return handler(\n processSelectionResponse(\n response as { tools: string[] },\n selectionRequest.availableTools,\n selectionRequest.validToolNames,\n request,\n options\n )\n );\n },\n });\n}\n\n/**\n * Prepare inputs for tool selection.\n *\n * @param request - The model request to process.\n * @param options - Configuration options.\n * @param runtime - Runtime context.\n * @returns SelectionRequest with prepared inputs, or null if no selection is needed.\n */\nasync function prepareSelectionRequest<\n TState extends Record<string, unknown> = Record<string, unknown>,\n TContext = unknown,\n>(\n request: ModelRequest<TState, TContext>,\n options: LLMToolSelectorConfig,\n runtime: Runtime<LLMToolSelectorConfig>\n): Promise<SelectionRequest | undefined> {\n const model = runtime.context.model ?? options.model;\n const maxTools = runtime.context.maxTools ?? options.maxTools;\n const alwaysInclude =\n runtime.context.alwaysInclude ?? options.alwaysInclude ?? [];\n const systemPrompt =\n runtime.context.systemPrompt ??\n options.systemPrompt ??\n DEFAULT_SYSTEM_PROMPT;\n\n /**\n * If no tools available, return null\n */\n if (!request.tools || request.tools.length === 0) {\n return undefined;\n }\n\n /**\n * Filter to only StructuredToolInterface instances (exclude provider-specific tool dicts)\n */\n const baseTools = request.tools.filter(\n (tool): tool is StructuredToolInterface =>\n typeof tool === \"object\" &&\n \"name\" in tool &&\n \"description\" in tool &&\n typeof tool.name === \"string\"\n );\n\n /**\n * Validate that alwaysInclude tools exist\n */\n if (alwaysInclude.length > 0) {\n const availableToolNames = new Set(baseTools.map((tool) => tool.name));\n const missingTools = alwaysInclude.filter(\n (name) => !availableToolNames.has(name)\n );\n if (missingTools.length > 0) {\n throw new Error(\n `Tools in alwaysInclude not found in request: ${missingTools.join(\n \", \"\n )}. ` +\n `Available tools: ${Array.from(availableToolNames).sort().join(\", \")}`\n );\n }\n }\n\n /**\n * Separate tools that are always included from those available for selection\n */\n const availableTools = baseTools.filter(\n (tool) => !alwaysInclude.includes(tool.name)\n );\n\n /**\n * If no tools available for selection, return null\n */\n if (availableTools.length === 0) {\n return undefined;\n }\n\n let systemMessage = systemPrompt;\n /**\n * If there's a maxTools limit, append instructions to the system prompt\n */\n if (maxTools !== undefined) {\n systemMessage +=\n `\\nIMPORTANT: List the tool names in order of relevance, ` +\n `with the most relevant first. ` +\n `If you exceed the maximum number of tools, ` +\n `only the first ${maxTools} will be used.`;\n }\n\n /**\n * Get the last user message from the conversation history\n */\n let lastUserMessage: HumanMessage | undefined;\n for (const message of request.messages) {\n if (HumanMessage.isInstance(message)) {\n lastUserMessage = message;\n }\n }\n\n if (!lastUserMessage) {\n throw new Error(\"No user message found in request messages\");\n }\n\n const modelInstance = !model\n ? (request.model as BaseLanguageModel)\n : typeof model === \"string\"\n ? await initChatModel(model)\n : model;\n\n const validToolNames = availableTools.map((tool) => tool.name);\n\n return {\n availableTools,\n systemMessage,\n lastUserMessage,\n model: modelInstance,\n validToolNames,\n };\n}\n\n/**\n * Process the selection response and return filtered ModelRequest.\n *\n * @param response - The structured output response from the model.\n * @param availableTools - Tools available for selection.\n * @param validToolNames - Valid tool names that can be selected.\n * @param request - Original model request.\n * @param options - Configuration options.\n * @returns Modified ModelRequest with filtered tools.\n */\nfunction processSelectionResponse<\n TState extends Record<string, unknown> = Record<string, unknown>,\n TContext = unknown,\n>(\n response: { tools: string[] },\n availableTools: StructuredToolInterface[],\n validToolNames: string[],\n request: ModelRequest<TState, TContext>,\n options: LLMToolSelectorConfig\n): ModelRequest<TState, TContext> {\n const maxTools = options.maxTools;\n const alwaysInclude = options.alwaysInclude ?? [];\n\n const selectedToolNames: string[] = [];\n const invalidToolSelections: string[] = [];\n\n for (const toolName of response.tools) {\n if (!validToolNames.includes(toolName)) {\n invalidToolSelections.push(toolName);\n continue;\n }\n\n /**\n * Only add if not already selected and within maxTools limit\n */\n if (\n !selectedToolNames.includes(toolName) &&\n (maxTools === undefined || selectedToolNames.length < maxTools)\n ) {\n selectedToolNames.push(toolName);\n }\n }\n\n if (invalidToolSelections.length > 0) {\n throw new Error(\n `Model selected invalid tools: ${invalidToolSelections.join(\", \")}`\n );\n }\n\n /**\n * Filter tools based on selection\n */\n const selectedTools = availableTools.filter((tool) =>\n selectedToolNames.includes(tool.name)\n );\n\n /**\n * Append always-included tools\n */\n const alwaysIncludedTools = (request.tools ?? []).filter(\n (tool): tool is StructuredToolInterface =>\n typeof tool === \"object\" &&\n \"name\" in tool &&\n typeof tool.name === \"string\" &&\n alwaysInclude.includes(tool.name)\n );\n selectedTools.push(...alwaysIncludedTools);\n\n /**\n * Also preserve any provider-specific tool dicts from the original request\n */\n const providerTools = (request.tools ?? []).filter(\n (tool) =>\n !(\n typeof tool === \"object\" &&\n \"name\" in tool &&\n \"description\" in tool &&\n typeof tool.name === \"string\"\n )\n );\n\n return {\n ...request,\n tools: [...selectedTools, ...providerTools],\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"llmToolSelector.cjs","names":["z","BaseLanguageModel","createMiddleware","INTERNAL_CALL_TAG","HumanMessage","initChatModel"],"sources":["../../../src/agents/middleware/llmToolSelector.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { BaseLanguageModel } from \"@langchain/core/language_models/base\";\nimport type { InferInteropZodInput } from \"@langchain/core/utils/types\";\nimport { HumanMessage } from \"@langchain/core/messages\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\n\nimport { createMiddleware } from \"../middleware.js\";\nimport { INTERNAL_CALL_TAG } from \"./constants.js\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport type { Runtime } from \"../runtime.js\";\nimport type { ModelRequest } from \"../nodes/types.js\";\nimport {\n mergeConfigs,\n pickRunnableConfigKeys,\n type RunnableConfig,\n} from \"@langchain/core/runnables\";\n\nconst DEFAULT_SYSTEM_PROMPT =\n \"Your goal is to select the most relevant tools for answering the user's query.\";\n\n/**\n * Prepared inputs for tool selection.\n */\ninterface SelectionRequest {\n availableTools: StructuredToolInterface[];\n systemMessage: string;\n lastUserMessage: HumanMessage;\n model: BaseLanguageModel;\n validToolNames: string[];\n}\n\n/**\n * Create a structured output schema for tool selection.\n *\n * @param tools - Available tools to include in the schema.\n * @returns Zod schema where each tool name is a literal with its description.\n */\nfunction createToolSelectionResponse(tools: StructuredToolInterface[]) {\n if (!tools || tools.length === 0) {\n throw new Error(\"Invalid usage: tools must be non-empty\");\n }\n\n // Create a union of literals for each tool name\n const toolLiterals = tools.map((tool) => z.literal(tool.name));\n const toolEnum = z.union(\n toolLiterals as [\n z.ZodLiteral<string>,\n z.ZodLiteral<string>,\n ...z.ZodLiteral<string>[],\n ]\n );\n\n return z.object({\n tools: z\n .array(toolEnum)\n .describe(\"Tools to use. Place the most relevant tools first.\"),\n });\n}\n\n/**\n * Options for configuring the LLM Tool Selector middleware.\n */\nexport const LLMToolSelectorOptionsSchema = z.object({\n /**\n * The language model to use for tool selection (default: the provided model from the agent options).\n */\n model: z.string().or(z.instanceof(BaseLanguageModel)).optional(),\n /**\n * System prompt for the tool selection model.\n */\n systemPrompt: z.string().optional(),\n /**\n * Maximum number of tools to select. If the model selects more,\n * only the first maxTools will be used. No limit if not specified.\n */\n maxTools: z.number().optional(),\n /**\n * Tool names to always include regardless of selection.\n * These do not count against the maxTools limit.\n */\n alwaysInclude: z.array(z.string()).optional(),\n});\nexport type LLMToolSelectorConfig = InferInteropZodInput<\n typeof LLMToolSelectorOptionsSchema\n>;\n\n/**\n * Middleware for selecting tools using an LLM-based strategy.\n *\n * When an agent has many tools available, this middleware filters them down\n * to only the most relevant ones for the user's query. This reduces token usage\n * and helps the main model focus on the right tools.\n *\n * @param options - Configuration options for the middleware\n * @param options.model - The language model to use for tool selection (default: the provided model from the agent options).\n * @param options.systemPrompt - Instructions for the selection model.\n * @param options.maxTools - Maximum number of tools to select. If the model selects more,\n * only the first maxTools will be used. No limit if not specified.\n * @param options.alwaysInclude - Tool names to always include regardless of selection.\n * These do not count against the maxTools limit.\n *\n * @example\n * Limit to 3 tools:\n * ```ts\n * import { llmToolSelectorMiddleware } from \"langchain/agents/middleware\";\n *\n * const middleware = llmToolSelectorMiddleware({ maxTools: 3 });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [tool1, tool2, tool3, tool4, tool5],\n * middleware: [middleware],\n * });\n * ```\n *\n * @example\n * Use a smaller model for selection:\n * ```ts\n * const middleware = llmToolSelectorMiddleware({\n * model: \"openai:gpt-4o-mini\",\n * maxTools: 2\n * });\n * ```\n */\nexport function llmToolSelectorMiddleware(options: LLMToolSelectorConfig) {\n return createMiddleware({\n name: \"LLMToolSelector\",\n contextSchema: LLMToolSelectorOptionsSchema,\n async wrapModelCall(request, handler) {\n const selectionRequest = await prepareSelectionRequest(\n request,\n options,\n request.runtime\n );\n if (!selectionRequest) {\n return handler(request);\n }\n\n // Create dynamic response model with union of literal tool names\n const toolSelectionSchema = createToolSelectionResponse(\n selectionRequest.availableTools\n );\n const structuredModel =\n await selectionRequest.model.withStructuredOutput?.(\n toolSelectionSchema\n );\n\n const baseConfig: RunnableConfig =\n pickRunnableConfigKeys(request.runtime) ?? {};\n const config = mergeConfigs(baseConfig, {\n metadata: { lc_source: \"llmToolSelector\" },\n tags: [INTERNAL_CALL_TAG],\n callbacks: [],\n });\n\n const response = await structuredModel?.invoke(\n [\n { role: \"system\", content: selectionRequest.systemMessage },\n selectionRequest.lastUserMessage,\n ],\n config\n );\n\n // Response should be an object with a tools array\n if (!response || typeof response !== \"object\" || !(\"tools\" in response)) {\n throw new Error(\n `Expected object response with tools array, got ${typeof response}`\n );\n }\n\n return handler(\n processSelectionResponse(\n response as { tools: string[] },\n selectionRequest.availableTools,\n selectionRequest.validToolNames,\n request,\n options\n )\n );\n },\n });\n}\n\n/**\n * Prepare inputs for tool selection.\n *\n * @param request - The model request to process.\n * @param options - Configuration options.\n * @param runtime - Runtime context.\n * @returns SelectionRequest with prepared inputs, or null if no selection is needed.\n */\nasync function prepareSelectionRequest<\n TState extends Record<string, unknown> = Record<string, unknown>,\n TContext = unknown,\n>(\n request: ModelRequest<TState, TContext>,\n options: LLMToolSelectorConfig,\n runtime: Runtime<LLMToolSelectorConfig>\n): Promise<SelectionRequest | undefined> {\n const model = runtime.context.model ?? options.model;\n const maxTools = runtime.context.maxTools ?? options.maxTools;\n const alwaysInclude =\n runtime.context.alwaysInclude ?? options.alwaysInclude ?? [];\n const systemPrompt =\n runtime.context.systemPrompt ??\n options.systemPrompt ??\n DEFAULT_SYSTEM_PROMPT;\n\n /**\n * If no tools available, return null\n */\n if (!request.tools || request.tools.length === 0) {\n return undefined;\n }\n\n /**\n * Filter to only StructuredToolInterface instances (exclude provider-specific tool dicts)\n */\n const baseTools = request.tools.filter(\n (tool): tool is StructuredToolInterface =>\n typeof tool === \"object\" &&\n \"name\" in tool &&\n \"description\" in tool &&\n typeof tool.name === \"string\"\n );\n\n /**\n * Validate that alwaysInclude tools exist\n */\n if (alwaysInclude.length > 0) {\n const availableToolNames = new Set(baseTools.map((tool) => tool.name));\n const missingTools = alwaysInclude.filter(\n (name) => !availableToolNames.has(name)\n );\n if (missingTools.length > 0) {\n throw new Error(\n `Tools in alwaysInclude not found in request: ${missingTools.join(\n \", \"\n )}. ` +\n `Available tools: ${Array.from(availableToolNames).sort().join(\", \")}`\n );\n }\n }\n\n /**\n * Separate tools that are always included from those available for selection\n */\n const availableTools = baseTools.filter(\n (tool) => !alwaysInclude.includes(tool.name)\n );\n\n /**\n * If no tools available for selection, return null\n */\n if (availableTools.length === 0) {\n return undefined;\n }\n\n let systemMessage = systemPrompt;\n /**\n * If there's a maxTools limit, append instructions to the system prompt\n */\n if (maxTools !== undefined) {\n systemMessage +=\n `\\nIMPORTANT: List the tool names in order of relevance, ` +\n `with the most relevant first. ` +\n `If you exceed the maximum number of tools, ` +\n `only the first ${maxTools} will be used.`;\n }\n\n /**\n * Get the last user message from the conversation history\n */\n let lastUserMessage: HumanMessage | undefined;\n for (const message of request.messages) {\n if (HumanMessage.isInstance(message)) {\n lastUserMessage = message;\n }\n }\n\n if (!lastUserMessage) {\n throw new Error(\"No user message found in request messages\");\n }\n\n const modelInstance = !model\n ? (request.model as BaseLanguageModel)\n : typeof model === \"string\"\n ? await initChatModel(model)\n : model;\n\n const validToolNames = availableTools.map((tool) => tool.name);\n\n return {\n availableTools,\n systemMessage,\n lastUserMessage,\n model: modelInstance,\n validToolNames,\n };\n}\n\n/**\n * Process the selection response and return filtered ModelRequest.\n *\n * @param response - The structured output response from the model.\n * @param availableTools - Tools available for selection.\n * @param validToolNames - Valid tool names that can be selected.\n * @param request - Original model request.\n * @param options - Configuration options.\n * @returns Modified ModelRequest with filtered tools.\n */\nfunction processSelectionResponse<\n TState extends Record<string, unknown> = Record<string, unknown>,\n TContext = unknown,\n>(\n response: { tools: string[] },\n availableTools: StructuredToolInterface[],\n validToolNames: string[],\n request: ModelRequest<TState, TContext>,\n options: LLMToolSelectorConfig\n): ModelRequest<TState, TContext> {\n const maxTools = options.maxTools;\n const alwaysInclude = options.alwaysInclude ?? [];\n\n const selectedToolNames: string[] = [];\n const invalidToolSelections: string[] = [];\n\n for (const toolName of response.tools) {\n if (!validToolNames.includes(toolName)) {\n invalidToolSelections.push(toolName);\n continue;\n }\n\n /**\n * Only add if not already selected and within maxTools limit\n */\n if (\n !selectedToolNames.includes(toolName) &&\n (maxTools === undefined || selectedToolNames.length < maxTools)\n ) {\n selectedToolNames.push(toolName);\n }\n }\n\n if (invalidToolSelections.length > 0) {\n throw new Error(\n `Model selected invalid tools: ${invalidToolSelections.join(\", \")}`\n );\n }\n\n /**\n * Filter tools based on selection\n */\n const selectedTools = availableTools.filter((tool) =>\n selectedToolNames.includes(tool.name)\n );\n\n /**\n * Append always-included tools\n */\n const alwaysIncludedTools = (request.tools ?? []).filter(\n (tool): tool is StructuredToolInterface =>\n typeof tool === \"object\" &&\n \"name\" in tool &&\n typeof tool.name === \"string\" &&\n alwaysInclude.includes(tool.name)\n );\n selectedTools.push(...alwaysIncludedTools);\n\n /**\n * Also preserve any provider-specific tool dicts from the original request\n */\n const providerTools = (request.tools ?? []).filter(\n (tool) =>\n !(\n typeof tool === \"object\" &&\n \"name\" in tool &&\n \"description\" in tool &&\n typeof tool.name === \"string\"\n )\n );\n\n return {\n ...request,\n tools: [...selectedTools, ...providerTools],\n };\n}\n"],"mappings":";;;;;;;;AAiBA,MAAM,wBACJ;;;;;;;AAmBF,SAAS,4BAA4B,OAAkC;CACrE,IAAI,CAAC,SAAS,MAAM,WAAW,GAC7B,MAAM,IAAI,MAAM,wCAAwC;CAI1D,MAAM,eAAe,MAAM,KAAK,SAASA,OAAAA,EAAE,QAAQ,KAAK,IAAI,CAAC;CAC7D,MAAM,WAAWA,OAAAA,EAAE,MACjB,YAKF;CAEA,OAAOA,OAAAA,EAAE,OAAO,EACd,OAAOA,OAAAA,EACJ,MAAM,QAAQ,CAAC,CACf,SAAS,oDAAoD,EAClE,CAAC;AACH;;;;AAKA,MAAa,+BAA+BA,OAAAA,EAAE,OAAO;;;;CAInD,OAAOA,OAAAA,EAAE,OAAO,CAAC,CAAC,GAAGA,OAAAA,EAAE,WAAWC,qCAAAA,iBAAiB,CAAC,CAAC,CAAC,SAAS;;;;CAI/D,cAAcD,OAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;;;;;CAKlC,UAAUA,OAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;;;;;CAK9B,eAAeA,OAAAA,EAAE,MAAMA,OAAAA,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS;AAC9C,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CD,SAAgB,0BAA0B,SAAgC;CACxE,OAAOE,mBAAAA,iBAAiB;EACtB,MAAM;EACN,eAAe;EACf,MAAM,cAAc,SAAS,SAAS;GACpC,MAAM,mBAAmB,MAAM,wBAC7B,SACA,SACA,QAAQ,OACV;GACA,IAAI,CAAC,kBACH,OAAO,QAAQ,OAAO;GAIxB,MAAM,sBAAsB,4BAC1B,iBAAiB,cACnB;GACA,MAAM,kBACJ,MAAM,iBAAiB,MAAM,uBAC3B,mBACF;GAIF,MAAM,UAAA,GAAA,0BAAA,aAAA,EAAA,GAAA,0BAAA,uBAAA,CADmB,QAAQ,OAAO,KAAK,CAAC,GACN;IACtC,UAAU,EAAE,WAAW,kBAAkB;IACzC,MAAM,CAACC,kBAAAA,iBAAiB;IACxB,WAAW,CAAC;GACd,CAAC;GAED,MAAM,WAAW,MAAM,iBAAiB,OACtC,CACE;IAAE,MAAM;IAAU,SAAS,iBAAiB;GAAc,GAC1D,iBAAiB,eACnB,GACA,MACF;GAGA,IAAI,CAAC,YAAY,OAAO,aAAa,YAAY,EAAE,WAAW,WAC5D,MAAM,IAAI,MACR,kDAAkD,OAAO,UAC3D;GAGF,OAAO,QACL,yBACE,UACA,iBAAiB,gBACjB,iBAAiB,gBACjB,SACA,OACF,CACF;EACF;CACF,CAAC;AACH;;;;;;;;;AAUA,eAAe,wBAIb,SACA,SACA,SACuC;CACvC,MAAM,QAAQ,QAAQ,QAAQ,SAAS,QAAQ;CAC/C,MAAM,WAAW,QAAQ,QAAQ,YAAY,QAAQ;CACrD,MAAM,gBACJ,QAAQ,QAAQ,iBAAiB,QAAQ,iBAAiB,CAAC;CAC7D,MAAM,eACJ,QAAQ,QAAQ,gBAChB,QAAQ,gBACR;;;;CAKF,IAAI,CAAC,QAAQ,SAAS,QAAQ,MAAM,WAAW,GAC7C;;;;CAMF,MAAM,YAAY,QAAQ,MAAM,QAC7B,SACC,OAAO,SAAS,YAChB,UAAU,QACV,iBAAiB,QACjB,OAAO,KAAK,SAAS,QACzB;;;;CAKA,IAAI,cAAc,SAAS,GAAG;EAC5B,MAAM,qBAAqB,IAAI,IAAI,UAAU,KAAK,SAAS,KAAK,IAAI,CAAC;EACrE,MAAM,eAAe,cAAc,QAChC,SAAS,CAAC,mBAAmB,IAAI,IAAI,CACxC;EACA,IAAI,aAAa,SAAS,GACxB,MAAM,IAAI,MACR,gDAAgD,aAAa,KAC3D,IACF,EAAE,qBACoB,MAAM,KAAK,kBAAkB,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,GACvE;CAEJ;;;;CAKA,MAAM,iBAAiB,UAAU,QAC9B,SAAS,CAAC,cAAc,SAAS,KAAK,IAAI,CAC7C;;;;CAKA,IAAI,eAAe,WAAW,GAC5B;CAGF,IAAI,gBAAgB;;;;CAIpB,IAAI,aAAa,KAAA,GACf,iBACE;gJAGkB,SAAS;;;;CAM/B,IAAI;CACJ,KAAK,MAAM,WAAW,QAAQ,UAC5B,IAAIC,yBAAAA,aAAa,WAAW,OAAO,GACjC,kBAAkB;CAItB,IAAI,CAAC,iBACH,MAAM,IAAI,MAAM,2CAA2C;CAG7D,MAAM,gBAAgB,CAAC,QAClB,QAAQ,QACT,OAAO,UAAU,WACf,MAAMC,8BAAAA,cAAc,KAAK,IACzB;CAEN,MAAM,iBAAiB,eAAe,KAAK,SAAS,KAAK,IAAI;CAE7D,OAAO;EACL;EACA;EACA;EACA,OAAO;EACP;CACF;AACF;;;;;;;;;;;AAYA,SAAS,yBAIP,UACA,gBACA,gBACA,SACA,SACgC;CAChC,MAAM,WAAW,QAAQ;CACzB,MAAM,gBAAgB,QAAQ,iBAAiB,CAAC;CAEhD,MAAM,oBAA8B,CAAC;CACrC,MAAM,wBAAkC,CAAC;CAEzC,KAAK,MAAM,YAAY,SAAS,OAAO;EACrC,IAAI,CAAC,eAAe,SAAS,QAAQ,GAAG;GACtC,sBAAsB,KAAK,QAAQ;GACnC;EACF;;;;EAKA,IACE,CAAC,kBAAkB,SAAS,QAAQ,MACnC,aAAa,KAAA,KAAa,kBAAkB,SAAS,WAEtD,kBAAkB,KAAK,QAAQ;CAEnC;CAEA,IAAI,sBAAsB,SAAS,GACjC,MAAM,IAAI,MACR,iCAAiC,sBAAsB,KAAK,IAAI,GAClE;;;;CAMF,MAAM,gBAAgB,eAAe,QAAQ,SAC3C,kBAAkB,SAAS,KAAK,IAAI,CACtC;;;;CAKA,MAAM,uBAAuB,QAAQ,SAAS,CAAC,EAAA,CAAG,QAC/C,SACC,OAAO,SAAS,YAChB,UAAU,QACV,OAAO,KAAK,SAAS,YACrB,cAAc,SAAS,KAAK,IAAI,CACpC;CACA,cAAc,KAAK,GAAG,mBAAmB;;;;CAKzC,MAAM,iBAAiB,QAAQ,SAAS,CAAC,EAAA,CAAG,QACzC,SACC,EACE,OAAO,SAAS,YAChB,UAAU,QACV,iBAAiB,QACjB,OAAO,KAAK,SAAS,SAE3B;CAEA,OAAO;EACL,GAAG;EACH,OAAO,CAAC,GAAG,eAAe,GAAG,aAAa;CAC5C;AACF"}
@@ -1,10 +1,7 @@
1
1
  import { AgentMiddleware } from "./types.cjs";
2
- import * as _$_langchain_core_language_models_base0 from "@langchain/core/language_models/base";
3
2
  import { BaseLanguageModel } from "@langchain/core/language_models/base";
4
- import * as _$_langchain_core_tools0 from "@langchain/core/tools";
5
3
  import { InferInteropZodInput } from "@langchain/core/utils/types";
6
4
  import { z } from "zod/v3";
7
-
8
5
  //#region src/agents/middleware/llmToolSelector.d.ts
9
6
  /**
10
7
  * Options for configuring the LLM Tool Selector middleware.
@@ -13,7 +10,7 @@ declare const LLMToolSelectorOptionsSchema: z.ZodObject<{
13
10
  /**
14
11
  * The language model to use for tool selection (default: the provided model from the agent options).
15
12
  */
16
- model: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodType<BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions>, z.ZodTypeDef, BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions>>]>>;
13
+ model: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodType<BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions>, z.ZodTypeDef, BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions>>]>>;
17
14
  /**
18
15
  * System prompt for the tool selection model.
19
16
  */
@@ -29,12 +26,12 @@ declare const LLMToolSelectorOptionsSchema: z.ZodObject<{
29
26
  */
30
27
  alwaysInclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
31
28
  }, "strip", z.ZodTypeAny, {
32
- model?: string | BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions> | undefined;
29
+ model?: string | BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions> | undefined;
33
30
  systemPrompt?: string | undefined;
34
31
  maxTools?: number | undefined;
35
32
  alwaysInclude?: string[] | undefined;
36
33
  }, {
37
- model?: string | BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions> | undefined;
34
+ model?: string | BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions> | undefined;
38
35
  systemPrompt?: string | undefined;
39
36
  maxTools?: number | undefined;
40
37
  alwaysInclude?: string[] | undefined;
@@ -82,7 +79,7 @@ declare function llmToolSelectorMiddleware(options: LLMToolSelectorConfig): Agen
82
79
  /**
83
80
  * The language model to use for tool selection (default: the provided model from the agent options).
84
81
  */
85
- model: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodType<BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions>, z.ZodTypeDef, BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions>>]>>;
82
+ model: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodType<BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions>, z.ZodTypeDef, BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions>>]>>;
86
83
  /**
87
84
  * System prompt for the tool selection model.
88
85
  */
@@ -98,21 +95,21 @@ declare function llmToolSelectorMiddleware(options: LLMToolSelectorConfig): Agen
98
95
  */
99
96
  alwaysInclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
100
97
  }, "strip", z.ZodTypeAny, {
101
- model?: string | BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions> | undefined;
98
+ model?: string | BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions> | undefined;
102
99
  systemPrompt?: string | undefined;
103
100
  maxTools?: number | undefined;
104
101
  alwaysInclude?: string[] | undefined;
105
102
  }, {
106
- model?: string | BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions> | undefined;
103
+ model?: string | BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions> | undefined;
107
104
  systemPrompt?: string | undefined;
108
105
  maxTools?: number | undefined;
109
106
  alwaysInclude?: string[] | undefined;
110
107
  }>, {
111
- model?: string | BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions> | undefined;
108
+ model?: string | BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions> | undefined;
112
109
  systemPrompt?: string | undefined;
113
110
  maxTools?: number | undefined;
114
111
  alwaysInclude?: string[] | undefined;
115
- }, readonly (_$_langchain_core_tools0.ServerTool | _$_langchain_core_tools0.ClientTool)[], readonly []>;
112
+ }, readonly (import("@langchain/core/tools").ServerTool | import("@langchain/core/tools").ClientTool)[], readonly []>;
116
113
  //#endregion
117
- export { LLMToolSelectorConfig, llmToolSelectorMiddleware };
114
+ export { LLMToolSelectorConfig, LLMToolSelectorOptionsSchema, llmToolSelectorMiddleware };
118
115
  //# sourceMappingURL=llmToolSelector.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"llmToolSelector.d.cts","names":[],"sources":["../../../src/agents/middleware/llmToolSelector.ts"],"mappings":";;;;;;;;;;;cA6Da,4BAAA,EAA4B,CAAA,CAAA,SAAA;;AAAzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoBY,qBAAA,GAAwB,oBAAA,QAC3B,4BAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyCO,yBAAA,CAA0B,OAAA,EAAS,qBAAA,8BAAqB,CAAA,CAAA,SAAA;;;;;;;;;;AA1CxE;;;;EACqC;AAyCrC;;;;;;;;;;;;;;;8CAAwE,uCAAA,CAAA,4BAAA"}
1
+ {"version":3,"file":"llmToolSelector.d.cts","names":[],"sources":["../../../src/agents/middleware/llmToolSelector.ts"],"mappings":";;;;;;;;cA8Da,8BAA4B,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoB7B,wBAAwB,4BAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyCO,0BAA0B,SAAS,mDAAqB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6CAyDvE,6CAAA"}
@@ -1,10 +1,7 @@
1
1
  import { AgentMiddleware } from "./types.js";
2
- import * as _$_langchain_core_tools0 from "@langchain/core/tools";
3
2
  import { InferInteropZodInput } from "@langchain/core/utils/types";
4
3
  import { z } from "zod/v3";
5
- import * as _$_langchain_core_language_models_base0 from "@langchain/core/language_models/base";
6
4
  import { BaseLanguageModel } from "@langchain/core/language_models/base";
7
-
8
5
  //#region src/agents/middleware/llmToolSelector.d.ts
9
6
  /**
10
7
  * Options for configuring the LLM Tool Selector middleware.
@@ -13,7 +10,7 @@ declare const LLMToolSelectorOptionsSchema: z.ZodObject<{
13
10
  /**
14
11
  * The language model to use for tool selection (default: the provided model from the agent options).
15
12
  */
16
- model: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodType<BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions>, z.ZodTypeDef, BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions>>]>>;
13
+ model: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodType<BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions>, z.ZodTypeDef, BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions>>]>>;
17
14
  /**
18
15
  * System prompt for the tool selection model.
19
16
  */
@@ -29,12 +26,12 @@ declare const LLMToolSelectorOptionsSchema: z.ZodObject<{
29
26
  */
30
27
  alwaysInclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
31
28
  }, "strip", z.ZodTypeAny, {
32
- model?: string | BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions> | undefined;
29
+ model?: string | BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions> | undefined;
33
30
  systemPrompt?: string | undefined;
34
31
  maxTools?: number | undefined;
35
32
  alwaysInclude?: string[] | undefined;
36
33
  }, {
37
- model?: string | BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions> | undefined;
34
+ model?: string | BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions> | undefined;
38
35
  systemPrompt?: string | undefined;
39
36
  maxTools?: number | undefined;
40
37
  alwaysInclude?: string[] | undefined;
@@ -82,7 +79,7 @@ declare function llmToolSelectorMiddleware(options: LLMToolSelectorConfig): Agen
82
79
  /**
83
80
  * The language model to use for tool selection (default: the provided model from the agent options).
84
81
  */
85
- model: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodType<BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions>, z.ZodTypeDef, BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions>>]>>;
82
+ model: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodType<BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions>, z.ZodTypeDef, BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions>>]>>;
86
83
  /**
87
84
  * System prompt for the tool selection model.
88
85
  */
@@ -98,21 +95,21 @@ declare function llmToolSelectorMiddleware(options: LLMToolSelectorConfig): Agen
98
95
  */
99
96
  alwaysInclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
100
97
  }, "strip", z.ZodTypeAny, {
101
- model?: string | BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions> | undefined;
98
+ model?: string | BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions> | undefined;
102
99
  systemPrompt?: string | undefined;
103
100
  maxTools?: number | undefined;
104
101
  alwaysInclude?: string[] | undefined;
105
102
  }, {
106
- model?: string | BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions> | undefined;
103
+ model?: string | BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions> | undefined;
107
104
  systemPrompt?: string | undefined;
108
105
  maxTools?: number | undefined;
109
106
  alwaysInclude?: string[] | undefined;
110
107
  }>, {
111
- model?: string | BaseLanguageModel<unknown, _$_langchain_core_language_models_base0.BaseLanguageModelCallOptions> | undefined;
108
+ model?: string | BaseLanguageModel<unknown, import("@langchain/core/language_models/base").BaseLanguageModelCallOptions> | undefined;
112
109
  systemPrompt?: string | undefined;
113
110
  maxTools?: number | undefined;
114
111
  alwaysInclude?: string[] | undefined;
115
- }, readonly (_$_langchain_core_tools0.ServerTool | _$_langchain_core_tools0.ClientTool)[], readonly []>;
112
+ }, readonly (import("@langchain/core/tools").ServerTool | import("@langchain/core/tools").ClientTool)[], readonly []>;
116
113
  //#endregion
117
- export { LLMToolSelectorConfig, llmToolSelectorMiddleware };
114
+ export { LLMToolSelectorConfig, LLMToolSelectorOptionsSchema, llmToolSelectorMiddleware };
118
115
  //# sourceMappingURL=llmToolSelector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"llmToolSelector.d.ts","names":[],"sources":["../../../src/agents/middleware/llmToolSelector.ts"],"mappings":";;;;;;;;;;;cA6Da,4BAAA,EAA4B,CAAA,CAAA,SAAA;;AAAzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoBY,qBAAA,GAAwB,oBAAA,QAC3B,4BAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyCO,yBAAA,CAA0B,OAAA,EAAS,qBAAA,8BAAqB,CAAA,CAAA,SAAA;;;;;;;;;;AA1CxE;;;;EACqC;AAyCrC;;;;;;;;;;;;;;;8CAAwE,uCAAA,CAAA,4BAAA"}
1
+ {"version":3,"file":"llmToolSelector.d.ts","names":[],"sources":["../../../src/agents/middleware/llmToolSelector.ts"],"mappings":";;;;;;;;cA8Da,8BAA4B,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoB7B,wBAAwB,4BAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyCO,0BAA0B,SAAS,mDAAqB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6CAyDvE,6CAAA"}
@@ -1,5 +1,6 @@
1
1
  import { initChatModel } from "../../chat_models/universal.js";
2
2
  import { createMiddleware } from "../middleware.js";
3
+ import { INTERNAL_CALL_TAG } from "./constants.js";
3
4
  import { HumanMessage } from "@langchain/core/messages";
4
5
  import { mergeConfigs, pickRunnableConfigKeys } from "@langchain/core/runnables";
5
6
  import { z } from "zod/v3";
@@ -90,6 +91,7 @@ function llmToolSelectorMiddleware(options) {
90
91
  const structuredModel = await selectionRequest.model.withStructuredOutput?.(toolSelectionSchema);
91
92
  const config = mergeConfigs(pickRunnableConfigKeys(request.runtime) ?? {}, {
92
93
  metadata: { lc_source: "llmToolSelector" },
94
+ tags: [INTERNAL_CALL_TAG],
93
95
  callbacks: []
94
96
  });
95
97
  const response = await structuredModel?.invoke([{
@@ -205,6 +207,6 @@ function processSelectionResponse(response, availableTools, validToolNames, requ
205
207
  };
206
208
  }
207
209
  //#endregion
208
- export { llmToolSelectorMiddleware };
210
+ export { LLMToolSelectorOptionsSchema, llmToolSelectorMiddleware };
209
211
 
210
212
  //# sourceMappingURL=llmToolSelector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"llmToolSelector.js","names":[],"sources":["../../../src/agents/middleware/llmToolSelector.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { BaseLanguageModel } from \"@langchain/core/language_models/base\";\nimport type { InferInteropZodInput } from \"@langchain/core/utils/types\";\nimport { HumanMessage } from \"@langchain/core/messages\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\n\nimport { createMiddleware } from \"../middleware.js\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport type { Runtime } from \"../runtime.js\";\nimport type { ModelRequest } from \"../nodes/types.js\";\nimport {\n mergeConfigs,\n pickRunnableConfigKeys,\n type RunnableConfig,\n} from \"@langchain/core/runnables\";\n\nconst DEFAULT_SYSTEM_PROMPT =\n \"Your goal is to select the most relevant tools for answering the user's query.\";\n\n/**\n * Prepared inputs for tool selection.\n */\ninterface SelectionRequest {\n availableTools: StructuredToolInterface[];\n systemMessage: string;\n lastUserMessage: HumanMessage;\n model: BaseLanguageModel;\n validToolNames: string[];\n}\n\n/**\n * Create a structured output schema for tool selection.\n *\n * @param tools - Available tools to include in the schema.\n * @returns Zod schema where each tool name is a literal with its description.\n */\nfunction createToolSelectionResponse(tools: StructuredToolInterface[]) {\n if (!tools || tools.length === 0) {\n throw new Error(\"Invalid usage: tools must be non-empty\");\n }\n\n // Create a union of literals for each tool name\n const toolLiterals = tools.map((tool) => z.literal(tool.name));\n const toolEnum = z.union(\n toolLiterals as [\n z.ZodLiteral<string>,\n z.ZodLiteral<string>,\n ...z.ZodLiteral<string>[],\n ]\n );\n\n return z.object({\n tools: z\n .array(toolEnum)\n .describe(\"Tools to use. Place the most relevant tools first.\"),\n });\n}\n\n/**\n * Options for configuring the LLM Tool Selector middleware.\n */\nexport const LLMToolSelectorOptionsSchema = z.object({\n /**\n * The language model to use for tool selection (default: the provided model from the agent options).\n */\n model: z.string().or(z.instanceof(BaseLanguageModel)).optional(),\n /**\n * System prompt for the tool selection model.\n */\n systemPrompt: z.string().optional(),\n /**\n * Maximum number of tools to select. If the model selects more,\n * only the first maxTools will be used. No limit if not specified.\n */\n maxTools: z.number().optional(),\n /**\n * Tool names to always include regardless of selection.\n * These do not count against the maxTools limit.\n */\n alwaysInclude: z.array(z.string()).optional(),\n});\nexport type LLMToolSelectorConfig = InferInteropZodInput<\n typeof LLMToolSelectorOptionsSchema\n>;\n\n/**\n * Middleware for selecting tools using an LLM-based strategy.\n *\n * When an agent has many tools available, this middleware filters them down\n * to only the most relevant ones for the user's query. This reduces token usage\n * and helps the main model focus on the right tools.\n *\n * @param options - Configuration options for the middleware\n * @param options.model - The language model to use for tool selection (default: the provided model from the agent options).\n * @param options.systemPrompt - Instructions for the selection model.\n * @param options.maxTools - Maximum number of tools to select. If the model selects more,\n * only the first maxTools will be used. No limit if not specified.\n * @param options.alwaysInclude - Tool names to always include regardless of selection.\n * These do not count against the maxTools limit.\n *\n * @example\n * Limit to 3 tools:\n * ```ts\n * import { llmToolSelectorMiddleware } from \"langchain/agents/middleware\";\n *\n * const middleware = llmToolSelectorMiddleware({ maxTools: 3 });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [tool1, tool2, tool3, tool4, tool5],\n * middleware: [middleware],\n * });\n * ```\n *\n * @example\n * Use a smaller model for selection:\n * ```ts\n * const middleware = llmToolSelectorMiddleware({\n * model: \"openai:gpt-4o-mini\",\n * maxTools: 2\n * });\n * ```\n */\nexport function llmToolSelectorMiddleware(options: LLMToolSelectorConfig) {\n return createMiddleware({\n name: \"LLMToolSelector\",\n contextSchema: LLMToolSelectorOptionsSchema,\n async wrapModelCall(request, handler) {\n const selectionRequest = await prepareSelectionRequest(\n request,\n options,\n request.runtime\n );\n if (!selectionRequest) {\n return handler(request);\n }\n\n // Create dynamic response model with union of literal tool names\n const toolSelectionSchema = createToolSelectionResponse(\n selectionRequest.availableTools\n );\n const structuredModel =\n await selectionRequest.model.withStructuredOutput?.(\n toolSelectionSchema\n );\n\n const baseConfig: RunnableConfig =\n pickRunnableConfigKeys(request.runtime) ?? {};\n const config = mergeConfigs(baseConfig, {\n metadata: { lc_source: \"llmToolSelector\" },\n callbacks: [],\n });\n\n const response = await structuredModel?.invoke(\n [\n { role: \"system\", content: selectionRequest.systemMessage },\n selectionRequest.lastUserMessage,\n ],\n config\n );\n\n // Response should be an object with a tools array\n if (!response || typeof response !== \"object\" || !(\"tools\" in response)) {\n throw new Error(\n `Expected object response with tools array, got ${typeof response}`\n );\n }\n\n return handler(\n processSelectionResponse(\n response as { tools: string[] },\n selectionRequest.availableTools,\n selectionRequest.validToolNames,\n request,\n options\n )\n );\n },\n });\n}\n\n/**\n * Prepare inputs for tool selection.\n *\n * @param request - The model request to process.\n * @param options - Configuration options.\n * @param runtime - Runtime context.\n * @returns SelectionRequest with prepared inputs, or null if no selection is needed.\n */\nasync function prepareSelectionRequest<\n TState extends Record<string, unknown> = Record<string, unknown>,\n TContext = unknown,\n>(\n request: ModelRequest<TState, TContext>,\n options: LLMToolSelectorConfig,\n runtime: Runtime<LLMToolSelectorConfig>\n): Promise<SelectionRequest | undefined> {\n const model = runtime.context.model ?? options.model;\n const maxTools = runtime.context.maxTools ?? options.maxTools;\n const alwaysInclude =\n runtime.context.alwaysInclude ?? options.alwaysInclude ?? [];\n const systemPrompt =\n runtime.context.systemPrompt ??\n options.systemPrompt ??\n DEFAULT_SYSTEM_PROMPT;\n\n /**\n * If no tools available, return null\n */\n if (!request.tools || request.tools.length === 0) {\n return undefined;\n }\n\n /**\n * Filter to only StructuredToolInterface instances (exclude provider-specific tool dicts)\n */\n const baseTools = request.tools.filter(\n (tool): tool is StructuredToolInterface =>\n typeof tool === \"object\" &&\n \"name\" in tool &&\n \"description\" in tool &&\n typeof tool.name === \"string\"\n );\n\n /**\n * Validate that alwaysInclude tools exist\n */\n if (alwaysInclude.length > 0) {\n const availableToolNames = new Set(baseTools.map((tool) => tool.name));\n const missingTools = alwaysInclude.filter(\n (name) => !availableToolNames.has(name)\n );\n if (missingTools.length > 0) {\n throw new Error(\n `Tools in alwaysInclude not found in request: ${missingTools.join(\n \", \"\n )}. ` +\n `Available tools: ${Array.from(availableToolNames).sort().join(\", \")}`\n );\n }\n }\n\n /**\n * Separate tools that are always included from those available for selection\n */\n const availableTools = baseTools.filter(\n (tool) => !alwaysInclude.includes(tool.name)\n );\n\n /**\n * If no tools available for selection, return null\n */\n if (availableTools.length === 0) {\n return undefined;\n }\n\n let systemMessage = systemPrompt;\n /**\n * If there's a maxTools limit, append instructions to the system prompt\n */\n if (maxTools !== undefined) {\n systemMessage +=\n `\\nIMPORTANT: List the tool names in order of relevance, ` +\n `with the most relevant first. ` +\n `If you exceed the maximum number of tools, ` +\n `only the first ${maxTools} will be used.`;\n }\n\n /**\n * Get the last user message from the conversation history\n */\n let lastUserMessage: HumanMessage | undefined;\n for (const message of request.messages) {\n if (HumanMessage.isInstance(message)) {\n lastUserMessage = message;\n }\n }\n\n if (!lastUserMessage) {\n throw new Error(\"No user message found in request messages\");\n }\n\n const modelInstance = !model\n ? (request.model as BaseLanguageModel)\n : typeof model === \"string\"\n ? await initChatModel(model)\n : model;\n\n const validToolNames = availableTools.map((tool) => tool.name);\n\n return {\n availableTools,\n systemMessage,\n lastUserMessage,\n model: modelInstance,\n validToolNames,\n };\n}\n\n/**\n * Process the selection response and return filtered ModelRequest.\n *\n * @param response - The structured output response from the model.\n * @param availableTools - Tools available for selection.\n * @param validToolNames - Valid tool names that can be selected.\n * @param request - Original model request.\n * @param options - Configuration options.\n * @returns Modified ModelRequest with filtered tools.\n */\nfunction processSelectionResponse<\n TState extends Record<string, unknown> = Record<string, unknown>,\n TContext = unknown,\n>(\n response: { tools: string[] },\n availableTools: StructuredToolInterface[],\n validToolNames: string[],\n request: ModelRequest<TState, TContext>,\n options: LLMToolSelectorConfig\n): ModelRequest<TState, TContext> {\n const maxTools = options.maxTools;\n const alwaysInclude = options.alwaysInclude ?? [];\n\n const selectedToolNames: string[] = [];\n const invalidToolSelections: string[] = [];\n\n for (const toolName of response.tools) {\n if (!validToolNames.includes(toolName)) {\n invalidToolSelections.push(toolName);\n continue;\n }\n\n /**\n * Only add if not already selected and within maxTools limit\n */\n if (\n !selectedToolNames.includes(toolName) &&\n (maxTools === undefined || selectedToolNames.length < maxTools)\n ) {\n selectedToolNames.push(toolName);\n }\n }\n\n if (invalidToolSelections.length > 0) {\n throw new Error(\n `Model selected invalid tools: ${invalidToolSelections.join(\", \")}`\n );\n }\n\n /**\n * Filter tools based on selection\n */\n const selectedTools = availableTools.filter((tool) =>\n selectedToolNames.includes(tool.name)\n );\n\n /**\n * Append always-included tools\n */\n const alwaysIncludedTools = (request.tools ?? []).filter(\n (tool): tool is StructuredToolInterface =>\n typeof tool === \"object\" &&\n \"name\" in tool &&\n typeof tool.name === \"string\" &&\n alwaysInclude.includes(tool.name)\n );\n selectedTools.push(...alwaysIncludedTools);\n\n /**\n * Also preserve any provider-specific tool dicts from the original request\n */\n const providerTools = (request.tools ?? []).filter(\n (tool) =>\n !(\n typeof tool === \"object\" &&\n \"name\" in tool &&\n \"description\" in tool &&\n typeof tool.name === \"string\"\n )\n );\n\n return {\n ...request,\n tools: [...selectedTools, ...providerTools],\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"llmToolSelector.js","names":[],"sources":["../../../src/agents/middleware/llmToolSelector.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { BaseLanguageModel } from \"@langchain/core/language_models/base\";\nimport type { InferInteropZodInput } from \"@langchain/core/utils/types\";\nimport { HumanMessage } from \"@langchain/core/messages\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\n\nimport { createMiddleware } from \"../middleware.js\";\nimport { INTERNAL_CALL_TAG } from \"./constants.js\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport type { Runtime } from \"../runtime.js\";\nimport type { ModelRequest } from \"../nodes/types.js\";\nimport {\n mergeConfigs,\n pickRunnableConfigKeys,\n type RunnableConfig,\n} from \"@langchain/core/runnables\";\n\nconst DEFAULT_SYSTEM_PROMPT =\n \"Your goal is to select the most relevant tools for answering the user's query.\";\n\n/**\n * Prepared inputs for tool selection.\n */\ninterface SelectionRequest {\n availableTools: StructuredToolInterface[];\n systemMessage: string;\n lastUserMessage: HumanMessage;\n model: BaseLanguageModel;\n validToolNames: string[];\n}\n\n/**\n * Create a structured output schema for tool selection.\n *\n * @param tools - Available tools to include in the schema.\n * @returns Zod schema where each tool name is a literal with its description.\n */\nfunction createToolSelectionResponse(tools: StructuredToolInterface[]) {\n if (!tools || tools.length === 0) {\n throw new Error(\"Invalid usage: tools must be non-empty\");\n }\n\n // Create a union of literals for each tool name\n const toolLiterals = tools.map((tool) => z.literal(tool.name));\n const toolEnum = z.union(\n toolLiterals as [\n z.ZodLiteral<string>,\n z.ZodLiteral<string>,\n ...z.ZodLiteral<string>[],\n ]\n );\n\n return z.object({\n tools: z\n .array(toolEnum)\n .describe(\"Tools to use. Place the most relevant tools first.\"),\n });\n}\n\n/**\n * Options for configuring the LLM Tool Selector middleware.\n */\nexport const LLMToolSelectorOptionsSchema = z.object({\n /**\n * The language model to use for tool selection (default: the provided model from the agent options).\n */\n model: z.string().or(z.instanceof(BaseLanguageModel)).optional(),\n /**\n * System prompt for the tool selection model.\n */\n systemPrompt: z.string().optional(),\n /**\n * Maximum number of tools to select. If the model selects more,\n * only the first maxTools will be used. No limit if not specified.\n */\n maxTools: z.number().optional(),\n /**\n * Tool names to always include regardless of selection.\n * These do not count against the maxTools limit.\n */\n alwaysInclude: z.array(z.string()).optional(),\n});\nexport type LLMToolSelectorConfig = InferInteropZodInput<\n typeof LLMToolSelectorOptionsSchema\n>;\n\n/**\n * Middleware for selecting tools using an LLM-based strategy.\n *\n * When an agent has many tools available, this middleware filters them down\n * to only the most relevant ones for the user's query. This reduces token usage\n * and helps the main model focus on the right tools.\n *\n * @param options - Configuration options for the middleware\n * @param options.model - The language model to use for tool selection (default: the provided model from the agent options).\n * @param options.systemPrompt - Instructions for the selection model.\n * @param options.maxTools - Maximum number of tools to select. If the model selects more,\n * only the first maxTools will be used. No limit if not specified.\n * @param options.alwaysInclude - Tool names to always include regardless of selection.\n * These do not count against the maxTools limit.\n *\n * @example\n * Limit to 3 tools:\n * ```ts\n * import { llmToolSelectorMiddleware } from \"langchain/agents/middleware\";\n *\n * const middleware = llmToolSelectorMiddleware({ maxTools: 3 });\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\",\n * tools: [tool1, tool2, tool3, tool4, tool5],\n * middleware: [middleware],\n * });\n * ```\n *\n * @example\n * Use a smaller model for selection:\n * ```ts\n * const middleware = llmToolSelectorMiddleware({\n * model: \"openai:gpt-4o-mini\",\n * maxTools: 2\n * });\n * ```\n */\nexport function llmToolSelectorMiddleware(options: LLMToolSelectorConfig) {\n return createMiddleware({\n name: \"LLMToolSelector\",\n contextSchema: LLMToolSelectorOptionsSchema,\n async wrapModelCall(request, handler) {\n const selectionRequest = await prepareSelectionRequest(\n request,\n options,\n request.runtime\n );\n if (!selectionRequest) {\n return handler(request);\n }\n\n // Create dynamic response model with union of literal tool names\n const toolSelectionSchema = createToolSelectionResponse(\n selectionRequest.availableTools\n );\n const structuredModel =\n await selectionRequest.model.withStructuredOutput?.(\n toolSelectionSchema\n );\n\n const baseConfig: RunnableConfig =\n pickRunnableConfigKeys(request.runtime) ?? {};\n const config = mergeConfigs(baseConfig, {\n metadata: { lc_source: \"llmToolSelector\" },\n tags: [INTERNAL_CALL_TAG],\n callbacks: [],\n });\n\n const response = await structuredModel?.invoke(\n [\n { role: \"system\", content: selectionRequest.systemMessage },\n selectionRequest.lastUserMessage,\n ],\n config\n );\n\n // Response should be an object with a tools array\n if (!response || typeof response !== \"object\" || !(\"tools\" in response)) {\n throw new Error(\n `Expected object response with tools array, got ${typeof response}`\n );\n }\n\n return handler(\n processSelectionResponse(\n response as { tools: string[] },\n selectionRequest.availableTools,\n selectionRequest.validToolNames,\n request,\n options\n )\n );\n },\n });\n}\n\n/**\n * Prepare inputs for tool selection.\n *\n * @param request - The model request to process.\n * @param options - Configuration options.\n * @param runtime - Runtime context.\n * @returns SelectionRequest with prepared inputs, or null if no selection is needed.\n */\nasync function prepareSelectionRequest<\n TState extends Record<string, unknown> = Record<string, unknown>,\n TContext = unknown,\n>(\n request: ModelRequest<TState, TContext>,\n options: LLMToolSelectorConfig,\n runtime: Runtime<LLMToolSelectorConfig>\n): Promise<SelectionRequest | undefined> {\n const model = runtime.context.model ?? options.model;\n const maxTools = runtime.context.maxTools ?? options.maxTools;\n const alwaysInclude =\n runtime.context.alwaysInclude ?? options.alwaysInclude ?? [];\n const systemPrompt =\n runtime.context.systemPrompt ??\n options.systemPrompt ??\n DEFAULT_SYSTEM_PROMPT;\n\n /**\n * If no tools available, return null\n */\n if (!request.tools || request.tools.length === 0) {\n return undefined;\n }\n\n /**\n * Filter to only StructuredToolInterface instances (exclude provider-specific tool dicts)\n */\n const baseTools = request.tools.filter(\n (tool): tool is StructuredToolInterface =>\n typeof tool === \"object\" &&\n \"name\" in tool &&\n \"description\" in tool &&\n typeof tool.name === \"string\"\n );\n\n /**\n * Validate that alwaysInclude tools exist\n */\n if (alwaysInclude.length > 0) {\n const availableToolNames = new Set(baseTools.map((tool) => tool.name));\n const missingTools = alwaysInclude.filter(\n (name) => !availableToolNames.has(name)\n );\n if (missingTools.length > 0) {\n throw new Error(\n `Tools in alwaysInclude not found in request: ${missingTools.join(\n \", \"\n )}. ` +\n `Available tools: ${Array.from(availableToolNames).sort().join(\", \")}`\n );\n }\n }\n\n /**\n * Separate tools that are always included from those available for selection\n */\n const availableTools = baseTools.filter(\n (tool) => !alwaysInclude.includes(tool.name)\n );\n\n /**\n * If no tools available for selection, return null\n */\n if (availableTools.length === 0) {\n return undefined;\n }\n\n let systemMessage = systemPrompt;\n /**\n * If there's a maxTools limit, append instructions to the system prompt\n */\n if (maxTools !== undefined) {\n systemMessage +=\n `\\nIMPORTANT: List the tool names in order of relevance, ` +\n `with the most relevant first. ` +\n `If you exceed the maximum number of tools, ` +\n `only the first ${maxTools} will be used.`;\n }\n\n /**\n * Get the last user message from the conversation history\n */\n let lastUserMessage: HumanMessage | undefined;\n for (const message of request.messages) {\n if (HumanMessage.isInstance(message)) {\n lastUserMessage = message;\n }\n }\n\n if (!lastUserMessage) {\n throw new Error(\"No user message found in request messages\");\n }\n\n const modelInstance = !model\n ? (request.model as BaseLanguageModel)\n : typeof model === \"string\"\n ? await initChatModel(model)\n : model;\n\n const validToolNames = availableTools.map((tool) => tool.name);\n\n return {\n availableTools,\n systemMessage,\n lastUserMessage,\n model: modelInstance,\n validToolNames,\n };\n}\n\n/**\n * Process the selection response and return filtered ModelRequest.\n *\n * @param response - The structured output response from the model.\n * @param availableTools - Tools available for selection.\n * @param validToolNames - Valid tool names that can be selected.\n * @param request - Original model request.\n * @param options - Configuration options.\n * @returns Modified ModelRequest with filtered tools.\n */\nfunction processSelectionResponse<\n TState extends Record<string, unknown> = Record<string, unknown>,\n TContext = unknown,\n>(\n response: { tools: string[] },\n availableTools: StructuredToolInterface[],\n validToolNames: string[],\n request: ModelRequest<TState, TContext>,\n options: LLMToolSelectorConfig\n): ModelRequest<TState, TContext> {\n const maxTools = options.maxTools;\n const alwaysInclude = options.alwaysInclude ?? [];\n\n const selectedToolNames: string[] = [];\n const invalidToolSelections: string[] = [];\n\n for (const toolName of response.tools) {\n if (!validToolNames.includes(toolName)) {\n invalidToolSelections.push(toolName);\n continue;\n }\n\n /**\n * Only add if not already selected and within maxTools limit\n */\n if (\n !selectedToolNames.includes(toolName) &&\n (maxTools === undefined || selectedToolNames.length < maxTools)\n ) {\n selectedToolNames.push(toolName);\n }\n }\n\n if (invalidToolSelections.length > 0) {\n throw new Error(\n `Model selected invalid tools: ${invalidToolSelections.join(\", \")}`\n );\n }\n\n /**\n * Filter tools based on selection\n */\n const selectedTools = availableTools.filter((tool) =>\n selectedToolNames.includes(tool.name)\n );\n\n /**\n * Append always-included tools\n */\n const alwaysIncludedTools = (request.tools ?? []).filter(\n (tool): tool is StructuredToolInterface =>\n typeof tool === \"object\" &&\n \"name\" in tool &&\n typeof tool.name === \"string\" &&\n alwaysInclude.includes(tool.name)\n );\n selectedTools.push(...alwaysIncludedTools);\n\n /**\n * Also preserve any provider-specific tool dicts from the original request\n */\n const providerTools = (request.tools ?? []).filter(\n (tool) =>\n !(\n typeof tool === \"object\" &&\n \"name\" in tool &&\n \"description\" in tool &&\n typeof tool.name === \"string\"\n )\n );\n\n return {\n ...request,\n tools: [...selectedTools, ...providerTools],\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- require("../../_virtual/_rolldown/runtime.cjs");
2
1
  const require_middleware = require("../middleware.cjs");
3
2
  let _langchain_core_messages = require("@langchain/core/messages");
4
3
  let zod_v3 = require("zod/v3");
@@ -1 +1 @@
1
- {"version":3,"file":"modelCallLimit.cjs","names":["z","createMiddleware","AIMessage"],"sources":["../../../src/agents/middleware/modelCallLimit.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { AIMessage } from \"@langchain/core/messages\";\nimport { InferInteropZodInput } from \"@langchain/core/utils/types\";\n\nimport { createMiddleware } from \"../middleware.js\";\n\nconst DEFAULT_EXIT_BEHAVIOR = \"end\";\n\nconst contextSchema = z.object({\n /**\n * The maximum number of model calls allowed per thread.\n */\n threadLimit: z.number().optional(),\n /**\n * The maximum number of model calls allowed per run.\n */\n runLimit: z.number().optional(),\n /**\n * The behavior to take when the limit is exceeded.\n * - \"error\" will throw an error and stop the agent.\n * - \"end\" will end the agent.\n * @default \"end\"\n */\n exitBehavior: z.enum([\"error\", \"end\"]).optional(),\n});\nexport type ModelCallLimitMiddlewareConfig = Partial<\n InferInteropZodInput<typeof contextSchema>\n>;\n\n/**\n * Middleware state schema to track the number of model calls made at the thread and run level.\n */\nconst stateSchema = z.object({\n threadModelCallCount: z.number().default(0),\n runModelCallCount: z.number().default(0),\n});\n\n/**\n * Error thrown when the model call limit is exceeded.\n *\n * @param threadLimit - The maximum number of model calls allowed per thread.\n * @param runLimit - The maximum number of model calls allowed per run.\n * @param threadCount - The number of model calls made at the thread level.\n * @param runCount - The number of model calls made at the run level.\n */\nclass ModelCallLimitMiddlewareError extends Error {\n constructor({\n threadLimit,\n runLimit,\n threadCount,\n runCount,\n }: {\n threadLimit?: number;\n runLimit?: number;\n threadCount?: number;\n runCount?: number;\n }) {\n const exceededHint: string[] = [];\n if (typeof threadLimit === \"number\" && typeof threadCount === \"number\") {\n exceededHint.push(\n `thread level call limit reached with ${threadCount} model calls`\n );\n }\n if (typeof runLimit === \"number\" && typeof runCount === \"number\") {\n exceededHint.push(\n `run level call limit reached with ${runCount} model calls`\n );\n }\n super(\n `Model call limits exceeded${\n exceededHint.length > 0 ? `: ${exceededHint.join(\", \")}` : \"\"\n }`\n );\n this.name = \"ModelCallLimitMiddlewareError\";\n }\n}\n\n/**\n * Creates a middleware to limit the number of model calls at both thread and run levels.\n *\n * This middleware helps prevent excessive model API calls by enforcing limits on how many\n * times the model can be invoked. It supports two types of limits:\n *\n * - **Thread-level limit**: Restricts the total number of model calls across an entire conversation thread\n * - **Run-level limit**: Restricts the number of model calls within a single agent run/invocation\n *\n * ## How It Works\n *\n * The middleware intercepts model requests before they are sent and checks the current call counts\n * against the configured limits. If either limit is exceeded, it throws a `ModelCallLimitMiddlewareError`\n * to stop execution and prevent further API calls.\n *\n * ## Use Cases\n *\n * - **Cost Control**: Prevent runaway costs from excessive model calls in production\n * - **Testing**: Ensure agents don't make too many calls during development/testing\n * - **Safety**: Limit potential infinite loops or recursive agent behaviors\n * - **Rate Limiting**: Enforce organizational policies on model usage per conversation\n *\n * @param middlewareOptions - Configuration options for the call limits\n * @param middlewareOptions.threadLimit - Maximum number of model calls allowed per thread (optional)\n * @param middlewareOptions.runLimit - Maximum number of model calls allowed per run (optional)\n *\n * @returns A middleware instance that can be passed to `createAgent`\n *\n * @throws {ModelCallLimitMiddlewareError} When either the thread or run limit is exceeded\n *\n * @example\n * ```typescript\n * import { createAgent, modelCallLimitMiddleware } from \"langchain\";\n *\n * // Limit to 10 calls per thread and 3 calls per run\n * const agent = createAgent({\n * model: \"openai:gpt-4o-mini\",\n * tools: [myTool],\n * middleware: [\n * modelCallLimitMiddleware({\n * threadLimit: 10,\n * runLimit: 3\n * })\n * ]\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Limits can also be configured at runtime via context\n * const result = await agent.invoke(\n * { messages: [\"Hello\"] },\n * {\n * configurable: {\n * threadLimit: 5 // Override the default limit for this run\n * }\n * }\n * );\n * ```\n */\nexport function modelCallLimitMiddleware(\n middlewareOptions?: ModelCallLimitMiddlewareConfig\n) {\n return createMiddleware({\n name: \"ModelCallLimitMiddleware\",\n contextSchema,\n stateSchema,\n beforeModel: {\n canJumpTo: [\"end\"],\n hook: (state, runtime) => {\n let exitBehavior =\n runtime.context.exitBehavior ??\n middlewareOptions?.exitBehavior ??\n DEFAULT_EXIT_BEHAVIOR;\n\n // @ts-expect-error - throw is deprecated\n if (exitBehavior === \"throw\") {\n console.warn(\n \"The 'throw' exit behavior is deprecated. Please use 'error' instead.\"\n );\n exitBehavior = \"error\";\n }\n\n const threadLimit =\n runtime.context.threadLimit ?? middlewareOptions?.threadLimit;\n const runLimit =\n runtime.context.runLimit ?? middlewareOptions?.runLimit;\n\n const threadCount = state.threadModelCallCount;\n const runCount = state.runModelCallCount;\n if (typeof threadLimit === \"number\" && threadLimit <= threadCount) {\n const error = new ModelCallLimitMiddlewareError({\n threadLimit,\n threadCount,\n });\n if (exitBehavior === \"end\") {\n return {\n jumpTo: \"end\",\n messages: [new AIMessage(error.message)],\n };\n }\n\n throw error;\n }\n if (typeof runLimit === \"number\" && runLimit <= runCount) {\n const error = new ModelCallLimitMiddlewareError({\n runLimit,\n runCount,\n });\n if (exitBehavior === \"end\") {\n return {\n jumpTo: \"end\",\n messages: [new AIMessage(error.message)],\n };\n }\n\n throw error;\n }\n\n return state;\n },\n },\n afterModel: (state) => ({\n runModelCallCount: state.runModelCallCount + 1,\n threadModelCallCount: state.threadModelCallCount + 1,\n }),\n afterAgent: () => ({\n runModelCallCount: 0,\n }),\n });\n}\n"],"mappings":";;;;;AAMA,MAAM,wBAAwB;AAE9B,MAAM,gBAAgBA,OAAAA,EAAE,OAAO;;;;CAI7B,aAAaA,OAAAA,EAAE,QAAQ,CAAC,UAAU;;;;CAIlC,UAAUA,OAAAA,EAAE,QAAQ,CAAC,UAAU;;;;;;;CAO/B,cAAcA,OAAAA,EAAE,KAAK,CAAC,SAAS,MAAM,CAAC,CAAC,UAAU;CAClD,CAAC;;;;AAQF,MAAM,cAAcA,OAAAA,EAAE,OAAO;CAC3B,sBAAsBA,OAAAA,EAAE,QAAQ,CAAC,QAAQ,EAAE;CAC3C,mBAAmBA,OAAAA,EAAE,QAAQ,CAAC,QAAQ,EAAE;CACzC,CAAC;;;;;;;;;AAUF,IAAM,gCAAN,cAA4C,MAAM;CAChD,YAAY,EACV,aACA,UACA,aACA,YAMC;EACD,MAAM,eAAyB,EAAE;AACjC,MAAI,OAAO,gBAAgB,YAAY,OAAO,gBAAgB,SAC5D,cAAa,KACX,wCAAwC,YAAY,cACrD;AAEH,MAAI,OAAO,aAAa,YAAY,OAAO,aAAa,SACtD,cAAa,KACX,qCAAqC,SAAS,cAC/C;AAEH,QACE,6BACE,aAAa,SAAS,IAAI,KAAK,aAAa,KAAK,KAAK,KAAK,KAE9D;AACD,OAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgEhB,SAAgB,yBACd,mBACA;AACA,QAAOC,mBAAAA,iBAAiB;EACtB,MAAM;EACN;EACA;EACA,aAAa;GACX,WAAW,CAAC,MAAM;GAClB,OAAO,OAAO,YAAY;IACxB,IAAI,eACF,QAAQ,QAAQ,gBAChB,mBAAmB,gBACnB;AAGF,QAAI,iBAAiB,SAAS;AAC5B,aAAQ,KACN,uEACD;AACD,oBAAe;;IAGjB,MAAM,cACJ,QAAQ,QAAQ,eAAe,mBAAmB;IACpD,MAAM,WACJ,QAAQ,QAAQ,YAAY,mBAAmB;IAEjD,MAAM,cAAc,MAAM;IAC1B,MAAM,WAAW,MAAM;AACvB,QAAI,OAAO,gBAAgB,YAAY,eAAe,aAAa;KACjE,MAAM,QAAQ,IAAI,8BAA8B;MAC9C;MACA;MACD,CAAC;AACF,SAAI,iBAAiB,MACnB,QAAO;MACL,QAAQ;MACR,UAAU,CAAC,IAAIC,yBAAAA,UAAU,MAAM,QAAQ,CAAC;MACzC;AAGH,WAAM;;AAER,QAAI,OAAO,aAAa,YAAY,YAAY,UAAU;KACxD,MAAM,QAAQ,IAAI,8BAA8B;MAC9C;MACA;MACD,CAAC;AACF,SAAI,iBAAiB,MACnB,QAAO;MACL,QAAQ;MACR,UAAU,CAAC,IAAIA,yBAAAA,UAAU,MAAM,QAAQ,CAAC;MACzC;AAGH,WAAM;;AAGR,WAAO;;GAEV;EACD,aAAa,WAAW;GACtB,mBAAmB,MAAM,oBAAoB;GAC7C,sBAAsB,MAAM,uBAAuB;GACpD;EACD,mBAAmB,EACjB,mBAAmB,GACpB;EACF,CAAC"}
1
+ {"version":3,"file":"modelCallLimit.cjs","names":["z","createMiddleware","AIMessage"],"sources":["../../../src/agents/middleware/modelCallLimit.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { AIMessage } from \"@langchain/core/messages\";\nimport { InferInteropZodInput } from \"@langchain/core/utils/types\";\n\nimport { createMiddleware } from \"../middleware.js\";\n\nconst DEFAULT_EXIT_BEHAVIOR = \"end\";\n\nconst contextSchema = z.object({\n /**\n * The maximum number of model calls allowed per thread.\n */\n threadLimit: z.number().optional(),\n /**\n * The maximum number of model calls allowed per run.\n */\n runLimit: z.number().optional(),\n /**\n * The behavior to take when the limit is exceeded.\n * - \"error\" will throw an error and stop the agent.\n * - \"end\" will end the agent.\n * @default \"end\"\n */\n exitBehavior: z.enum([\"error\", \"end\"]).optional(),\n});\nexport type ModelCallLimitMiddlewareConfig = Partial<\n InferInteropZodInput<typeof contextSchema>\n>;\n\n/**\n * Middleware state schema to track the number of model calls made at the thread and run level.\n */\nconst stateSchema = z.object({\n threadModelCallCount: z.number().default(0),\n runModelCallCount: z.number().default(0),\n});\n\n/**\n * Error thrown when the model call limit is exceeded.\n *\n * @param threadLimit - The maximum number of model calls allowed per thread.\n * @param runLimit - The maximum number of model calls allowed per run.\n * @param threadCount - The number of model calls made at the thread level.\n * @param runCount - The number of model calls made at the run level.\n */\nclass ModelCallLimitMiddlewareError extends Error {\n constructor({\n threadLimit,\n runLimit,\n threadCount,\n runCount,\n }: {\n threadLimit?: number;\n runLimit?: number;\n threadCount?: number;\n runCount?: number;\n }) {\n const exceededHint: string[] = [];\n if (typeof threadLimit === \"number\" && typeof threadCount === \"number\") {\n exceededHint.push(\n `thread level call limit reached with ${threadCount} model calls`\n );\n }\n if (typeof runLimit === \"number\" && typeof runCount === \"number\") {\n exceededHint.push(\n `run level call limit reached with ${runCount} model calls`\n );\n }\n super(\n `Model call limits exceeded${\n exceededHint.length > 0 ? `: ${exceededHint.join(\", \")}` : \"\"\n }`\n );\n this.name = \"ModelCallLimitMiddlewareError\";\n }\n}\n\n/**\n * Creates a middleware to limit the number of model calls at both thread and run levels.\n *\n * This middleware helps prevent excessive model API calls by enforcing limits on how many\n * times the model can be invoked. It supports two types of limits:\n *\n * - **Thread-level limit**: Restricts the total number of model calls across an entire conversation thread\n * - **Run-level limit**: Restricts the number of model calls within a single agent run/invocation\n *\n * ## How It Works\n *\n * The middleware intercepts model requests before they are sent and checks the current call counts\n * against the configured limits. If either limit is exceeded, it throws a `ModelCallLimitMiddlewareError`\n * to stop execution and prevent further API calls.\n *\n * ## Use Cases\n *\n * - **Cost Control**: Prevent runaway costs from excessive model calls in production\n * - **Testing**: Ensure agents don't make too many calls during development/testing\n * - **Safety**: Limit potential infinite loops or recursive agent behaviors\n * - **Rate Limiting**: Enforce organizational policies on model usage per conversation\n *\n * @param middlewareOptions - Configuration options for the call limits\n * @param middlewareOptions.threadLimit - Maximum number of model calls allowed per thread (optional)\n * @param middlewareOptions.runLimit - Maximum number of model calls allowed per run (optional)\n *\n * @returns A middleware instance that can be passed to `createAgent`\n *\n * @throws {ModelCallLimitMiddlewareError} When either the thread or run limit is exceeded\n *\n * @example\n * ```typescript\n * import { createAgent, modelCallLimitMiddleware } from \"langchain\";\n *\n * // Limit to 10 calls per thread and 3 calls per run\n * const agent = createAgent({\n * model: \"openai:gpt-4o-mini\",\n * tools: [myTool],\n * middleware: [\n * modelCallLimitMiddleware({\n * threadLimit: 10,\n * runLimit: 3\n * })\n * ]\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Limits can also be configured at runtime via context\n * const result = await agent.invoke(\n * { messages: [\"Hello\"] },\n * {\n * configurable: {\n * threadLimit: 5 // Override the default limit for this run\n * }\n * }\n * );\n * ```\n */\nexport function modelCallLimitMiddleware(\n middlewareOptions?: ModelCallLimitMiddlewareConfig\n) {\n return createMiddleware({\n name: \"ModelCallLimitMiddleware\",\n contextSchema,\n stateSchema,\n beforeModel: {\n canJumpTo: [\"end\"],\n hook: (state, runtime) => {\n let exitBehavior =\n runtime.context.exitBehavior ??\n middlewareOptions?.exitBehavior ??\n DEFAULT_EXIT_BEHAVIOR;\n\n // @ts-expect-error - throw is deprecated\n if (exitBehavior === \"throw\") {\n console.warn(\n \"The 'throw' exit behavior is deprecated. Please use 'error' instead.\"\n );\n exitBehavior = \"error\";\n }\n\n const threadLimit =\n runtime.context.threadLimit ?? middlewareOptions?.threadLimit;\n const runLimit =\n runtime.context.runLimit ?? middlewareOptions?.runLimit;\n\n const threadCount = state.threadModelCallCount;\n const runCount = state.runModelCallCount;\n if (typeof threadLimit === \"number\" && threadLimit <= threadCount) {\n const error = new ModelCallLimitMiddlewareError({\n threadLimit,\n threadCount,\n });\n if (exitBehavior === \"end\") {\n return {\n jumpTo: \"end\",\n messages: [new AIMessage(error.message)],\n };\n }\n\n throw error;\n }\n if (typeof runLimit === \"number\" && runLimit <= runCount) {\n const error = new ModelCallLimitMiddlewareError({\n runLimit,\n runCount,\n });\n if (exitBehavior === \"end\") {\n return {\n jumpTo: \"end\",\n messages: [new AIMessage(error.message)],\n };\n }\n\n throw error;\n }\n\n return state;\n },\n },\n afterModel: (state) => ({\n runModelCallCount: state.runModelCallCount + 1,\n threadModelCallCount: state.threadModelCallCount + 1,\n }),\n afterAgent: () => ({\n runModelCallCount: 0,\n }),\n });\n}\n"],"mappings":";;;;AAMA,MAAM,wBAAwB;AAE9B,MAAM,gBAAgBA,OAAAA,EAAE,OAAO;;;;CAI7B,aAAaA,OAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;;;;CAIjC,UAAUA,OAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;;;;;;;CAO9B,cAAcA,OAAAA,EAAE,KAAK,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,SAAS;AAClD,CAAC;;;;AAQD,MAAM,cAAcA,OAAAA,EAAE,OAAO;CAC3B,sBAAsBA,OAAAA,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC;CAC1C,mBAAmBA,OAAAA,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC;AACzC,CAAC;;;;;;;;;AAUD,IAAM,gCAAN,cAA4C,MAAM;CAChD,YAAY,EACV,aACA,UACA,aACA,YAMC;EACD,MAAM,eAAyB,CAAC;EAChC,IAAI,OAAO,gBAAgB,YAAY,OAAO,gBAAgB,UAC5D,aAAa,KACX,wCAAwC,YAAY,aACtD;EAEF,IAAI,OAAO,aAAa,YAAY,OAAO,aAAa,UACtD,aAAa,KACX,qCAAqC,SAAS,aAChD;EAEF,MACE,6BACE,aAAa,SAAS,IAAI,KAAK,aAAa,KAAK,IAAI,MAAM,IAE/D;EACA,KAAK,OAAO;CACd;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DA,SAAgB,yBACd,mBACA;CACA,OAAOC,mBAAAA,iBAAiB;EACtB,MAAM;EACN;EACA;EACA,aAAa;GACX,WAAW,CAAC,KAAK;GACjB,OAAO,OAAO,YAAY;IACxB,IAAI,eACF,QAAQ,QAAQ,gBAChB,mBAAmB,gBACnB;IAGF,IAAI,iBAAiB,SAAS;KAC5B,QAAQ,KACN,sEACF;KACA,eAAe;IACjB;IAEA,MAAM,cACJ,QAAQ,QAAQ,eAAe,mBAAmB;IACpD,MAAM,WACJ,QAAQ,QAAQ,YAAY,mBAAmB;IAEjD,MAAM,cAAc,MAAM;IAC1B,MAAM,WAAW,MAAM;IACvB,IAAI,OAAO,gBAAgB,YAAY,eAAe,aAAa;KACjE,MAAM,QAAQ,IAAI,8BAA8B;MAC9C;MACA;KACF,CAAC;KACD,IAAI,iBAAiB,OACnB,OAAO;MACL,QAAQ;MACR,UAAU,CAAC,IAAIC,yBAAAA,UAAU,MAAM,OAAO,CAAC;KACzC;KAGF,MAAM;IACR;IACA,IAAI,OAAO,aAAa,YAAY,YAAY,UAAU;KACxD,MAAM,QAAQ,IAAI,8BAA8B;MAC9C;MACA;KACF,CAAC;KACD,IAAI,iBAAiB,OACnB,OAAO;MACL,QAAQ;MACR,UAAU,CAAC,IAAIA,yBAAAA,UAAU,MAAM,OAAO,CAAC;KACzC;KAGF,MAAM;IACR;IAEA,OAAO;GACT;EACF;EACA,aAAa,WAAW;GACtB,mBAAmB,MAAM,oBAAoB;GAC7C,sBAAsB,MAAM,uBAAuB;EACrD;EACA,mBAAmB,EACjB,mBAAmB,EACrB;CACF,CAAC;AACH"}
@@ -1,8 +1,6 @@
1
1
  import { AgentMiddleware } from "./types.cjs";
2
- import * as _$_langchain_core_tools0 from "@langchain/core/tools";
3
2
  import { InferInteropZodInput } from "@langchain/core/utils/types";
4
3
  import { z } from "zod/v3";
5
-
6
4
  //#region src/agents/middleware/modelCallLimit.d.ts
7
5
  declare const contextSchema: z.ZodObject<{
8
6
  /**
@@ -127,7 +125,7 @@ declare function modelCallLimitMiddleware(middlewareOptions?: ModelCallLimitMidd
127
125
  threadLimit?: number | undefined;
128
126
  runLimit?: number | undefined;
129
127
  exitBehavior?: "end" | "error" | undefined;
130
- }, readonly (_$_langchain_core_tools0.ServerTool | _$_langchain_core_tools0.ClientTool)[], readonly []>;
128
+ }, readonly (import("@langchain/core/tools").ServerTool | import("@langchain/core/tools").ClientTool)[], readonly []>;
131
129
  //#endregion
132
130
  export { ModelCallLimitMiddlewareConfig, modelCallLimitMiddleware };
133
131
  //# sourceMappingURL=modelCallLimit.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"modelCallLimit.d.cts","names":[],"sources":["../../../src/agents/middleware/modelCallLimit.ts"],"mappings":";;;;;;cAQM,aAAA,EAAa,CAAA,CAAA,SAAA;;;;;EAgBjB;;;;;;;;;;;;;;;;;;;;KACU,8BAAA,GAAiC,OAAA,CAC3C,oBAAA,QAA4B,aAAA;;;;;;;;;;;;;;;;;;;AAD9B;;;;;;;;;;;;;AAgHA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,wBAAA,CACd,iBAAA,GAAoB,8BAAA,mBAA8B,CAAA,CAAA,SAAA"}
1
+ {"version":3,"file":"modelCallLimit.d.cts","names":[],"sources":["../../../src/agents/middleware/modelCallLimit.ts"],"mappings":";;;;cAQM,eAAa,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;KAiBP,iCAAiC,QAC3C,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+Gd,yBACd,oBAAoB,iDAA8B,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6CAqEnD,6CAAA"}
@@ -1,8 +1,6 @@
1
1
  import { AgentMiddleware } from "./types.js";
2
- import * as _$_langchain_core_tools0 from "@langchain/core/tools";
3
2
  import { InferInteropZodInput } from "@langchain/core/utils/types";
4
3
  import { z } from "zod/v3";
5
-
6
4
  //#region src/agents/middleware/modelCallLimit.d.ts
7
5
  declare const contextSchema: z.ZodObject<{
8
6
  /**
@@ -127,7 +125,7 @@ declare function modelCallLimitMiddleware(middlewareOptions?: ModelCallLimitMidd
127
125
  threadLimit?: number | undefined;
128
126
  runLimit?: number | undefined;
129
127
  exitBehavior?: "end" | "error" | undefined;
130
- }, readonly (_$_langchain_core_tools0.ServerTool | _$_langchain_core_tools0.ClientTool)[], readonly []>;
128
+ }, readonly (import("@langchain/core/tools").ServerTool | import("@langchain/core/tools").ClientTool)[], readonly []>;
131
129
  //#endregion
132
130
  export { ModelCallLimitMiddlewareConfig, modelCallLimitMiddleware };
133
131
  //# sourceMappingURL=modelCallLimit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"modelCallLimit.d.ts","names":[],"sources":["../../../src/agents/middleware/modelCallLimit.ts"],"mappings":";;;;;;cAQM,aAAA,EAAa,CAAA,CAAA,SAAA;;;;;EAgBjB;;;;;;;;;;;;;;;;;;;;KACU,8BAAA,GAAiC,OAAA,CAC3C,oBAAA,QAA4B,aAAA;;;;;;;;;;;;;;;;;;;AAD9B;;;;;;;;;;;;;AAgHA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,wBAAA,CACd,iBAAA,GAAoB,8BAAA,mBAA8B,CAAA,CAAA,SAAA"}
1
+ {"version":3,"file":"modelCallLimit.d.ts","names":[],"sources":["../../../src/agents/middleware/modelCallLimit.ts"],"mappings":";;;;cAQM,eAAa,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;KAiBP,iCAAiC,QAC3C,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+Gd,yBACd,oBAAoB,iDAA8B,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6CAqEnD,6CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"modelCallLimit.js","names":[],"sources":["../../../src/agents/middleware/modelCallLimit.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { AIMessage } from \"@langchain/core/messages\";\nimport { InferInteropZodInput } from \"@langchain/core/utils/types\";\n\nimport { createMiddleware } from \"../middleware.js\";\n\nconst DEFAULT_EXIT_BEHAVIOR = \"end\";\n\nconst contextSchema = z.object({\n /**\n * The maximum number of model calls allowed per thread.\n */\n threadLimit: z.number().optional(),\n /**\n * The maximum number of model calls allowed per run.\n */\n runLimit: z.number().optional(),\n /**\n * The behavior to take when the limit is exceeded.\n * - \"error\" will throw an error and stop the agent.\n * - \"end\" will end the agent.\n * @default \"end\"\n */\n exitBehavior: z.enum([\"error\", \"end\"]).optional(),\n});\nexport type ModelCallLimitMiddlewareConfig = Partial<\n InferInteropZodInput<typeof contextSchema>\n>;\n\n/**\n * Middleware state schema to track the number of model calls made at the thread and run level.\n */\nconst stateSchema = z.object({\n threadModelCallCount: z.number().default(0),\n runModelCallCount: z.number().default(0),\n});\n\n/**\n * Error thrown when the model call limit is exceeded.\n *\n * @param threadLimit - The maximum number of model calls allowed per thread.\n * @param runLimit - The maximum number of model calls allowed per run.\n * @param threadCount - The number of model calls made at the thread level.\n * @param runCount - The number of model calls made at the run level.\n */\nclass ModelCallLimitMiddlewareError extends Error {\n constructor({\n threadLimit,\n runLimit,\n threadCount,\n runCount,\n }: {\n threadLimit?: number;\n runLimit?: number;\n threadCount?: number;\n runCount?: number;\n }) {\n const exceededHint: string[] = [];\n if (typeof threadLimit === \"number\" && typeof threadCount === \"number\") {\n exceededHint.push(\n `thread level call limit reached with ${threadCount} model calls`\n );\n }\n if (typeof runLimit === \"number\" && typeof runCount === \"number\") {\n exceededHint.push(\n `run level call limit reached with ${runCount} model calls`\n );\n }\n super(\n `Model call limits exceeded${\n exceededHint.length > 0 ? `: ${exceededHint.join(\", \")}` : \"\"\n }`\n );\n this.name = \"ModelCallLimitMiddlewareError\";\n }\n}\n\n/**\n * Creates a middleware to limit the number of model calls at both thread and run levels.\n *\n * This middleware helps prevent excessive model API calls by enforcing limits on how many\n * times the model can be invoked. It supports two types of limits:\n *\n * - **Thread-level limit**: Restricts the total number of model calls across an entire conversation thread\n * - **Run-level limit**: Restricts the number of model calls within a single agent run/invocation\n *\n * ## How It Works\n *\n * The middleware intercepts model requests before they are sent and checks the current call counts\n * against the configured limits. If either limit is exceeded, it throws a `ModelCallLimitMiddlewareError`\n * to stop execution and prevent further API calls.\n *\n * ## Use Cases\n *\n * - **Cost Control**: Prevent runaway costs from excessive model calls in production\n * - **Testing**: Ensure agents don't make too many calls during development/testing\n * - **Safety**: Limit potential infinite loops or recursive agent behaviors\n * - **Rate Limiting**: Enforce organizational policies on model usage per conversation\n *\n * @param middlewareOptions - Configuration options for the call limits\n * @param middlewareOptions.threadLimit - Maximum number of model calls allowed per thread (optional)\n * @param middlewareOptions.runLimit - Maximum number of model calls allowed per run (optional)\n *\n * @returns A middleware instance that can be passed to `createAgent`\n *\n * @throws {ModelCallLimitMiddlewareError} When either the thread or run limit is exceeded\n *\n * @example\n * ```typescript\n * import { createAgent, modelCallLimitMiddleware } from \"langchain\";\n *\n * // Limit to 10 calls per thread and 3 calls per run\n * const agent = createAgent({\n * model: \"openai:gpt-4o-mini\",\n * tools: [myTool],\n * middleware: [\n * modelCallLimitMiddleware({\n * threadLimit: 10,\n * runLimit: 3\n * })\n * ]\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Limits can also be configured at runtime via context\n * const result = await agent.invoke(\n * { messages: [\"Hello\"] },\n * {\n * configurable: {\n * threadLimit: 5 // Override the default limit for this run\n * }\n * }\n * );\n * ```\n */\nexport function modelCallLimitMiddleware(\n middlewareOptions?: ModelCallLimitMiddlewareConfig\n) {\n return createMiddleware({\n name: \"ModelCallLimitMiddleware\",\n contextSchema,\n stateSchema,\n beforeModel: {\n canJumpTo: [\"end\"],\n hook: (state, runtime) => {\n let exitBehavior =\n runtime.context.exitBehavior ??\n middlewareOptions?.exitBehavior ??\n DEFAULT_EXIT_BEHAVIOR;\n\n // @ts-expect-error - throw is deprecated\n if (exitBehavior === \"throw\") {\n console.warn(\n \"The 'throw' exit behavior is deprecated. Please use 'error' instead.\"\n );\n exitBehavior = \"error\";\n }\n\n const threadLimit =\n runtime.context.threadLimit ?? middlewareOptions?.threadLimit;\n const runLimit =\n runtime.context.runLimit ?? middlewareOptions?.runLimit;\n\n const threadCount = state.threadModelCallCount;\n const runCount = state.runModelCallCount;\n if (typeof threadLimit === \"number\" && threadLimit <= threadCount) {\n const error = new ModelCallLimitMiddlewareError({\n threadLimit,\n threadCount,\n });\n if (exitBehavior === \"end\") {\n return {\n jumpTo: \"end\",\n messages: [new AIMessage(error.message)],\n };\n }\n\n throw error;\n }\n if (typeof runLimit === \"number\" && runLimit <= runCount) {\n const error = new ModelCallLimitMiddlewareError({\n runLimit,\n runCount,\n });\n if (exitBehavior === \"end\") {\n return {\n jumpTo: \"end\",\n messages: [new AIMessage(error.message)],\n };\n }\n\n throw error;\n }\n\n return state;\n },\n },\n afterModel: (state) => ({\n runModelCallCount: state.runModelCallCount + 1,\n threadModelCallCount: state.threadModelCallCount + 1,\n }),\n afterAgent: () => ({\n runModelCallCount: 0,\n }),\n });\n}\n"],"mappings":";;;;AAMA,MAAM,wBAAwB;AAE9B,MAAM,gBAAgB,EAAE,OAAO;;;;CAI7B,aAAa,EAAE,QAAQ,CAAC,UAAU;;;;CAIlC,UAAU,EAAE,QAAQ,CAAC,UAAU;;;;;;;CAO/B,cAAc,EAAE,KAAK,CAAC,SAAS,MAAM,CAAC,CAAC,UAAU;CAClD,CAAC;;;;AAQF,MAAM,cAAc,EAAE,OAAO;CAC3B,sBAAsB,EAAE,QAAQ,CAAC,QAAQ,EAAE;CAC3C,mBAAmB,EAAE,QAAQ,CAAC,QAAQ,EAAE;CACzC,CAAC;;;;;;;;;AAUF,IAAM,gCAAN,cAA4C,MAAM;CAChD,YAAY,EACV,aACA,UACA,aACA,YAMC;EACD,MAAM,eAAyB,EAAE;AACjC,MAAI,OAAO,gBAAgB,YAAY,OAAO,gBAAgB,SAC5D,cAAa,KACX,wCAAwC,YAAY,cACrD;AAEH,MAAI,OAAO,aAAa,YAAY,OAAO,aAAa,SACtD,cAAa,KACX,qCAAqC,SAAS,cAC/C;AAEH,QACE,6BACE,aAAa,SAAS,IAAI,KAAK,aAAa,KAAK,KAAK,KAAK,KAE9D;AACD,OAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgEhB,SAAgB,yBACd,mBACA;AACA,QAAO,iBAAiB;EACtB,MAAM;EACN;EACA;EACA,aAAa;GACX,WAAW,CAAC,MAAM;GAClB,OAAO,OAAO,YAAY;IACxB,IAAI,eACF,QAAQ,QAAQ,gBAChB,mBAAmB,gBACnB;AAGF,QAAI,iBAAiB,SAAS;AAC5B,aAAQ,KACN,uEACD;AACD,oBAAe;;IAGjB,MAAM,cACJ,QAAQ,QAAQ,eAAe,mBAAmB;IACpD,MAAM,WACJ,QAAQ,QAAQ,YAAY,mBAAmB;IAEjD,MAAM,cAAc,MAAM;IAC1B,MAAM,WAAW,MAAM;AACvB,QAAI,OAAO,gBAAgB,YAAY,eAAe,aAAa;KACjE,MAAM,QAAQ,IAAI,8BAA8B;MAC9C;MACA;MACD,CAAC;AACF,SAAI,iBAAiB,MACnB,QAAO;MACL,QAAQ;MACR,UAAU,CAAC,IAAI,UAAU,MAAM,QAAQ,CAAC;MACzC;AAGH,WAAM;;AAER,QAAI,OAAO,aAAa,YAAY,YAAY,UAAU;KACxD,MAAM,QAAQ,IAAI,8BAA8B;MAC9C;MACA;MACD,CAAC;AACF,SAAI,iBAAiB,MACnB,QAAO;MACL,QAAQ;MACR,UAAU,CAAC,IAAI,UAAU,MAAM,QAAQ,CAAC;MACzC;AAGH,WAAM;;AAGR,WAAO;;GAEV;EACD,aAAa,WAAW;GACtB,mBAAmB,MAAM,oBAAoB;GAC7C,sBAAsB,MAAM,uBAAuB;GACpD;EACD,mBAAmB,EACjB,mBAAmB,GACpB;EACF,CAAC"}
1
+ {"version":3,"file":"modelCallLimit.js","names":[],"sources":["../../../src/agents/middleware/modelCallLimit.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport { AIMessage } from \"@langchain/core/messages\";\nimport { InferInteropZodInput } from \"@langchain/core/utils/types\";\n\nimport { createMiddleware } from \"../middleware.js\";\n\nconst DEFAULT_EXIT_BEHAVIOR = \"end\";\n\nconst contextSchema = z.object({\n /**\n * The maximum number of model calls allowed per thread.\n */\n threadLimit: z.number().optional(),\n /**\n * The maximum number of model calls allowed per run.\n */\n runLimit: z.number().optional(),\n /**\n * The behavior to take when the limit is exceeded.\n * - \"error\" will throw an error and stop the agent.\n * - \"end\" will end the agent.\n * @default \"end\"\n */\n exitBehavior: z.enum([\"error\", \"end\"]).optional(),\n});\nexport type ModelCallLimitMiddlewareConfig = Partial<\n InferInteropZodInput<typeof contextSchema>\n>;\n\n/**\n * Middleware state schema to track the number of model calls made at the thread and run level.\n */\nconst stateSchema = z.object({\n threadModelCallCount: z.number().default(0),\n runModelCallCount: z.number().default(0),\n});\n\n/**\n * Error thrown when the model call limit is exceeded.\n *\n * @param threadLimit - The maximum number of model calls allowed per thread.\n * @param runLimit - The maximum number of model calls allowed per run.\n * @param threadCount - The number of model calls made at the thread level.\n * @param runCount - The number of model calls made at the run level.\n */\nclass ModelCallLimitMiddlewareError extends Error {\n constructor({\n threadLimit,\n runLimit,\n threadCount,\n runCount,\n }: {\n threadLimit?: number;\n runLimit?: number;\n threadCount?: number;\n runCount?: number;\n }) {\n const exceededHint: string[] = [];\n if (typeof threadLimit === \"number\" && typeof threadCount === \"number\") {\n exceededHint.push(\n `thread level call limit reached with ${threadCount} model calls`\n );\n }\n if (typeof runLimit === \"number\" && typeof runCount === \"number\") {\n exceededHint.push(\n `run level call limit reached with ${runCount} model calls`\n );\n }\n super(\n `Model call limits exceeded${\n exceededHint.length > 0 ? `: ${exceededHint.join(\", \")}` : \"\"\n }`\n );\n this.name = \"ModelCallLimitMiddlewareError\";\n }\n}\n\n/**\n * Creates a middleware to limit the number of model calls at both thread and run levels.\n *\n * This middleware helps prevent excessive model API calls by enforcing limits on how many\n * times the model can be invoked. It supports two types of limits:\n *\n * - **Thread-level limit**: Restricts the total number of model calls across an entire conversation thread\n * - **Run-level limit**: Restricts the number of model calls within a single agent run/invocation\n *\n * ## How It Works\n *\n * The middleware intercepts model requests before they are sent and checks the current call counts\n * against the configured limits. If either limit is exceeded, it throws a `ModelCallLimitMiddlewareError`\n * to stop execution and prevent further API calls.\n *\n * ## Use Cases\n *\n * - **Cost Control**: Prevent runaway costs from excessive model calls in production\n * - **Testing**: Ensure agents don't make too many calls during development/testing\n * - **Safety**: Limit potential infinite loops or recursive agent behaviors\n * - **Rate Limiting**: Enforce organizational policies on model usage per conversation\n *\n * @param middlewareOptions - Configuration options for the call limits\n * @param middlewareOptions.threadLimit - Maximum number of model calls allowed per thread (optional)\n * @param middlewareOptions.runLimit - Maximum number of model calls allowed per run (optional)\n *\n * @returns A middleware instance that can be passed to `createAgent`\n *\n * @throws {ModelCallLimitMiddlewareError} When either the thread or run limit is exceeded\n *\n * @example\n * ```typescript\n * import { createAgent, modelCallLimitMiddleware } from \"langchain\";\n *\n * // Limit to 10 calls per thread and 3 calls per run\n * const agent = createAgent({\n * model: \"openai:gpt-4o-mini\",\n * tools: [myTool],\n * middleware: [\n * modelCallLimitMiddleware({\n * threadLimit: 10,\n * runLimit: 3\n * })\n * ]\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Limits can also be configured at runtime via context\n * const result = await agent.invoke(\n * { messages: [\"Hello\"] },\n * {\n * configurable: {\n * threadLimit: 5 // Override the default limit for this run\n * }\n * }\n * );\n * ```\n */\nexport function modelCallLimitMiddleware(\n middlewareOptions?: ModelCallLimitMiddlewareConfig\n) {\n return createMiddleware({\n name: \"ModelCallLimitMiddleware\",\n contextSchema,\n stateSchema,\n beforeModel: {\n canJumpTo: [\"end\"],\n hook: (state, runtime) => {\n let exitBehavior =\n runtime.context.exitBehavior ??\n middlewareOptions?.exitBehavior ??\n DEFAULT_EXIT_BEHAVIOR;\n\n // @ts-expect-error - throw is deprecated\n if (exitBehavior === \"throw\") {\n console.warn(\n \"The 'throw' exit behavior is deprecated. Please use 'error' instead.\"\n );\n exitBehavior = \"error\";\n }\n\n const threadLimit =\n runtime.context.threadLimit ?? middlewareOptions?.threadLimit;\n const runLimit =\n runtime.context.runLimit ?? middlewareOptions?.runLimit;\n\n const threadCount = state.threadModelCallCount;\n const runCount = state.runModelCallCount;\n if (typeof threadLimit === \"number\" && threadLimit <= threadCount) {\n const error = new ModelCallLimitMiddlewareError({\n threadLimit,\n threadCount,\n });\n if (exitBehavior === \"end\") {\n return {\n jumpTo: \"end\",\n messages: [new AIMessage(error.message)],\n };\n }\n\n throw error;\n }\n if (typeof runLimit === \"number\" && runLimit <= runCount) {\n const error = new ModelCallLimitMiddlewareError({\n runLimit,\n runCount,\n });\n if (exitBehavior === \"end\") {\n return {\n jumpTo: \"end\",\n messages: [new AIMessage(error.message)],\n };\n }\n\n throw error;\n }\n\n return state;\n },\n },\n afterModel: (state) => ({\n runModelCallCount: state.runModelCallCount + 1,\n threadModelCallCount: state.threadModelCallCount + 1,\n }),\n afterAgent: () => ({\n runModelCallCount: 0,\n }),\n });\n}\n"],"mappings":";;;;AAMA,MAAM,wBAAwB;AAE9B,MAAM,gBAAgB,EAAE,OAAO;;;;CAI7B,aAAa,EAAE,OAAO,CAAC,CAAC,SAAS;;;;CAIjC,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;;;;;;;CAO9B,cAAc,EAAE,KAAK,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,SAAS;AAClD,CAAC;;;;AAQD,MAAM,cAAc,EAAE,OAAO;CAC3B,sBAAsB,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC;CAC1C,mBAAmB,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC;AACzC,CAAC;;;;;;;;;AAUD,IAAM,gCAAN,cAA4C,MAAM;CAChD,YAAY,EACV,aACA,UACA,aACA,YAMC;EACD,MAAM,eAAyB,CAAC;EAChC,IAAI,OAAO,gBAAgB,YAAY,OAAO,gBAAgB,UAC5D,aAAa,KACX,wCAAwC,YAAY,aACtD;EAEF,IAAI,OAAO,aAAa,YAAY,OAAO,aAAa,UACtD,aAAa,KACX,qCAAqC,SAAS,aAChD;EAEF,MACE,6BACE,aAAa,SAAS,IAAI,KAAK,aAAa,KAAK,IAAI,MAAM,IAE/D;EACA,KAAK,OAAO;CACd;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DA,SAAgB,yBACd,mBACA;CACA,OAAO,iBAAiB;EACtB,MAAM;EACN;EACA;EACA,aAAa;GACX,WAAW,CAAC,KAAK;GACjB,OAAO,OAAO,YAAY;IACxB,IAAI,eACF,QAAQ,QAAQ,gBAChB,mBAAmB,gBACnB;IAGF,IAAI,iBAAiB,SAAS;KAC5B,QAAQ,KACN,sEACF;KACA,eAAe;IACjB;IAEA,MAAM,cACJ,QAAQ,QAAQ,eAAe,mBAAmB;IACpD,MAAM,WACJ,QAAQ,QAAQ,YAAY,mBAAmB;IAEjD,MAAM,cAAc,MAAM;IAC1B,MAAM,WAAW,MAAM;IACvB,IAAI,OAAO,gBAAgB,YAAY,eAAe,aAAa;KACjE,MAAM,QAAQ,IAAI,8BAA8B;MAC9C;MACA;KACF,CAAC;KACD,IAAI,iBAAiB,OACnB,OAAO;MACL,QAAQ;MACR,UAAU,CAAC,IAAI,UAAU,MAAM,OAAO,CAAC;KACzC;KAGF,MAAM;IACR;IACA,IAAI,OAAO,aAAa,YAAY,YAAY,UAAU;KACxD,MAAM,QAAQ,IAAI,8BAA8B;MAC9C;MACA;KACF,CAAC;KACD,IAAI,iBAAiB,OACnB,OAAO;MACL,QAAQ;MACR,UAAU,CAAC,IAAI,UAAU,MAAM,OAAO,CAAC;KACzC;KAGF,MAAM;IACR;IAEA,OAAO;GACT;EACF;EACA,aAAa,WAAW;GACtB,mBAAmB,MAAM,oBAAoB;GAC7C,sBAAsB,MAAM,uBAAuB;EACrD;EACA,mBAAmB,EACjB,mBAAmB,EACrB;CACF,CAAC;AACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"modelFallback.cjs","names":["createMiddleware","initChatModel"],"sources":["../../../src/agents/middleware/modelFallback.ts"],"sourcesContent":["import type { AgentLanguageModelLike as LanguageModelLike } from \"../model.js\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport { createMiddleware } from \"../middleware.js\";\n\n/**\n * Middleware that provides automatic model fallback on errors.\n *\n * This middleware attempts to retry failed model calls with alternative models\n * in sequence. When a model call fails, it tries the next model in the fallback\n * list until either a call succeeds or all models have been exhausted.\n *\n * @example\n * ```ts\n * import { createAgent, modelFallbackMiddleware } from \"langchain\";\n *\n * // Create middleware with fallback models (not including primary)\n * const fallback = modelFallbackMiddleware(\n * \"openai:gpt-4o-mini\", // First fallback\n * \"anthropic:claude-sonnet-4-5-20250929\", // Second fallback\n * );\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\", // Primary model\n * middleware: [fallback],\n * tools: [],\n * });\n *\n * // If gpt-4o fails, automatically tries gpt-4o-mini, then claude\n * const result = await agent.invoke({\n * messages: [{ role: \"user\", content: \"Hello\" }]\n * });\n * ```\n *\n * @param fallbackModels - The fallback models to try, in order.\n * @returns A middleware instance that handles model failures with fallbacks\n */\nexport function modelFallbackMiddleware(\n /**\n * The fallback models to try, in order.\n */\n ...fallbackModels: (string | LanguageModelLike)[]\n) {\n return createMiddleware({\n name: \"modelFallbackMiddleware\",\n wrapModelCall: async (request, handler) => {\n /**\n * Try the primary model first\n */\n try {\n return await handler(request);\n } catch (error) {\n /**\n * If primary model fails, try fallback models in sequence\n */\n for (let i = 0; i < fallbackModels.length; i++) {\n try {\n const fallbackModel = fallbackModels[i];\n const model =\n typeof fallbackModel === \"string\"\n ? await initChatModel(fallbackModel)\n : fallbackModel;\n\n return await handler({\n ...request,\n model,\n });\n } catch (fallbackError) {\n /**\n * If this is the last fallback, throw the error\n */\n if (i === fallbackModels.length - 1) {\n throw fallbackError;\n }\n // Otherwise, continue to next fallback\n }\n }\n /**\n * If no fallbacks were provided, re-throw the original error\n */\n throw error;\n }\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,SAAgB,wBAId,GAAG,gBACH;AACA,QAAOA,mBAAAA,iBAAiB;EACtB,MAAM;EACN,eAAe,OAAO,SAAS,YAAY;;;;AAIzC,OAAI;AACF,WAAO,MAAM,QAAQ,QAAQ;YACtB,OAAO;;;;AAId,SAAK,IAAI,IAAI,GAAG,IAAI,eAAe,QAAQ,IACzC,KAAI;KACF,MAAM,gBAAgB,eAAe;KACrC,MAAM,QACJ,OAAO,kBAAkB,WACrB,MAAMC,8BAAAA,cAAc,cAAc,GAClC;AAEN,YAAO,MAAM,QAAQ;MACnB,GAAG;MACH;MACD,CAAC;aACK,eAAe;;;;AAItB,SAAI,MAAM,eAAe,SAAS,EAChC,OAAM;;;;;AAQZ,UAAM;;;EAGX,CAAC"}
1
+ {"version":3,"file":"modelFallback.cjs","names":["createMiddleware","initChatModel"],"sources":["../../../src/agents/middleware/modelFallback.ts"],"sourcesContent":["import type { AgentLanguageModelLike as LanguageModelLike } from \"../model.js\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport { createMiddleware } from \"../middleware.js\";\n\n/**\n * Middleware that provides automatic model fallback on errors.\n *\n * This middleware attempts to retry failed model calls with alternative models\n * in sequence. When a model call fails, it tries the next model in the fallback\n * list until either a call succeeds or all models have been exhausted.\n *\n * @example\n * ```ts\n * import { createAgent, modelFallbackMiddleware } from \"langchain\";\n *\n * // Create middleware with fallback models (not including primary)\n * const fallback = modelFallbackMiddleware(\n * \"openai:gpt-4o-mini\", // First fallback\n * \"anthropic:claude-sonnet-4-5-20250929\", // Second fallback\n * );\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\", // Primary model\n * middleware: [fallback],\n * tools: [],\n * });\n *\n * // If gpt-4o fails, automatically tries gpt-4o-mini, then claude\n * const result = await agent.invoke({\n * messages: [{ role: \"user\", content: \"Hello\" }]\n * });\n * ```\n *\n * @param fallbackModels - The fallback models to try, in order.\n * @returns A middleware instance that handles model failures with fallbacks\n */\nexport function modelFallbackMiddleware(\n /**\n * The fallback models to try, in order.\n */\n ...fallbackModels: (string | LanguageModelLike)[]\n) {\n return createMiddleware({\n name: \"modelFallbackMiddleware\",\n wrapModelCall: async (request, handler) => {\n /**\n * Try the primary model first\n */\n try {\n return await handler(request);\n } catch (error) {\n /**\n * If primary model fails, try fallback models in sequence\n */\n for (let i = 0; i < fallbackModels.length; i++) {\n try {\n const fallbackModel = fallbackModels[i];\n const model =\n typeof fallbackModel === \"string\"\n ? await initChatModel(fallbackModel)\n : fallbackModel;\n\n return await handler({\n ...request,\n model,\n });\n } catch (fallbackError) {\n /**\n * If this is the last fallback, throw the error\n */\n if (i === fallbackModels.length - 1) {\n throw fallbackError;\n }\n // Otherwise, continue to next fallback\n }\n }\n /**\n * If no fallbacks were provided, re-throw the original error\n */\n throw error;\n }\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,SAAgB,wBAId,GAAG,gBACH;CACA,OAAOA,mBAAAA,iBAAiB;EACtB,MAAM;EACN,eAAe,OAAO,SAAS,YAAY;;;;GAIzC,IAAI;IACF,OAAO,MAAM,QAAQ,OAAO;GAC9B,SAAS,OAAO;;;;IAId,KAAK,IAAI,IAAI,GAAG,IAAI,eAAe,QAAQ,KACzC,IAAI;KACF,MAAM,gBAAgB,eAAe;KACrC,MAAM,QACJ,OAAO,kBAAkB,WACrB,MAAMC,8BAAAA,cAAc,aAAa,IACjC;KAEN,OAAO,MAAM,QAAQ;MACnB,GAAG;MACH;KACF,CAAC;IACH,SAAS,eAAe;;;;KAItB,IAAI,MAAM,eAAe,SAAS,GAChC,MAAM;IAGV;;;;IAKF,MAAM;GACR;EACF;CACF,CAAC;AACH"}
@@ -1,7 +1,5 @@
1
1
  import { AgentLanguageModelLike } from "../model.cjs";
2
2
  import { AgentMiddleware } from "./types.cjs";
3
- import * as _$_langchain_core_tools0 from "@langchain/core/tools";
4
-
5
3
  //#region src/agents/middleware/modelFallback.d.ts
6
4
  /**
7
5
  * Middleware that provides automatic model fallback on errors.
@@ -39,7 +37,7 @@ declare function modelFallbackMiddleware(
39
37
  /**
40
38
  * The fallback models to try, in order.
41
39
  */
42
- ...fallbackModels: (string | AgentLanguageModelLike)[]): AgentMiddleware<undefined, undefined, unknown, readonly (_$_langchain_core_tools0.ServerTool | _$_langchain_core_tools0.ClientTool)[], readonly []>;
40
+ ...fallbackModels: (string | AgentLanguageModelLike)[]): AgentMiddleware<undefined, undefined, unknown, readonly (import("@langchain/core/tools").ServerTool | import("@langchain/core/tools").ClientTool)[], readonly []>;
43
41
  //#endregion
44
42
  export { modelFallbackMiddleware };
45
43
  //# sourceMappingURL=modelFallback.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"modelFallback.d.cts","names":[],"sources":["../../../src/agents/middleware/modelFallback.ts"],"mappings":";;;;;;;;;AAoCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,uBAAA;;;;GAIX,cAAA,YAA0B,sBAAA,MAAoB,eAAA,0CAAH,wBAAA,CAAG,UAAA,GAAA,wBAAA,CAAA,UAAA"}
1
+ {"version":3,"file":"modelFallback.d.cts","names":[],"sources":["../../../src/agents/middleware/modelFallback.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoCgB;;;;GAIX,0BAA0B,4BAAA,yFAAoB,6CAAA"}
@@ -1,7 +1,5 @@
1
1
  import { AgentLanguageModelLike } from "../model.js";
2
2
  import { AgentMiddleware } from "./types.js";
3
- import * as _$_langchain_core_tools0 from "@langchain/core/tools";
4
-
5
3
  //#region src/agents/middleware/modelFallback.d.ts
6
4
  /**
7
5
  * Middleware that provides automatic model fallback on errors.
@@ -39,7 +37,7 @@ declare function modelFallbackMiddleware(
39
37
  /**
40
38
  * The fallback models to try, in order.
41
39
  */
42
- ...fallbackModels: (string | AgentLanguageModelLike)[]): AgentMiddleware<undefined, undefined, unknown, readonly (_$_langchain_core_tools0.ServerTool | _$_langchain_core_tools0.ClientTool)[], readonly []>;
40
+ ...fallbackModels: (string | AgentLanguageModelLike)[]): AgentMiddleware<undefined, undefined, unknown, readonly (import("@langchain/core/tools").ServerTool | import("@langchain/core/tools").ClientTool)[], readonly []>;
43
41
  //#endregion
44
42
  export { modelFallbackMiddleware };
45
43
  //# sourceMappingURL=modelFallback.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"modelFallback.d.ts","names":[],"sources":["../../../src/agents/middleware/modelFallback.ts"],"mappings":";;;;;;;;;AAoCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,uBAAA;;;;GAIX,cAAA,YAA0B,sBAAA,MAAoB,eAAA,0CAAH,wBAAA,CAAG,UAAA,GAAA,wBAAA,CAAA,UAAA"}
1
+ {"version":3,"file":"modelFallback.d.ts","names":[],"sources":["../../../src/agents/middleware/modelFallback.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoCgB;;;;GAIX,0BAA0B,4BAAA,yFAAoB,6CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"modelFallback.js","names":[],"sources":["../../../src/agents/middleware/modelFallback.ts"],"sourcesContent":["import type { AgentLanguageModelLike as LanguageModelLike } from \"../model.js\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport { createMiddleware } from \"../middleware.js\";\n\n/**\n * Middleware that provides automatic model fallback on errors.\n *\n * This middleware attempts to retry failed model calls with alternative models\n * in sequence. When a model call fails, it tries the next model in the fallback\n * list until either a call succeeds or all models have been exhausted.\n *\n * @example\n * ```ts\n * import { createAgent, modelFallbackMiddleware } from \"langchain\";\n *\n * // Create middleware with fallback models (not including primary)\n * const fallback = modelFallbackMiddleware(\n * \"openai:gpt-4o-mini\", // First fallback\n * \"anthropic:claude-sonnet-4-5-20250929\", // Second fallback\n * );\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\", // Primary model\n * middleware: [fallback],\n * tools: [],\n * });\n *\n * // If gpt-4o fails, automatically tries gpt-4o-mini, then claude\n * const result = await agent.invoke({\n * messages: [{ role: \"user\", content: \"Hello\" }]\n * });\n * ```\n *\n * @param fallbackModels - The fallback models to try, in order.\n * @returns A middleware instance that handles model failures with fallbacks\n */\nexport function modelFallbackMiddleware(\n /**\n * The fallback models to try, in order.\n */\n ...fallbackModels: (string | LanguageModelLike)[]\n) {\n return createMiddleware({\n name: \"modelFallbackMiddleware\",\n wrapModelCall: async (request, handler) => {\n /**\n * Try the primary model first\n */\n try {\n return await handler(request);\n } catch (error) {\n /**\n * If primary model fails, try fallback models in sequence\n */\n for (let i = 0; i < fallbackModels.length; i++) {\n try {\n const fallbackModel = fallbackModels[i];\n const model =\n typeof fallbackModel === \"string\"\n ? await initChatModel(fallbackModel)\n : fallbackModel;\n\n return await handler({\n ...request,\n model,\n });\n } catch (fallbackError) {\n /**\n * If this is the last fallback, throw the error\n */\n if (i === fallbackModels.length - 1) {\n throw fallbackError;\n }\n // Otherwise, continue to next fallback\n }\n }\n /**\n * If no fallbacks were provided, re-throw the original error\n */\n throw error;\n }\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,SAAgB,wBAId,GAAG,gBACH;AACA,QAAO,iBAAiB;EACtB,MAAM;EACN,eAAe,OAAO,SAAS,YAAY;;;;AAIzC,OAAI;AACF,WAAO,MAAM,QAAQ,QAAQ;YACtB,OAAO;;;;AAId,SAAK,IAAI,IAAI,GAAG,IAAI,eAAe,QAAQ,IACzC,KAAI;KACF,MAAM,gBAAgB,eAAe;KACrC,MAAM,QACJ,OAAO,kBAAkB,WACrB,MAAM,cAAc,cAAc,GAClC;AAEN,YAAO,MAAM,QAAQ;MACnB,GAAG;MACH;MACD,CAAC;aACK,eAAe;;;;AAItB,SAAI,MAAM,eAAe,SAAS,EAChC,OAAM;;;;;AAQZ,UAAM;;;EAGX,CAAC"}
1
+ {"version":3,"file":"modelFallback.js","names":[],"sources":["../../../src/agents/middleware/modelFallback.ts"],"sourcesContent":["import type { AgentLanguageModelLike as LanguageModelLike } from \"../model.js\";\nimport { initChatModel } from \"../../chat_models/universal.js\";\nimport { createMiddleware } from \"../middleware.js\";\n\n/**\n * Middleware that provides automatic model fallback on errors.\n *\n * This middleware attempts to retry failed model calls with alternative models\n * in sequence. When a model call fails, it tries the next model in the fallback\n * list until either a call succeeds or all models have been exhausted.\n *\n * @example\n * ```ts\n * import { createAgent, modelFallbackMiddleware } from \"langchain\";\n *\n * // Create middleware with fallback models (not including primary)\n * const fallback = modelFallbackMiddleware(\n * \"openai:gpt-4o-mini\", // First fallback\n * \"anthropic:claude-sonnet-4-5-20250929\", // Second fallback\n * );\n *\n * const agent = createAgent({\n * model: \"openai:gpt-4o\", // Primary model\n * middleware: [fallback],\n * tools: [],\n * });\n *\n * // If gpt-4o fails, automatically tries gpt-4o-mini, then claude\n * const result = await agent.invoke({\n * messages: [{ role: \"user\", content: \"Hello\" }]\n * });\n * ```\n *\n * @param fallbackModels - The fallback models to try, in order.\n * @returns A middleware instance that handles model failures with fallbacks\n */\nexport function modelFallbackMiddleware(\n /**\n * The fallback models to try, in order.\n */\n ...fallbackModels: (string | LanguageModelLike)[]\n) {\n return createMiddleware({\n name: \"modelFallbackMiddleware\",\n wrapModelCall: async (request, handler) => {\n /**\n * Try the primary model first\n */\n try {\n return await handler(request);\n } catch (error) {\n /**\n * If primary model fails, try fallback models in sequence\n */\n for (let i = 0; i < fallbackModels.length; i++) {\n try {\n const fallbackModel = fallbackModels[i];\n const model =\n typeof fallbackModel === \"string\"\n ? await initChatModel(fallbackModel)\n : fallbackModel;\n\n return await handler({\n ...request,\n model,\n });\n } catch (fallbackError) {\n /**\n * If this is the last fallback, throw the error\n */\n if (i === fallbackModels.length - 1) {\n throw fallbackError;\n }\n // Otherwise, continue to next fallback\n }\n }\n /**\n * If no fallbacks were provided, re-throw the original error\n */\n throw error;\n }\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,SAAgB,wBAId,GAAG,gBACH;CACA,OAAO,iBAAiB;EACtB,MAAM;EACN,eAAe,OAAO,SAAS,YAAY;;;;GAIzC,IAAI;IACF,OAAO,MAAM,QAAQ,OAAO;GAC9B,SAAS,OAAO;;;;IAId,KAAK,IAAI,IAAI,GAAG,IAAI,eAAe,QAAQ,KACzC,IAAI;KACF,MAAM,gBAAgB,eAAe;KACrC,MAAM,QACJ,OAAO,kBAAkB,WACrB,MAAM,cAAc,aAAa,IACjC;KAEN,OAAO,MAAM,QAAQ;MACnB,GAAG;MACH;KACF,CAAC;IACH,SAAS,eAAe;;;;KAItB,IAAI,MAAM,eAAe,SAAS,GAChC,MAAM;IAGV;;;;IAKF,MAAM;GACR;EACF;CACF,CAAC;AACH"}
@@ -1,4 +1,3 @@
1
- require("../../_virtual/_rolldown/runtime.cjs");
2
1
  const require_utils = require("./utils.cjs");
3
2
  const require_middleware = require("../middleware.cjs");
4
3
  const require_constants = require("./constants.cjs");
@@ -167,6 +166,7 @@ function modelRetryMiddleware(config = {}) {
167
166
  });
168
167
  }
169
168
  //#endregion
169
+ exports.ModelRetryMiddlewareOptionsSchema = ModelRetryMiddlewareOptionsSchema;
170
170
  exports.modelRetryMiddleware = modelRetryMiddleware;
171
171
 
172
172
  //# sourceMappingURL=modelRetry.cjs.map