@langchain/core 1.1.49-dev-1781048185730 → 1.1.49

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 (410) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/agents.cjs +1 -0
  3. package/agents.d.cts +1 -0
  4. package/agents.d.ts +1 -0
  5. package/agents.js +1 -0
  6. package/caches.cjs +1 -0
  7. package/caches.d.cts +1 -0
  8. package/caches.d.ts +1 -0
  9. package/caches.js +1 -0
  10. package/callbacks/base.cjs +1 -0
  11. package/callbacks/base.d.cts +1 -0
  12. package/callbacks/base.d.ts +1 -0
  13. package/callbacks/base.js +1 -0
  14. package/callbacks/dispatch/web.cjs +1 -0
  15. package/callbacks/dispatch/web.d.cts +1 -0
  16. package/callbacks/dispatch/web.d.ts +1 -0
  17. package/callbacks/dispatch/web.js +1 -0
  18. package/callbacks/dispatch.cjs +1 -0
  19. package/callbacks/dispatch.d.cts +1 -0
  20. package/callbacks/dispatch.d.ts +1 -0
  21. package/callbacks/dispatch.js +1 -0
  22. package/callbacks/manager.cjs +1 -0
  23. package/callbacks/manager.d.cts +1 -0
  24. package/callbacks/manager.d.ts +1 -0
  25. package/callbacks/manager.js +1 -0
  26. package/callbacks/promises.cjs +1 -0
  27. package/callbacks/promises.d.cts +1 -0
  28. package/callbacks/promises.d.ts +1 -0
  29. package/callbacks/promises.js +1 -0
  30. package/chat_history.cjs +1 -0
  31. package/chat_history.d.cts +1 -0
  32. package/chat_history.d.ts +1 -0
  33. package/chat_history.js +1 -0
  34. package/context.cjs +1 -0
  35. package/context.d.cts +1 -0
  36. package/context.d.ts +1 -0
  37. package/context.js +1 -0
  38. package/dist/callbacks/dispatch/index.cjs.map +1 -1
  39. package/dist/callbacks/dispatch/index.js.map +1 -1
  40. package/dist/callbacks/manager.cjs.map +1 -1
  41. package/dist/callbacks/manager.js.map +1 -1
  42. package/dist/example_selectors/conditional.cjs.map +1 -1
  43. package/dist/example_selectors/conditional.js.map +1 -1
  44. package/dist/example_selectors/length_based.cjs.map +1 -1
  45. package/dist/example_selectors/length_based.js.map +1 -1
  46. package/dist/example_selectors/semantic_similarity.cjs.map +1 -1
  47. package/dist/example_selectors/semantic_similarity.js.map +1 -1
  48. package/dist/indexing/base.cjs.map +1 -1
  49. package/dist/indexing/base.js.map +1 -1
  50. package/dist/language_models/base.cjs +1 -1
  51. package/dist/language_models/base.cjs.map +1 -1
  52. package/dist/language_models/base.js +1 -1
  53. package/dist/language_models/base.js.map +1 -1
  54. package/dist/language_models/chat_models.cjs.map +1 -1
  55. package/dist/language_models/chat_models.js.map +1 -1
  56. package/dist/language_models/compat.cjs.map +1 -1
  57. package/dist/language_models/compat.js.map +1 -1
  58. package/dist/language_models/llms.cjs.map +1 -1
  59. package/dist/language_models/llms.js.map +1 -1
  60. package/dist/language_models/stream.cjs.map +1 -1
  61. package/dist/language_models/stream.js.map +1 -1
  62. package/dist/load/index.cjs.map +1 -1
  63. package/dist/load/index.js.map +1 -1
  64. package/dist/memory.cjs.map +1 -1
  65. package/dist/memory.js.map +1 -1
  66. package/dist/messages/base.cjs.map +1 -1
  67. package/dist/messages/base.js.map +1 -1
  68. package/dist/messages/block_translators/anthropic.cjs.map +1 -1
  69. package/dist/messages/block_translators/anthropic.js.map +1 -1
  70. package/dist/messages/block_translators/bedrock_converse.cjs.map +1 -1
  71. package/dist/messages/block_translators/bedrock_converse.js.map +1 -1
  72. package/dist/messages/block_translators/google.cjs.map +1 -1
  73. package/dist/messages/block_translators/google.js.map +1 -1
  74. package/dist/messages/block_translators/google_vertexai.cjs.map +1 -1
  75. package/dist/messages/block_translators/google_vertexai.js.map +1 -1
  76. package/dist/messages/block_translators/openai.cjs.map +1 -1
  77. package/dist/messages/block_translators/openai.js.map +1 -1
  78. package/dist/messages/transformers.cjs.map +1 -1
  79. package/dist/messages/transformers.js.map +1 -1
  80. package/dist/messages/utils.cjs.map +1 -1
  81. package/dist/messages/utils.js.map +1 -1
  82. package/dist/output_parsers/openai_functions/json_output_functions_parsers.cjs.map +1 -1
  83. package/dist/output_parsers/openai_functions/json_output_functions_parsers.js.map +1 -1
  84. package/dist/output_parsers/openai_tools/json_output_tools_parsers.cjs.map +1 -1
  85. package/dist/output_parsers/openai_tools/json_output_tools_parsers.js.map +1 -1
  86. package/dist/output_parsers/structured.cjs.map +1 -1
  87. package/dist/output_parsers/structured.js.map +1 -1
  88. package/dist/output_parsers/xml.cjs.map +1 -1
  89. package/dist/output_parsers/xml.js.map +1 -1
  90. package/dist/prompts/base.cjs.map +1 -1
  91. package/dist/prompts/base.js.map +1 -1
  92. package/dist/prompts/chat.cjs.map +1 -1
  93. package/dist/prompts/chat.js.map +1 -1
  94. package/dist/prompts/few_shot.cjs.map +1 -1
  95. package/dist/prompts/few_shot.js.map +1 -1
  96. package/dist/prompts/image.cjs.map +1 -1
  97. package/dist/prompts/image.js.map +1 -1
  98. package/dist/prompts/prompt.cjs.map +1 -1
  99. package/dist/prompts/prompt.js.map +1 -1
  100. package/dist/prompts/string.cjs.map +1 -1
  101. package/dist/prompts/string.js.map +1 -1
  102. package/dist/prompts/template.cjs.map +1 -1
  103. package/dist/prompts/template.js.map +1 -1
  104. package/dist/retrievers/index.cjs.map +1 -1
  105. package/dist/retrievers/index.js.map +1 -1
  106. package/dist/runnables/base.cjs.map +1 -1
  107. package/dist/runnables/base.js.map +1 -1
  108. package/dist/runnables/branch.cjs.map +1 -1
  109. package/dist/runnables/branch.js.map +1 -1
  110. package/dist/runnables/graph.cjs.map +1 -1
  111. package/dist/runnables/graph.js.map +1 -1
  112. package/dist/runnables/graph_mermaid.cjs.map +1 -1
  113. package/dist/runnables/graph_mermaid.js.map +1 -1
  114. package/dist/runnables/history.cjs.map +1 -1
  115. package/dist/runnables/history.js.map +1 -1
  116. package/dist/runnables/router.cjs.map +1 -1
  117. package/dist/runnables/router.js.map +1 -1
  118. package/dist/runnables/utils.cjs.map +1 -1
  119. package/dist/runnables/utils.js.map +1 -1
  120. package/dist/singletons/async_local_storage/context.cjs.map +1 -1
  121. package/dist/singletons/async_local_storage/context.js.map +1 -1
  122. package/dist/singletons/async_local_storage/index.cjs.map +1 -1
  123. package/dist/singletons/async_local_storage/index.js.map +1 -1
  124. package/dist/testing/fake_model_builder.cjs.map +1 -1
  125. package/dist/testing/fake_model_builder.js.map +1 -1
  126. package/dist/testing/matchers.cjs.map +1 -1
  127. package/dist/testing/matchers.js.map +1 -1
  128. package/dist/tracers/console.cjs.map +1 -1
  129. package/dist/tracers/console.js.map +1 -1
  130. package/dist/tracers/event_stream.cjs.map +1 -1
  131. package/dist/tracers/event_stream.js.map +1 -1
  132. package/dist/tracers/tracer_langchain.cjs.map +1 -1
  133. package/dist/tracers/tracer_langchain.js.map +1 -1
  134. package/dist/utils/callbacks.cjs.map +1 -1
  135. package/dist/utils/callbacks.js.map +1 -1
  136. package/dist/utils/context.cjs.map +1 -1
  137. package/dist/utils/context.js.map +1 -1
  138. package/dist/utils/env.cjs.map +1 -1
  139. package/dist/utils/env.js.map +1 -1
  140. package/dist/utils/fast-json-patch/src/core.cjs.map +1 -1
  141. package/dist/utils/fast-json-patch/src/core.js.map +1 -1
  142. package/dist/utils/json_schema.cjs.map +1 -1
  143. package/dist/utils/json_schema.js.map +1 -1
  144. package/dist/utils/sax-js/sax.cjs.map +1 -1
  145. package/dist/utils/sax-js/sax.js.map +1 -1
  146. package/dist/utils/ssrf.cjs.map +1 -1
  147. package/dist/utils/ssrf.js.map +1 -1
  148. package/dist/utils/stream.d.cts +2 -2
  149. package/dist/utils/stream.d.cts.map +1 -1
  150. package/dist/utils/stream.d.ts +2 -2
  151. package/dist/utils/stream.d.ts.map +1 -1
  152. package/dist/utils/testing/chat_models.cjs.map +1 -1
  153. package/dist/utils/testing/chat_models.js.map +1 -1
  154. package/dist/utils/testing/embeddings.cjs.map +1 -1
  155. package/dist/utils/testing/embeddings.js.map +1 -1
  156. package/dist/utils/testing/vectorstores.cjs.map +1 -1
  157. package/dist/utils/testing/vectorstores.js.map +1 -1
  158. package/dist/utils/types/zod.cjs.map +1 -1
  159. package/dist/utils/types/zod.js.map +1 -1
  160. package/dist/utils/uuid/v35.cjs.map +1 -1
  161. package/dist/utils/uuid/v35.js.map +1 -1
  162. package/dist/utils/zod-to-json-schema/parsers/nativeEnum.cjs.map +1 -1
  163. package/dist/utils/zod-to-json-schema/parsers/nativeEnum.js.map +1 -1
  164. package/dist/utils/zod-to-json-schema/parsers/pipeline.cjs.map +1 -1
  165. package/dist/utils/zod-to-json-schema/parsers/pipeline.js.map +1 -1
  166. package/dist/utils/zod-to-json-schema/parsers/set.cjs.map +1 -1
  167. package/dist/utils/zod-to-json-schema/parsers/set.js.map +1 -1
  168. package/dist/utils/zod-to-json-schema/parsers/string.cjs +26 -0
  169. package/dist/utils/zod-to-json-schema/parsers/string.cjs.map +1 -1
  170. package/dist/utils/zod-to-json-schema/parsers/string.js +26 -0
  171. package/dist/utils/zod-to-json-schema/parsers/string.js.map +1 -1
  172. package/dist/vectorstores.cjs.map +1 -1
  173. package/dist/vectorstores.js.map +1 -1
  174. package/document_loaders/base.cjs +1 -0
  175. package/document_loaders/base.d.cts +1 -0
  176. package/document_loaders/base.d.ts +1 -0
  177. package/document_loaders/base.js +1 -0
  178. package/document_loaders/langsmith.cjs +1 -0
  179. package/document_loaders/langsmith.d.cts +1 -0
  180. package/document_loaders/langsmith.d.ts +1 -0
  181. package/document_loaders/langsmith.js +1 -0
  182. package/documents.cjs +1 -0
  183. package/documents.d.cts +1 -0
  184. package/documents.d.ts +1 -0
  185. package/documents.js +1 -0
  186. package/embeddings.cjs +1 -0
  187. package/embeddings.d.cts +1 -0
  188. package/embeddings.d.ts +1 -0
  189. package/embeddings.js +1 -0
  190. package/errors.cjs +1 -0
  191. package/errors.d.cts +1 -0
  192. package/errors.d.ts +1 -0
  193. package/errors.js +1 -0
  194. package/example_selectors.cjs +1 -0
  195. package/example_selectors.d.cts +1 -0
  196. package/example_selectors.d.ts +1 -0
  197. package/example_selectors.js +1 -0
  198. package/indexing.cjs +1 -0
  199. package/indexing.d.cts +1 -0
  200. package/indexing.d.ts +1 -0
  201. package/indexing.js +1 -0
  202. package/language_models/base.cjs +1 -0
  203. package/language_models/base.d.cts +1 -0
  204. package/language_models/base.d.ts +1 -0
  205. package/language_models/base.js +1 -0
  206. package/language_models/chat_models.cjs +1 -0
  207. package/language_models/chat_models.d.cts +1 -0
  208. package/language_models/chat_models.d.ts +1 -0
  209. package/language_models/chat_models.js +1 -0
  210. package/language_models/compat.cjs +1 -0
  211. package/language_models/compat.d.cts +1 -0
  212. package/language_models/compat.d.ts +1 -0
  213. package/language_models/compat.js +1 -0
  214. package/language_models/event.cjs +1 -0
  215. package/language_models/event.d.cts +1 -0
  216. package/language_models/event.d.ts +1 -0
  217. package/language_models/event.js +1 -0
  218. package/language_models/llms.cjs +1 -0
  219. package/language_models/llms.d.cts +1 -0
  220. package/language_models/llms.d.ts +1 -0
  221. package/language_models/llms.js +1 -0
  222. package/language_models/profile.cjs +1 -0
  223. package/language_models/profile.d.cts +1 -0
  224. package/language_models/profile.d.ts +1 -0
  225. package/language_models/profile.js +1 -0
  226. package/language_models/stream.cjs +1 -0
  227. package/language_models/stream.d.cts +1 -0
  228. package/language_models/stream.d.ts +1 -0
  229. package/language_models/stream.js +1 -0
  230. package/language_models/structured_output.cjs +1 -0
  231. package/language_models/structured_output.d.cts +1 -0
  232. package/language_models/structured_output.d.ts +1 -0
  233. package/language_models/structured_output.js +1 -0
  234. package/load/serializable.cjs +1 -0
  235. package/load/serializable.d.cts +1 -0
  236. package/load/serializable.d.ts +1 -0
  237. package/load/serializable.js +1 -0
  238. package/load.cjs +1 -0
  239. package/load.d.cts +1 -0
  240. package/load.d.ts +1 -0
  241. package/load.js +1 -0
  242. package/memory.cjs +1 -0
  243. package/memory.d.cts +1 -0
  244. package/memory.d.ts +1 -0
  245. package/memory.js +1 -0
  246. package/messages/tool.cjs +1 -0
  247. package/messages/tool.d.cts +1 -0
  248. package/messages/tool.d.ts +1 -0
  249. package/messages/tool.js +1 -0
  250. package/messages.cjs +1 -0
  251. package/messages.d.cts +1 -0
  252. package/messages.d.ts +1 -0
  253. package/messages.js +1 -0
  254. package/output_parsers/openai_functions.cjs +1 -0
  255. package/output_parsers/openai_functions.d.cts +1 -0
  256. package/output_parsers/openai_functions.d.ts +1 -0
  257. package/output_parsers/openai_functions.js +1 -0
  258. package/output_parsers/openai_tools.cjs +1 -0
  259. package/output_parsers/openai_tools.d.cts +1 -0
  260. package/output_parsers/openai_tools.d.ts +1 -0
  261. package/output_parsers/openai_tools.js +1 -0
  262. package/output_parsers.cjs +1 -0
  263. package/output_parsers.d.cts +1 -0
  264. package/output_parsers.d.ts +1 -0
  265. package/output_parsers.js +1 -0
  266. package/outputs.cjs +1 -0
  267. package/outputs.d.cts +1 -0
  268. package/outputs.d.ts +1 -0
  269. package/outputs.js +1 -0
  270. package/package.json +5 -5
  271. package/prompt_values.cjs +1 -0
  272. package/prompt_values.d.cts +1 -0
  273. package/prompt_values.d.ts +1 -0
  274. package/prompt_values.js +1 -0
  275. package/prompts.cjs +1 -0
  276. package/prompts.d.cts +1 -0
  277. package/prompts.d.ts +1 -0
  278. package/prompts.js +1 -0
  279. package/retrievers/document_compressors.cjs +1 -0
  280. package/retrievers/document_compressors.d.cts +1 -0
  281. package/retrievers/document_compressors.d.ts +1 -0
  282. package/retrievers/document_compressors.js +1 -0
  283. package/retrievers.cjs +1 -0
  284. package/retrievers.d.cts +1 -0
  285. package/retrievers.d.ts +1 -0
  286. package/retrievers.js +1 -0
  287. package/runnables/graph.cjs +1 -0
  288. package/runnables/graph.d.cts +1 -0
  289. package/runnables/graph.d.ts +1 -0
  290. package/runnables/graph.js +1 -0
  291. package/runnables.cjs +1 -0
  292. package/runnables.d.cts +1 -0
  293. package/runnables.d.ts +1 -0
  294. package/runnables.js +1 -0
  295. package/singletons.cjs +1 -0
  296. package/singletons.d.cts +1 -0
  297. package/singletons.d.ts +1 -0
  298. package/singletons.js +1 -0
  299. package/stores.cjs +1 -0
  300. package/stores.d.cts +1 -0
  301. package/stores.d.ts +1 -0
  302. package/stores.js +1 -0
  303. package/structured_query.cjs +1 -0
  304. package/structured_query.d.cts +1 -0
  305. package/structured_query.d.ts +1 -0
  306. package/structured_query.js +1 -0
  307. package/tools.cjs +1 -0
  308. package/tools.d.cts +1 -0
  309. package/tools.d.ts +1 -0
  310. package/tools.js +1 -0
  311. package/tracers/base.cjs +1 -0
  312. package/tracers/base.d.cts +1 -0
  313. package/tracers/base.d.ts +1 -0
  314. package/tracers/base.js +1 -0
  315. package/tracers/console.cjs +1 -0
  316. package/tracers/console.d.cts +1 -0
  317. package/tracers/console.d.ts +1 -0
  318. package/tracers/console.js +1 -0
  319. package/tracers/log_stream.cjs +1 -0
  320. package/tracers/log_stream.d.cts +1 -0
  321. package/tracers/log_stream.d.ts +1 -0
  322. package/tracers/log_stream.js +1 -0
  323. package/tracers/run_collector.cjs +1 -0
  324. package/tracers/run_collector.d.cts +1 -0
  325. package/tracers/run_collector.d.ts +1 -0
  326. package/tracers/run_collector.js +1 -0
  327. package/tracers/tracer_langchain.cjs +1 -0
  328. package/tracers/tracer_langchain.d.cts +1 -0
  329. package/tracers/tracer_langchain.d.ts +1 -0
  330. package/tracers/tracer_langchain.js +1 -0
  331. package/types/stream.cjs +1 -0
  332. package/types/stream.d.cts +1 -0
  333. package/types/stream.d.ts +1 -0
  334. package/types/stream.js +1 -0
  335. package/utils/async_caller.cjs +1 -0
  336. package/utils/async_caller.d.cts +1 -0
  337. package/utils/async_caller.d.ts +1 -0
  338. package/utils/async_caller.js +1 -0
  339. package/utils/chunk_array.cjs +1 -0
  340. package/utils/chunk_array.d.cts +1 -0
  341. package/utils/chunk_array.d.ts +1 -0
  342. package/utils/chunk_array.js +1 -0
  343. package/utils/context.cjs +1 -0
  344. package/utils/context.d.cts +1 -0
  345. package/utils/context.d.ts +1 -0
  346. package/utils/context.js +1 -0
  347. package/utils/env.cjs +1 -0
  348. package/utils/env.d.cts +1 -0
  349. package/utils/env.d.ts +1 -0
  350. package/utils/env.js +1 -0
  351. package/utils/event_source_parse.cjs +1 -0
  352. package/utils/event_source_parse.d.cts +1 -0
  353. package/utils/event_source_parse.d.ts +1 -0
  354. package/utils/event_source_parse.js +1 -0
  355. package/utils/format.cjs +1 -0
  356. package/utils/format.d.cts +1 -0
  357. package/utils/format.d.ts +1 -0
  358. package/utils/format.js +1 -0
  359. package/utils/function_calling.cjs +1 -0
  360. package/utils/function_calling.d.cts +1 -0
  361. package/utils/function_calling.d.ts +1 -0
  362. package/utils/function_calling.js +1 -0
  363. package/utils/hash.cjs +1 -0
  364. package/utils/hash.d.cts +1 -0
  365. package/utils/hash.d.ts +1 -0
  366. package/utils/hash.js +1 -0
  367. package/utils/json_patch.cjs +1 -0
  368. package/utils/json_patch.d.cts +1 -0
  369. package/utils/json_patch.d.ts +1 -0
  370. package/utils/json_patch.js +1 -0
  371. package/utils/json_schema.cjs +1 -0
  372. package/utils/json_schema.d.cts +1 -0
  373. package/utils/json_schema.d.ts +1 -0
  374. package/utils/json_schema.js +1 -0
  375. package/utils/math.cjs +1 -0
  376. package/utils/math.d.cts +1 -0
  377. package/utils/math.d.ts +1 -0
  378. package/utils/math.js +1 -0
  379. package/utils/ssrf.cjs +1 -0
  380. package/utils/ssrf.d.cts +1 -0
  381. package/utils/ssrf.d.ts +1 -0
  382. package/utils/ssrf.js +1 -0
  383. package/utils/standard_schema.cjs +1 -0
  384. package/utils/standard_schema.d.cts +1 -0
  385. package/utils/standard_schema.d.ts +1 -0
  386. package/utils/standard_schema.js +1 -0
  387. package/utils/stream.cjs +1 -0
  388. package/utils/stream.d.cts +1 -0
  389. package/utils/stream.d.ts +1 -0
  390. package/utils/stream.js +1 -0
  391. package/utils/testing.cjs +1 -0
  392. package/utils/testing.d.cts +1 -0
  393. package/utils/testing.d.ts +1 -0
  394. package/utils/testing.js +1 -0
  395. package/utils/tiktoken.cjs +1 -0
  396. package/utils/tiktoken.d.cts +1 -0
  397. package/utils/tiktoken.d.ts +1 -0
  398. package/utils/tiktoken.js +1 -0
  399. package/utils/types.cjs +1 -0
  400. package/utils/types.d.cts +1 -0
  401. package/utils/types.d.ts +1 -0
  402. package/utils/types.js +1 -0
  403. package/utils/uuid.cjs +1 -0
  404. package/utils/uuid.d.cts +1 -0
  405. package/utils/uuid.d.ts +1 -0
  406. package/utils/uuid.js +1 -0
  407. package/vectorstores.cjs +1 -0
  408. package/vectorstores.d.cts +1 -0
  409. package/vectorstores.d.ts +1 -0
  410. package/vectorstores.js +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../src/runnables/utils.ts"],"sourcesContent":["import { StreamEvent } from \"../tracers/event_stream.js\";\nimport type { RunnableInterface } from \"./types.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isRunnableInterface(thing: any): thing is RunnableInterface {\n return thing ? thing.lc_runnable : false;\n}\n\n/**\n * Utility to filter the root event in the streamEvents implementation.\n * This is simply binding the arguments to the namespace to make save on\n * a bit of typing in the streamEvents implementation.\n *\n * TODO: Refactor and remove.\n */\nexport class _RootEventFilter {\n includeNames?: string[];\n\n includeTypes?: string[];\n\n includeTags?: string[];\n\n excludeNames?: string[];\n\n excludeTypes?: string[];\n\n excludeTags?: string[];\n\n constructor(fields: {\n includeNames?: string[];\n includeTypes?: string[];\n includeTags?: string[];\n excludeNames?: string[];\n excludeTypes?: string[];\n excludeTags?: string[];\n }) {\n this.includeNames = fields.includeNames;\n this.includeTypes = fields.includeTypes;\n this.includeTags = fields.includeTags;\n this.excludeNames = fields.excludeNames;\n this.excludeTypes = fields.excludeTypes;\n this.excludeTags = fields.excludeTags;\n }\n\n includeEvent(event: StreamEvent, rootType: string): boolean {\n let include =\n this.includeNames === undefined &&\n this.includeTypes === undefined &&\n this.includeTags === undefined;\n const eventTags = event.tags ?? [];\n\n if (this.includeNames !== undefined) {\n include = include || this.includeNames.includes(event.name);\n }\n if (this.includeTypes !== undefined) {\n include = include || this.includeTypes.includes(rootType);\n }\n if (this.includeTags !== undefined) {\n include =\n include || eventTags.some((tag) => this.includeTags?.includes(tag));\n }\n\n if (this.excludeNames !== undefined) {\n include = include && !this.excludeNames.includes(event.name);\n }\n if (this.excludeTypes !== undefined) {\n include = include && !this.excludeTypes.includes(rootType);\n }\n if (this.excludeTags !== undefined) {\n include =\n include && eventTags.every((tag) => !this.excludeTags?.includes(tag));\n }\n\n return include;\n }\n}\n\nexport const toBase64Url = (str: string): string => {\n // Use btoa for compatibility, assume ASCII\n const encoded = btoa(str);\n return encoded.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n};\n"],"mappings":";AAIA,SAAgB,oBAAoB,OAAwC;AAC1E,QAAO,QAAQ,MAAM,cAAc;;;;;;;;;AAUrC,IAAa,mBAAb,MAA8B;CAC5B;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA,YAAY,QAOT;AACD,OAAK,eAAe,OAAO;AAC3B,OAAK,eAAe,OAAO;AAC3B,OAAK,cAAc,OAAO;AAC1B,OAAK,eAAe,OAAO;AAC3B,OAAK,eAAe,OAAO;AAC3B,OAAK,cAAc,OAAO;;CAG5B,aAAa,OAAoB,UAA2B;EAC1D,IAAI,UACF,KAAK,iBAAiB,KAAA,KACtB,KAAK,iBAAiB,KAAA,KACtB,KAAK,gBAAgB,KAAA;EACvB,MAAM,YAAY,MAAM,QAAQ,EAAE;AAElC,MAAI,KAAK,iBAAiB,KAAA,EACxB,WAAU,WAAW,KAAK,aAAa,SAAS,MAAM,KAAK;AAE7D,MAAI,KAAK,iBAAiB,KAAA,EACxB,WAAU,WAAW,KAAK,aAAa,SAAS,SAAS;AAE3D,MAAI,KAAK,gBAAgB,KAAA,EACvB,WACE,WAAW,UAAU,MAAM,QAAQ,KAAK,aAAa,SAAS,IAAI,CAAC;AAGvE,MAAI,KAAK,iBAAiB,KAAA,EACxB,WAAU,WAAW,CAAC,KAAK,aAAa,SAAS,MAAM,KAAK;AAE9D,MAAI,KAAK,iBAAiB,KAAA,EACxB,WAAU,WAAW,CAAC,KAAK,aAAa,SAAS,SAAS;AAE5D,MAAI,KAAK,gBAAgB,KAAA,EACvB,WACE,WAAW,UAAU,OAAO,QAAQ,CAAC,KAAK,aAAa,SAAS,IAAI,CAAC;AAGzE,SAAO;;;AAIX,MAAa,eAAe,QAAwB;AAGlD,QADgB,KAAK,IAAI,CACV,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,GAAG"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../src/runnables/utils.ts"],"sourcesContent":["import { StreamEvent } from \"../tracers/event_stream.js\";\nimport type { RunnableInterface } from \"./types.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isRunnableInterface(thing: any): thing is RunnableInterface {\n return thing ? thing.lc_runnable : false;\n}\n\n/**\n * Utility to filter the root event in the streamEvents implementation.\n * This is simply binding the arguments to the namespace to make save on\n * a bit of typing in the streamEvents implementation.\n *\n * TODO: Refactor and remove.\n */\nexport class _RootEventFilter {\n includeNames?: string[];\n\n includeTypes?: string[];\n\n includeTags?: string[];\n\n excludeNames?: string[];\n\n excludeTypes?: string[];\n\n excludeTags?: string[];\n\n constructor(fields: {\n includeNames?: string[];\n includeTypes?: string[];\n includeTags?: string[];\n excludeNames?: string[];\n excludeTypes?: string[];\n excludeTags?: string[];\n }) {\n this.includeNames = fields.includeNames;\n this.includeTypes = fields.includeTypes;\n this.includeTags = fields.includeTags;\n this.excludeNames = fields.excludeNames;\n this.excludeTypes = fields.excludeTypes;\n this.excludeTags = fields.excludeTags;\n }\n\n includeEvent(event: StreamEvent, rootType: string): boolean {\n let include =\n this.includeNames === undefined &&\n this.includeTypes === undefined &&\n this.includeTags === undefined;\n const eventTags = event.tags ?? [];\n\n if (this.includeNames !== undefined) {\n include = include || this.includeNames.includes(event.name);\n }\n if (this.includeTypes !== undefined) {\n include = include || this.includeTypes.includes(rootType);\n }\n if (this.includeTags !== undefined) {\n include =\n include || eventTags.some((tag) => this.includeTags?.includes(tag));\n }\n\n if (this.excludeNames !== undefined) {\n include = include && !this.excludeNames.includes(event.name);\n }\n if (this.excludeTypes !== undefined) {\n include = include && !this.excludeTypes.includes(rootType);\n }\n if (this.excludeTags !== undefined) {\n include =\n include && eventTags.every((tag) => !this.excludeTags?.includes(tag));\n }\n\n return include;\n }\n}\n\nexport const toBase64Url = (str: string): string => {\n // Use btoa for compatibility, assume ASCII\n const encoded = btoa(str);\n return encoded.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n};\n"],"mappings":";AAIA,SAAgB,oBAAoB,OAAwC;AAC1E,QAAO,QAAQ,MAAM,cAAc;;;;;;;;;AAUrC,IAAa,mBAAb,MAA8B;CAC5B;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA,YAAY,QAOT;AACD,OAAK,eAAe,OAAO;AAC3B,OAAK,eAAe,OAAO;AAC3B,OAAK,cAAc,OAAO;AAC1B,OAAK,eAAe,OAAO;AAC3B,OAAK,eAAe,OAAO;AAC3B,OAAK,cAAc,OAAO;;CAG5B,aAAa,OAAoB,UAA2B;EAC1D,IAAI,UACF,KAAK,iBAAiB,KAAA,KACtB,KAAK,iBAAiB,KAAA,KACtB,KAAK,gBAAgB,KAAA;EACvB,MAAM,YAAY,MAAM,QAAQ,EAAE;AAElC,MAAI,KAAK,iBAAiB,KAAA,EACxB,WAAU,WAAW,KAAK,aAAa,SAAS,MAAM,KAAK;AAE7D,MAAI,KAAK,iBAAiB,KAAA,EACxB,WAAU,WAAW,KAAK,aAAa,SAAS,SAAS;AAE3D,MAAI,KAAK,gBAAgB,KAAA,EACvB,WACE,WAAW,UAAU,MAAM,QAAQ,KAAK,aAAa,SAAS,IAAI,CAAC;AAGvE,MAAI,KAAK,iBAAiB,KAAA,EACxB,WAAU,WAAW,CAAC,KAAK,aAAa,SAAS,MAAM,KAAK;AAE9D,MAAI,KAAK,iBAAiB,KAAA,EACxB,WAAU,WAAW,CAAC,KAAK,aAAa,SAAS,SAAS;AAE5D,MAAI,KAAK,gBAAgB,KAAA,EACvB,WACE,WAAW,UAAU,OAAO,QAAQ,CAAC,KAAK,aAAa,SAAS,IAAI,CAAC;AAGzE,SAAO;;;AAIX,MAAa,eAAe,QAAwB;AAGlD,QADgB,KAAK,IACP,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,GAAG"}
@@ -1 +1 @@
1
- {"version":3,"file":"context.cjs","names":["getGlobalAsyncLocalStorageInstance","_CONTEXT_VARIABLES_KEY","RunTree"],"sources":["../../../src/singletons/async_local_storage/context.ts"],"sourcesContent":["import { isRunTree, RunTree } from \"langsmith/run_trees\";\nimport { BaseCallbackHandler } from \"../../callbacks/base.js\";\nimport {\n _CONTEXT_VARIABLES_KEY,\n getGlobalAsyncLocalStorageInstance,\n} from \"./globals.js\";\n\n/**\n * Set a context variable. Context variables are scoped to any\n * child runnables called by the current runnable, or globally if set outside\n * of any runnable.\n *\n * @remarks\n * This function is only supported in environments that support AsyncLocalStorage,\n * including Node.js, Deno, and Cloudflare Workers.\n *\n * @example\n * ```ts\n * import { RunnableLambda } from \"@langchain/core/runnables\";\n * import {\n * getContextVariable,\n * setContextVariable\n * } from \"@langchain/core/context\";\n *\n * const nested = RunnableLambda.from(() => {\n * // \"bar\" because it was set by a parent\n * console.log(getContextVariable(\"foo\"));\n *\n * // Override to \"baz\", but only for child runnables\n * setContextVariable(\"foo\", \"baz\");\n *\n * // Now \"baz\", but only for child runnables\n * return getContextVariable(\"foo\");\n * });\n *\n * const runnable = RunnableLambda.from(async () => {\n * // Set a context variable named \"foo\"\n * setContextVariable(\"foo\", \"bar\");\n *\n * const res = await nested.invoke({});\n *\n * // Still \"bar\" since child changes do not affect parents\n * console.log(getContextVariable(\"foo\"));\n *\n * return res;\n * });\n *\n * // undefined, because context variable has not been set yet\n * console.log(getContextVariable(\"foo\"));\n *\n * // Final return value is \"baz\"\n * const result = await runnable.invoke({});\n * ```\n *\n * @param name The name of the context variable.\n * @param value The value to set.\n */\nexport function setContextVariable<T>(name: PropertyKey, value: T): void {\n // Avoid using global singleton due to circuluar dependency issues\n const asyncLocalStorageInstance = getGlobalAsyncLocalStorageInstance();\n if (asyncLocalStorageInstance === undefined) {\n throw new Error(\n `Internal error: Global shared async local storage instance has not been initialized.`\n );\n }\n const runTree = asyncLocalStorageInstance.getStore();\n const contextVars = { ...runTree?.[_CONTEXT_VARIABLES_KEY] };\n contextVars[name] = value;\n let newValue = {};\n if (isRunTree(runTree)) {\n newValue = new RunTree(runTree);\n }\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n (newValue as any)[_CONTEXT_VARIABLES_KEY] = contextVars;\n asyncLocalStorageInstance.enterWith(newValue);\n}\n\n/**\n * Get the value of a previously set context variable. Context variables\n * are scoped to any child runnables called by the current runnable,\n * or globally if set outside of any runnable.\n *\n * @remarks\n * This function is only supported in environments that support AsyncLocalStorage,\n * including Node.js, Deno, and Cloudflare Workers.\n *\n * @example\n * ```ts\n * import { RunnableLambda } from \"@langchain/core/runnables\";\n * import {\n * getContextVariable,\n * setContextVariable\n * } from \"@langchain/core/context\";\n *\n * const nested = RunnableLambda.from(() => {\n * // \"bar\" because it was set by a parent\n * console.log(getContextVariable(\"foo\"));\n *\n * // Override to \"baz\", but only for child runnables\n * setContextVariable(\"foo\", \"baz\");\n *\n * // Now \"baz\", but only for child runnables\n * return getContextVariable(\"foo\");\n * });\n *\n * const runnable = RunnableLambda.from(async () => {\n * // Set a context variable named \"foo\"\n * setContextVariable(\"foo\", \"bar\");\n *\n * const res = await nested.invoke({});\n *\n * // Still \"bar\" since child changes do not affect parents\n * console.log(getContextVariable(\"foo\"));\n *\n * return res;\n * });\n *\n * // undefined, because context variable has not been set yet\n * console.log(getContextVariable(\"foo\"));\n *\n * // Final return value is \"baz\"\n * const result = await runnable.invoke({});\n * ```\n *\n * @param name The name of the context variable.\n */\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getContextVariable<T = any>(name: PropertyKey): T | undefined {\n // Avoid using global singleton due to circuluar dependency issues\n const asyncLocalStorageInstance = getGlobalAsyncLocalStorageInstance();\n if (asyncLocalStorageInstance === undefined) {\n return undefined;\n }\n const runTree = asyncLocalStorageInstance.getStore();\n return runTree?.[_CONTEXT_VARIABLES_KEY]?.[name];\n}\n\nconst LC_CONFIGURE_HOOKS_KEY = Symbol(\"lc:configure_hooks\");\n\nexport const _getConfigureHooks = () =>\n getContextVariable<ConfigureHook[]>(LC_CONFIGURE_HOOKS_KEY) || [];\n\n/**\n * Register a callback configure hook to automatically add callback handlers to all runs.\n *\n * There are two ways to use this:\n *\n * 1. Using a context variable:\n * - Set `contextVar` to specify the variable name\n * - Use `setContextVariable()` to store your handler instance\n *\n * 2. Using an environment variable:\n * - Set both `envVar` and `handlerClass`\n * - The handler will be instantiated when the env var is set to \"true\".\n *\n * @example\n * ```typescript\n * // Method 1: Using context variable\n * import {\n * registerConfigureHook,\n * setContextVariable\n * } from \"@langchain/core/context\";\n *\n * const tracer = new MyCallbackHandler();\n * registerConfigureHook({\n * contextVar: \"my_tracer\",\n * });\n * setContextVariable(\"my_tracer\", tracer);\n *\n * // ...run code here\n *\n * // Method 2: Using environment variable\n * registerConfigureHook({\n * handlerClass: MyCallbackHandler,\n * envVar: \"MY_TRACER_ENABLED\",\n * });\n * process.env.MY_TRACER_ENABLED = \"true\";\n *\n * // ...run code here\n * ```\n *\n * @param config Configuration object for the hook\n * @param config.contextVar Name of the context variable containing the handler instance\n * @param config.inheritable Whether child runs should inherit this handler\n * @param config.handlerClass Optional callback handler class (required if using envVar)\n * @param config.envVar Optional environment variable name to control handler activation\n */\nexport const registerConfigureHook = (config: ConfigureHook) => {\n if (config.envVar && !config.handlerClass) {\n throw new Error(\n \"If envVar is set, handlerClass must also be set to a non-None value.\"\n );\n }\n setContextVariable(LC_CONFIGURE_HOOKS_KEY, [..._getConfigureHooks(), config]);\n};\n\nexport type ConfigureHook = {\n contextVar?: string;\n inheritable?: boolean;\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n handlerClass?: new (...args: any[]) => BaseCallbackHandler;\n envVar?: string;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,SAAgB,mBAAsB,MAAmB,OAAgB;CAEvE,MAAM,4BAA4BA,gBAAAA,oCAAoC;AACtE,KAAI,8BAA8B,KAAA,EAChC,OAAM,IAAI,MACR,uFACD;CAEH,MAAM,UAAU,0BAA0B,UAAU;CACpD,MAAM,cAAc,EAAE,GAAG,UAAUC,gBAAAA,yBAAyB;AAC5D,aAAY,QAAQ;CACpB,IAAI,WAAW,EAAE;AACjB,MAAA,GAAA,oBAAA,WAAc,QAAQ,CACpB,YAAW,IAAIC,oBAAAA,QAAQ,QAAQ;AAGhC,UAAiBD,gBAAAA,0BAA0B;AAC5C,2BAA0B,UAAU,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqD/C,SAAgB,mBAA4B,MAAkC;CAE5E,MAAM,4BAA4BD,gBAAAA,oCAAoC;AACtE,KAAI,8BAA8B,KAAA,EAChC;AAGF,QADgB,0BAA0B,UAAU,GACnCC,gBAAAA,0BAA0B;;AAG7C,MAAM,yBAAyB,OAAO,qBAAqB;AAE3D,MAAa,2BACX,mBAAoC,uBAAuB,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CnE,MAAa,yBAAyB,WAA0B;AAC9D,KAAI,OAAO,UAAU,CAAC,OAAO,aAC3B,OAAM,IAAI,MACR,uEACD;AAEH,oBAAmB,wBAAwB,CAAC,GAAG,oBAAoB,EAAE,OAAO,CAAC"}
1
+ {"version":3,"file":"context.cjs","names":["getGlobalAsyncLocalStorageInstance","_CONTEXT_VARIABLES_KEY","RunTree"],"sources":["../../../src/singletons/async_local_storage/context.ts"],"sourcesContent":["import { isRunTree, RunTree } from \"langsmith/run_trees\";\nimport { BaseCallbackHandler } from \"../../callbacks/base.js\";\nimport {\n _CONTEXT_VARIABLES_KEY,\n getGlobalAsyncLocalStorageInstance,\n} from \"./globals.js\";\n\n/**\n * Set a context variable. Context variables are scoped to any\n * child runnables called by the current runnable, or globally if set outside\n * of any runnable.\n *\n * @remarks\n * This function is only supported in environments that support AsyncLocalStorage,\n * including Node.js, Deno, and Cloudflare Workers.\n *\n * @example\n * ```ts\n * import { RunnableLambda } from \"@langchain/core/runnables\";\n * import {\n * getContextVariable,\n * setContextVariable\n * } from \"@langchain/core/context\";\n *\n * const nested = RunnableLambda.from(() => {\n * // \"bar\" because it was set by a parent\n * console.log(getContextVariable(\"foo\"));\n *\n * // Override to \"baz\", but only for child runnables\n * setContextVariable(\"foo\", \"baz\");\n *\n * // Now \"baz\", but only for child runnables\n * return getContextVariable(\"foo\");\n * });\n *\n * const runnable = RunnableLambda.from(async () => {\n * // Set a context variable named \"foo\"\n * setContextVariable(\"foo\", \"bar\");\n *\n * const res = await nested.invoke({});\n *\n * // Still \"bar\" since child changes do not affect parents\n * console.log(getContextVariable(\"foo\"));\n *\n * return res;\n * });\n *\n * // undefined, because context variable has not been set yet\n * console.log(getContextVariable(\"foo\"));\n *\n * // Final return value is \"baz\"\n * const result = await runnable.invoke({});\n * ```\n *\n * @param name The name of the context variable.\n * @param value The value to set.\n */\nexport function setContextVariable<T>(name: PropertyKey, value: T): void {\n // Avoid using global singleton due to circuluar dependency issues\n const asyncLocalStorageInstance = getGlobalAsyncLocalStorageInstance();\n if (asyncLocalStorageInstance === undefined) {\n throw new Error(\n `Internal error: Global shared async local storage instance has not been initialized.`\n );\n }\n const runTree = asyncLocalStorageInstance.getStore();\n const contextVars = { ...runTree?.[_CONTEXT_VARIABLES_KEY] };\n contextVars[name] = value;\n let newValue = {};\n if (isRunTree(runTree)) {\n newValue = new RunTree(runTree);\n }\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n (newValue as any)[_CONTEXT_VARIABLES_KEY] = contextVars;\n asyncLocalStorageInstance.enterWith(newValue);\n}\n\n/**\n * Get the value of a previously set context variable. Context variables\n * are scoped to any child runnables called by the current runnable,\n * or globally if set outside of any runnable.\n *\n * @remarks\n * This function is only supported in environments that support AsyncLocalStorage,\n * including Node.js, Deno, and Cloudflare Workers.\n *\n * @example\n * ```ts\n * import { RunnableLambda } from \"@langchain/core/runnables\";\n * import {\n * getContextVariable,\n * setContextVariable\n * } from \"@langchain/core/context\";\n *\n * const nested = RunnableLambda.from(() => {\n * // \"bar\" because it was set by a parent\n * console.log(getContextVariable(\"foo\"));\n *\n * // Override to \"baz\", but only for child runnables\n * setContextVariable(\"foo\", \"baz\");\n *\n * // Now \"baz\", but only for child runnables\n * return getContextVariable(\"foo\");\n * });\n *\n * const runnable = RunnableLambda.from(async () => {\n * // Set a context variable named \"foo\"\n * setContextVariable(\"foo\", \"bar\");\n *\n * const res = await nested.invoke({});\n *\n * // Still \"bar\" since child changes do not affect parents\n * console.log(getContextVariable(\"foo\"));\n *\n * return res;\n * });\n *\n * // undefined, because context variable has not been set yet\n * console.log(getContextVariable(\"foo\"));\n *\n * // Final return value is \"baz\"\n * const result = await runnable.invoke({});\n * ```\n *\n * @param name The name of the context variable.\n */\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getContextVariable<T = any>(name: PropertyKey): T | undefined {\n // Avoid using global singleton due to circuluar dependency issues\n const asyncLocalStorageInstance = getGlobalAsyncLocalStorageInstance();\n if (asyncLocalStorageInstance === undefined) {\n return undefined;\n }\n const runTree = asyncLocalStorageInstance.getStore();\n return runTree?.[_CONTEXT_VARIABLES_KEY]?.[name];\n}\n\nconst LC_CONFIGURE_HOOKS_KEY = Symbol(\"lc:configure_hooks\");\n\nexport const _getConfigureHooks = () =>\n getContextVariable<ConfigureHook[]>(LC_CONFIGURE_HOOKS_KEY) || [];\n\n/**\n * Register a callback configure hook to automatically add callback handlers to all runs.\n *\n * There are two ways to use this:\n *\n * 1. Using a context variable:\n * - Set `contextVar` to specify the variable name\n * - Use `setContextVariable()` to store your handler instance\n *\n * 2. Using an environment variable:\n * - Set both `envVar` and `handlerClass`\n * - The handler will be instantiated when the env var is set to \"true\".\n *\n * @example\n * ```typescript\n * // Method 1: Using context variable\n * import {\n * registerConfigureHook,\n * setContextVariable\n * } from \"@langchain/core/context\";\n *\n * const tracer = new MyCallbackHandler();\n * registerConfigureHook({\n * contextVar: \"my_tracer\",\n * });\n * setContextVariable(\"my_tracer\", tracer);\n *\n * // ...run code here\n *\n * // Method 2: Using environment variable\n * registerConfigureHook({\n * handlerClass: MyCallbackHandler,\n * envVar: \"MY_TRACER_ENABLED\",\n * });\n * process.env.MY_TRACER_ENABLED = \"true\";\n *\n * // ...run code here\n * ```\n *\n * @param config Configuration object for the hook\n * @param config.contextVar Name of the context variable containing the handler instance\n * @param config.inheritable Whether child runs should inherit this handler\n * @param config.handlerClass Optional callback handler class (required if using envVar)\n * @param config.envVar Optional environment variable name to control handler activation\n */\nexport const registerConfigureHook = (config: ConfigureHook) => {\n if (config.envVar && !config.handlerClass) {\n throw new Error(\n \"If envVar is set, handlerClass must also be set to a non-None value.\"\n );\n }\n setContextVariable(LC_CONFIGURE_HOOKS_KEY, [..._getConfigureHooks(), config]);\n};\n\nexport type ConfigureHook = {\n contextVar?: string;\n inheritable?: boolean;\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n handlerClass?: new (...args: any[]) => BaseCallbackHandler;\n envVar?: string;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,SAAgB,mBAAsB,MAAmB,OAAgB;CAEvE,MAAM,4BAA4BA,gBAAAA,oCAAoC;AACtE,KAAI,8BAA8B,KAAA,EAChC,OAAM,IAAI,MACR,uFACD;CAEH,MAAM,UAAU,0BAA0B,UAAU;CACpD,MAAM,cAAc,EAAE,GAAG,UAAUC,gBAAAA,yBAAyB;AAC5D,aAAY,QAAQ;CACpB,IAAI,WAAW,EAAE;AACjB,MAAA,GAAA,oBAAA,WAAc,QAAQ,CACpB,YAAW,IAAIC,oBAAAA,QAAQ,QAAQ;AAGhC,UAAiBD,gBAAAA,0BAA0B;AAC5C,2BAA0B,UAAU,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqD/C,SAAgB,mBAA4B,MAAkC;CAE5E,MAAM,4BAA4BD,gBAAAA,oCAAoC;AACtE,KAAI,8BAA8B,KAAA,EAChC;AAGF,QADgB,0BAA0B,UAC5B,GAAGC,gBAAAA,0BAA0B;;AAG7C,MAAM,yBAAyB,OAAO,qBAAqB;AAE3D,MAAa,2BACX,mBAAoC,uBAAuB,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CnE,MAAa,yBAAyB,WAA0B;AAC9D,KAAI,OAAO,UAAU,CAAC,OAAO,aAC3B,OAAM,IAAI,MACR,uEACD;AAEH,oBAAmB,wBAAwB,CAAC,GAAG,oBAAoB,EAAE,OAAO,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","names":[],"sources":["../../../src/singletons/async_local_storage/context.ts"],"sourcesContent":["import { isRunTree, RunTree } from \"langsmith/run_trees\";\nimport { BaseCallbackHandler } from \"../../callbacks/base.js\";\nimport {\n _CONTEXT_VARIABLES_KEY,\n getGlobalAsyncLocalStorageInstance,\n} from \"./globals.js\";\n\n/**\n * Set a context variable. Context variables are scoped to any\n * child runnables called by the current runnable, or globally if set outside\n * of any runnable.\n *\n * @remarks\n * This function is only supported in environments that support AsyncLocalStorage,\n * including Node.js, Deno, and Cloudflare Workers.\n *\n * @example\n * ```ts\n * import { RunnableLambda } from \"@langchain/core/runnables\";\n * import {\n * getContextVariable,\n * setContextVariable\n * } from \"@langchain/core/context\";\n *\n * const nested = RunnableLambda.from(() => {\n * // \"bar\" because it was set by a parent\n * console.log(getContextVariable(\"foo\"));\n *\n * // Override to \"baz\", but only for child runnables\n * setContextVariable(\"foo\", \"baz\");\n *\n * // Now \"baz\", but only for child runnables\n * return getContextVariable(\"foo\");\n * });\n *\n * const runnable = RunnableLambda.from(async () => {\n * // Set a context variable named \"foo\"\n * setContextVariable(\"foo\", \"bar\");\n *\n * const res = await nested.invoke({});\n *\n * // Still \"bar\" since child changes do not affect parents\n * console.log(getContextVariable(\"foo\"));\n *\n * return res;\n * });\n *\n * // undefined, because context variable has not been set yet\n * console.log(getContextVariable(\"foo\"));\n *\n * // Final return value is \"baz\"\n * const result = await runnable.invoke({});\n * ```\n *\n * @param name The name of the context variable.\n * @param value The value to set.\n */\nexport function setContextVariable<T>(name: PropertyKey, value: T): void {\n // Avoid using global singleton due to circuluar dependency issues\n const asyncLocalStorageInstance = getGlobalAsyncLocalStorageInstance();\n if (asyncLocalStorageInstance === undefined) {\n throw new Error(\n `Internal error: Global shared async local storage instance has not been initialized.`\n );\n }\n const runTree = asyncLocalStorageInstance.getStore();\n const contextVars = { ...runTree?.[_CONTEXT_VARIABLES_KEY] };\n contextVars[name] = value;\n let newValue = {};\n if (isRunTree(runTree)) {\n newValue = new RunTree(runTree);\n }\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n (newValue as any)[_CONTEXT_VARIABLES_KEY] = contextVars;\n asyncLocalStorageInstance.enterWith(newValue);\n}\n\n/**\n * Get the value of a previously set context variable. Context variables\n * are scoped to any child runnables called by the current runnable,\n * or globally if set outside of any runnable.\n *\n * @remarks\n * This function is only supported in environments that support AsyncLocalStorage,\n * including Node.js, Deno, and Cloudflare Workers.\n *\n * @example\n * ```ts\n * import { RunnableLambda } from \"@langchain/core/runnables\";\n * import {\n * getContextVariable,\n * setContextVariable\n * } from \"@langchain/core/context\";\n *\n * const nested = RunnableLambda.from(() => {\n * // \"bar\" because it was set by a parent\n * console.log(getContextVariable(\"foo\"));\n *\n * // Override to \"baz\", but only for child runnables\n * setContextVariable(\"foo\", \"baz\");\n *\n * // Now \"baz\", but only for child runnables\n * return getContextVariable(\"foo\");\n * });\n *\n * const runnable = RunnableLambda.from(async () => {\n * // Set a context variable named \"foo\"\n * setContextVariable(\"foo\", \"bar\");\n *\n * const res = await nested.invoke({});\n *\n * // Still \"bar\" since child changes do not affect parents\n * console.log(getContextVariable(\"foo\"));\n *\n * return res;\n * });\n *\n * // undefined, because context variable has not been set yet\n * console.log(getContextVariable(\"foo\"));\n *\n * // Final return value is \"baz\"\n * const result = await runnable.invoke({});\n * ```\n *\n * @param name The name of the context variable.\n */\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getContextVariable<T = any>(name: PropertyKey): T | undefined {\n // Avoid using global singleton due to circuluar dependency issues\n const asyncLocalStorageInstance = getGlobalAsyncLocalStorageInstance();\n if (asyncLocalStorageInstance === undefined) {\n return undefined;\n }\n const runTree = asyncLocalStorageInstance.getStore();\n return runTree?.[_CONTEXT_VARIABLES_KEY]?.[name];\n}\n\nconst LC_CONFIGURE_HOOKS_KEY = Symbol(\"lc:configure_hooks\");\n\nexport const _getConfigureHooks = () =>\n getContextVariable<ConfigureHook[]>(LC_CONFIGURE_HOOKS_KEY) || [];\n\n/**\n * Register a callback configure hook to automatically add callback handlers to all runs.\n *\n * There are two ways to use this:\n *\n * 1. Using a context variable:\n * - Set `contextVar` to specify the variable name\n * - Use `setContextVariable()` to store your handler instance\n *\n * 2. Using an environment variable:\n * - Set both `envVar` and `handlerClass`\n * - The handler will be instantiated when the env var is set to \"true\".\n *\n * @example\n * ```typescript\n * // Method 1: Using context variable\n * import {\n * registerConfigureHook,\n * setContextVariable\n * } from \"@langchain/core/context\";\n *\n * const tracer = new MyCallbackHandler();\n * registerConfigureHook({\n * contextVar: \"my_tracer\",\n * });\n * setContextVariable(\"my_tracer\", tracer);\n *\n * // ...run code here\n *\n * // Method 2: Using environment variable\n * registerConfigureHook({\n * handlerClass: MyCallbackHandler,\n * envVar: \"MY_TRACER_ENABLED\",\n * });\n * process.env.MY_TRACER_ENABLED = \"true\";\n *\n * // ...run code here\n * ```\n *\n * @param config Configuration object for the hook\n * @param config.contextVar Name of the context variable containing the handler instance\n * @param config.inheritable Whether child runs should inherit this handler\n * @param config.handlerClass Optional callback handler class (required if using envVar)\n * @param config.envVar Optional environment variable name to control handler activation\n */\nexport const registerConfigureHook = (config: ConfigureHook) => {\n if (config.envVar && !config.handlerClass) {\n throw new Error(\n \"If envVar is set, handlerClass must also be set to a non-None value.\"\n );\n }\n setContextVariable(LC_CONFIGURE_HOOKS_KEY, [..._getConfigureHooks(), config]);\n};\n\nexport type ConfigureHook = {\n contextVar?: string;\n inheritable?: boolean;\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n handlerClass?: new (...args: any[]) => BaseCallbackHandler;\n envVar?: string;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,SAAgB,mBAAsB,MAAmB,OAAgB;CAEvE,MAAM,4BAA4B,oCAAoC;AACtE,KAAI,8BAA8B,KAAA,EAChC,OAAM,IAAI,MACR,uFACD;CAEH,MAAM,UAAU,0BAA0B,UAAU;CACpD,MAAM,cAAc,EAAE,GAAG,UAAU,yBAAyB;AAC5D,aAAY,QAAQ;CACpB,IAAI,WAAW,EAAE;AACjB,KAAI,UAAU,QAAQ,CACpB,YAAW,IAAI,QAAQ,QAAQ;AAGhC,UAAiB,0BAA0B;AAC5C,2BAA0B,UAAU,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqD/C,SAAgB,mBAA4B,MAAkC;CAE5E,MAAM,4BAA4B,oCAAoC;AACtE,KAAI,8BAA8B,KAAA,EAChC;AAGF,QADgB,0BAA0B,UAAU,GACnC,0BAA0B;;AAG7C,MAAM,yBAAyB,OAAO,qBAAqB;AAE3D,MAAa,2BACX,mBAAoC,uBAAuB,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CnE,MAAa,yBAAyB,WAA0B;AAC9D,KAAI,OAAO,UAAU,CAAC,OAAO,aAC3B,OAAM,IAAI,MACR,uEACD;AAEH,oBAAmB,wBAAwB,CAAC,GAAG,oBAAoB,EAAE,OAAO,CAAC"}
1
+ {"version":3,"file":"context.js","names":[],"sources":["../../../src/singletons/async_local_storage/context.ts"],"sourcesContent":["import { isRunTree, RunTree } from \"langsmith/run_trees\";\nimport { BaseCallbackHandler } from \"../../callbacks/base.js\";\nimport {\n _CONTEXT_VARIABLES_KEY,\n getGlobalAsyncLocalStorageInstance,\n} from \"./globals.js\";\n\n/**\n * Set a context variable. Context variables are scoped to any\n * child runnables called by the current runnable, or globally if set outside\n * of any runnable.\n *\n * @remarks\n * This function is only supported in environments that support AsyncLocalStorage,\n * including Node.js, Deno, and Cloudflare Workers.\n *\n * @example\n * ```ts\n * import { RunnableLambda } from \"@langchain/core/runnables\";\n * import {\n * getContextVariable,\n * setContextVariable\n * } from \"@langchain/core/context\";\n *\n * const nested = RunnableLambda.from(() => {\n * // \"bar\" because it was set by a parent\n * console.log(getContextVariable(\"foo\"));\n *\n * // Override to \"baz\", but only for child runnables\n * setContextVariable(\"foo\", \"baz\");\n *\n * // Now \"baz\", but only for child runnables\n * return getContextVariable(\"foo\");\n * });\n *\n * const runnable = RunnableLambda.from(async () => {\n * // Set a context variable named \"foo\"\n * setContextVariable(\"foo\", \"bar\");\n *\n * const res = await nested.invoke({});\n *\n * // Still \"bar\" since child changes do not affect parents\n * console.log(getContextVariable(\"foo\"));\n *\n * return res;\n * });\n *\n * // undefined, because context variable has not been set yet\n * console.log(getContextVariable(\"foo\"));\n *\n * // Final return value is \"baz\"\n * const result = await runnable.invoke({});\n * ```\n *\n * @param name The name of the context variable.\n * @param value The value to set.\n */\nexport function setContextVariable<T>(name: PropertyKey, value: T): void {\n // Avoid using global singleton due to circuluar dependency issues\n const asyncLocalStorageInstance = getGlobalAsyncLocalStorageInstance();\n if (asyncLocalStorageInstance === undefined) {\n throw new Error(\n `Internal error: Global shared async local storage instance has not been initialized.`\n );\n }\n const runTree = asyncLocalStorageInstance.getStore();\n const contextVars = { ...runTree?.[_CONTEXT_VARIABLES_KEY] };\n contextVars[name] = value;\n let newValue = {};\n if (isRunTree(runTree)) {\n newValue = new RunTree(runTree);\n }\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n (newValue as any)[_CONTEXT_VARIABLES_KEY] = contextVars;\n asyncLocalStorageInstance.enterWith(newValue);\n}\n\n/**\n * Get the value of a previously set context variable. Context variables\n * are scoped to any child runnables called by the current runnable,\n * or globally if set outside of any runnable.\n *\n * @remarks\n * This function is only supported in environments that support AsyncLocalStorage,\n * including Node.js, Deno, and Cloudflare Workers.\n *\n * @example\n * ```ts\n * import { RunnableLambda } from \"@langchain/core/runnables\";\n * import {\n * getContextVariable,\n * setContextVariable\n * } from \"@langchain/core/context\";\n *\n * const nested = RunnableLambda.from(() => {\n * // \"bar\" because it was set by a parent\n * console.log(getContextVariable(\"foo\"));\n *\n * // Override to \"baz\", but only for child runnables\n * setContextVariable(\"foo\", \"baz\");\n *\n * // Now \"baz\", but only for child runnables\n * return getContextVariable(\"foo\");\n * });\n *\n * const runnable = RunnableLambda.from(async () => {\n * // Set a context variable named \"foo\"\n * setContextVariable(\"foo\", \"bar\");\n *\n * const res = await nested.invoke({});\n *\n * // Still \"bar\" since child changes do not affect parents\n * console.log(getContextVariable(\"foo\"));\n *\n * return res;\n * });\n *\n * // undefined, because context variable has not been set yet\n * console.log(getContextVariable(\"foo\"));\n *\n * // Final return value is \"baz\"\n * const result = await runnable.invoke({});\n * ```\n *\n * @param name The name of the context variable.\n */\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getContextVariable<T = any>(name: PropertyKey): T | undefined {\n // Avoid using global singleton due to circuluar dependency issues\n const asyncLocalStorageInstance = getGlobalAsyncLocalStorageInstance();\n if (asyncLocalStorageInstance === undefined) {\n return undefined;\n }\n const runTree = asyncLocalStorageInstance.getStore();\n return runTree?.[_CONTEXT_VARIABLES_KEY]?.[name];\n}\n\nconst LC_CONFIGURE_HOOKS_KEY = Symbol(\"lc:configure_hooks\");\n\nexport const _getConfigureHooks = () =>\n getContextVariable<ConfigureHook[]>(LC_CONFIGURE_HOOKS_KEY) || [];\n\n/**\n * Register a callback configure hook to automatically add callback handlers to all runs.\n *\n * There are two ways to use this:\n *\n * 1. Using a context variable:\n * - Set `contextVar` to specify the variable name\n * - Use `setContextVariable()` to store your handler instance\n *\n * 2. Using an environment variable:\n * - Set both `envVar` and `handlerClass`\n * - The handler will be instantiated when the env var is set to \"true\".\n *\n * @example\n * ```typescript\n * // Method 1: Using context variable\n * import {\n * registerConfigureHook,\n * setContextVariable\n * } from \"@langchain/core/context\";\n *\n * const tracer = new MyCallbackHandler();\n * registerConfigureHook({\n * contextVar: \"my_tracer\",\n * });\n * setContextVariable(\"my_tracer\", tracer);\n *\n * // ...run code here\n *\n * // Method 2: Using environment variable\n * registerConfigureHook({\n * handlerClass: MyCallbackHandler,\n * envVar: \"MY_TRACER_ENABLED\",\n * });\n * process.env.MY_TRACER_ENABLED = \"true\";\n *\n * // ...run code here\n * ```\n *\n * @param config Configuration object for the hook\n * @param config.contextVar Name of the context variable containing the handler instance\n * @param config.inheritable Whether child runs should inherit this handler\n * @param config.handlerClass Optional callback handler class (required if using envVar)\n * @param config.envVar Optional environment variable name to control handler activation\n */\nexport const registerConfigureHook = (config: ConfigureHook) => {\n if (config.envVar && !config.handlerClass) {\n throw new Error(\n \"If envVar is set, handlerClass must also be set to a non-None value.\"\n );\n }\n setContextVariable(LC_CONFIGURE_HOOKS_KEY, [..._getConfigureHooks(), config]);\n};\n\nexport type ConfigureHook = {\n contextVar?: string;\n inheritable?: boolean;\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n handlerClass?: new (...args: any[]) => BaseCallbackHandler;\n envVar?: string;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,SAAgB,mBAAsB,MAAmB,OAAgB;CAEvE,MAAM,4BAA4B,oCAAoC;AACtE,KAAI,8BAA8B,KAAA,EAChC,OAAM,IAAI,MACR,uFACD;CAEH,MAAM,UAAU,0BAA0B,UAAU;CACpD,MAAM,cAAc,EAAE,GAAG,UAAU,yBAAyB;AAC5D,aAAY,QAAQ;CACpB,IAAI,WAAW,EAAE;AACjB,KAAI,UAAU,QAAQ,CACpB,YAAW,IAAI,QAAQ,QAAQ;AAGhC,UAAiB,0BAA0B;AAC5C,2BAA0B,UAAU,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqD/C,SAAgB,mBAA4B,MAAkC;CAE5E,MAAM,4BAA4B,oCAAoC;AACtE,KAAI,8BAA8B,KAAA,EAChC;AAGF,QADgB,0BAA0B,UAC5B,GAAG,0BAA0B;;AAG7C,MAAM,yBAAyB,OAAO,qBAAqB;AAE3D,MAAa,2BACX,mBAAoC,uBAAuB,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CnE,MAAa,yBAAyB,WAA0B;AAC9D,KAAI,OAAO,UAAU,CAAC,OAAO,aAC3B,OAAM,IAAI,MACR,uEACD;AAEH,oBAAmB,wBAAwB,CAAC,GAAG,oBAAoB,EAAE,OAAO,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["getGlobalAsyncLocalStorageInstance","CallbackManager","RunTree","_CONTEXT_VARIABLES_KEY"],"sources":["../../../src/singletons/async_local_storage/index.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { RunTree } from \"langsmith\";\nimport {\n AsyncLocalStorageInterface,\n getGlobalAsyncLocalStorageInstance,\n setGlobalAsyncLocalStorageInstance,\n _CONTEXT_VARIABLES_KEY,\n} from \"./globals.js\";\nimport { CallbackManager } from \"../../callbacks/manager.js\";\nimport { LangChainTracer } from \"../../tracers/tracer_langchain.js\";\n\nexport class MockAsyncLocalStorage implements AsyncLocalStorageInterface {\n getStore(): any {\n return undefined;\n }\n\n run<T>(_store: any, callback: () => T): T {\n return callback();\n }\n\n enterWith(_store: any) {\n return undefined;\n }\n}\n\nconst mockAsyncLocalStorage = new MockAsyncLocalStorage();\n\nconst LC_CHILD_KEY = Symbol.for(\"lc:child_config\");\n\nclass AsyncLocalStorageProvider {\n getInstance(): AsyncLocalStorageInterface {\n return getGlobalAsyncLocalStorageInstance() ?? mockAsyncLocalStorage;\n }\n\n getRunnableConfig() {\n const storage = this.getInstance();\n // this has the runnable config\n // which means that we should also have an instance of a LangChainTracer\n // with the run map prepopulated\n return storage.getStore()?.extra?.[LC_CHILD_KEY];\n }\n\n runWithConfig<T>(\n config: any,\n callback: () => T,\n avoidCreatingRootRunTree?: boolean\n ): T {\n const callbackManager = CallbackManager._configureSync(\n config?.callbacks,\n undefined,\n config?.tags,\n undefined,\n config?.metadata\n );\n const storage = this.getInstance();\n const previousValue = storage.getStore();\n const parentRunId = callbackManager?.getParentRunId();\n\n const langChainTracer = callbackManager?.handlers?.find(\n (handler) => handler?.name === \"langchain_tracer\"\n ) as LangChainTracer | undefined;\n\n let runTree;\n if (langChainTracer && parentRunId) {\n runTree = langChainTracer.getRunTreeWithTracingConfig(parentRunId);\n } else if (!avoidCreatingRootRunTree) {\n runTree = new RunTree({\n name: \"<runnable_lambda>\",\n tracingEnabled: false,\n });\n }\n\n if (runTree) {\n runTree.extra = { ...runTree.extra, [LC_CHILD_KEY]: config };\n }\n\n if (\n previousValue !== undefined &&\n previousValue[_CONTEXT_VARIABLES_KEY] !== undefined\n ) {\n if (runTree === undefined) {\n runTree = {};\n }\n (runTree as any)[_CONTEXT_VARIABLES_KEY] =\n previousValue[_CONTEXT_VARIABLES_KEY];\n }\n\n return storage.run(runTree, callback);\n }\n\n initializeGlobalInstance(instance: AsyncLocalStorageInterface) {\n if (getGlobalAsyncLocalStorageInstance() === undefined) {\n setGlobalAsyncLocalStorageInstance(instance);\n }\n }\n}\n\nconst AsyncLocalStorageProviderSingleton = new AsyncLocalStorageProvider();\n\nexport { AsyncLocalStorageProviderSingleton, type AsyncLocalStorageInterface };\n"],"mappings":";;;;;AAWA,IAAa,wBAAb,MAAyE;CACvE,WAAgB;CAIhB,IAAO,QAAa,UAAsB;AACxC,SAAO,UAAU;;CAGnB,UAAU,QAAa;;AAKzB,MAAM,wBAAwB,IAAI,uBAAuB;AAEzD,MAAM,eAAe,OAAO,IAAI,kBAAkB;AAElD,IAAM,4BAAN,MAAgC;CAC9B,cAA0C;AACxC,SAAOA,gBAAAA,oCAAoC,IAAI;;CAGjD,oBAAoB;AAKlB,SAJgB,KAAK,aAAa,CAInB,UAAU,EAAE,QAAQ;;CAGrC,cACE,QACA,UACA,0BACG;EACH,MAAM,kBAAkBC,0BAAAA,gBAAgB,eACtC,QAAQ,WACR,KAAA,GACA,QAAQ,MACR,KAAA,GACA,QAAQ,SACT;EACD,MAAM,UAAU,KAAK,aAAa;EAClC,MAAM,gBAAgB,QAAQ,UAAU;EACxC,MAAM,cAAc,iBAAiB,gBAAgB;EAErD,MAAM,kBAAkB,iBAAiB,UAAU,MAChD,YAAY,SAAS,SAAS,mBAChC;EAED,IAAI;AACJ,MAAI,mBAAmB,YACrB,WAAU,gBAAgB,4BAA4B,YAAY;WACzD,CAAC,yBACV,WAAU,IAAIC,UAAAA,QAAQ;GACpB,MAAM;GACN,gBAAgB;GACjB,CAAC;AAGJ,MAAI,QACF,SAAQ,QAAQ;GAAE,GAAG,QAAQ;IAAQ,eAAe;GAAQ;AAG9D,MACE,kBAAkB,KAAA,KAClB,cAAcC,gBAAAA,4BAA4B,KAAA,GAC1C;AACA,OAAI,YAAY,KAAA,EACd,WAAU,EAAE;AAEb,WAAgBA,gBAAAA,0BACf,cAAcA,gBAAAA;;AAGlB,SAAO,QAAQ,IAAI,SAAS,SAAS;;CAGvC,yBAAyB,UAAsC;AAC7D,MAAIH,gBAAAA,oCAAoC,KAAK,KAAA,EAC3C,iBAAA,mCAAmC,SAAS;;;AAKlD,MAAM,qCAAqC,IAAI,2BAA2B"}
1
+ {"version":3,"file":"index.cjs","names":["getGlobalAsyncLocalStorageInstance","CallbackManager","RunTree","_CONTEXT_VARIABLES_KEY"],"sources":["../../../src/singletons/async_local_storage/index.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { RunTree } from \"langsmith\";\nimport {\n AsyncLocalStorageInterface,\n getGlobalAsyncLocalStorageInstance,\n setGlobalAsyncLocalStorageInstance,\n _CONTEXT_VARIABLES_KEY,\n} from \"./globals.js\";\nimport { CallbackManager } from \"../../callbacks/manager.js\";\nimport { LangChainTracer } from \"../../tracers/tracer_langchain.js\";\n\nexport class MockAsyncLocalStorage implements AsyncLocalStorageInterface {\n getStore(): any {\n return undefined;\n }\n\n run<T>(_store: any, callback: () => T): T {\n return callback();\n }\n\n enterWith(_store: any) {\n return undefined;\n }\n}\n\nconst mockAsyncLocalStorage = new MockAsyncLocalStorage();\n\nconst LC_CHILD_KEY = Symbol.for(\"lc:child_config\");\n\nclass AsyncLocalStorageProvider {\n getInstance(): AsyncLocalStorageInterface {\n return getGlobalAsyncLocalStorageInstance() ?? mockAsyncLocalStorage;\n }\n\n getRunnableConfig() {\n const storage = this.getInstance();\n // this has the runnable config\n // which means that we should also have an instance of a LangChainTracer\n // with the run map prepopulated\n return storage.getStore()?.extra?.[LC_CHILD_KEY];\n }\n\n runWithConfig<T>(\n config: any,\n callback: () => T,\n avoidCreatingRootRunTree?: boolean\n ): T {\n const callbackManager = CallbackManager._configureSync(\n config?.callbacks,\n undefined,\n config?.tags,\n undefined,\n config?.metadata\n );\n const storage = this.getInstance();\n const previousValue = storage.getStore();\n const parentRunId = callbackManager?.getParentRunId();\n\n const langChainTracer = callbackManager?.handlers?.find(\n (handler) => handler?.name === \"langchain_tracer\"\n ) as LangChainTracer | undefined;\n\n let runTree;\n if (langChainTracer && parentRunId) {\n runTree = langChainTracer.getRunTreeWithTracingConfig(parentRunId);\n } else if (!avoidCreatingRootRunTree) {\n runTree = new RunTree({\n name: \"<runnable_lambda>\",\n tracingEnabled: false,\n });\n }\n\n if (runTree) {\n runTree.extra = { ...runTree.extra, [LC_CHILD_KEY]: config };\n }\n\n if (\n previousValue !== undefined &&\n previousValue[_CONTEXT_VARIABLES_KEY] !== undefined\n ) {\n if (runTree === undefined) {\n runTree = {};\n }\n (runTree as any)[_CONTEXT_VARIABLES_KEY] =\n previousValue[_CONTEXT_VARIABLES_KEY];\n }\n\n return storage.run(runTree, callback);\n }\n\n initializeGlobalInstance(instance: AsyncLocalStorageInterface) {\n if (getGlobalAsyncLocalStorageInstance() === undefined) {\n setGlobalAsyncLocalStorageInstance(instance);\n }\n }\n}\n\nconst AsyncLocalStorageProviderSingleton = new AsyncLocalStorageProvider();\n\nexport { AsyncLocalStorageProviderSingleton, type AsyncLocalStorageInterface };\n"],"mappings":";;;;;AAWA,IAAa,wBAAb,MAAyE;CACvE,WAAgB;CAIhB,IAAO,QAAa,UAAsB;AACxC,SAAO,UAAU;;CAGnB,UAAU,QAAa;;AAKzB,MAAM,wBAAwB,IAAI,uBAAuB;AAEzD,MAAM,eAAe,OAAO,IAAI,kBAAkB;AAElD,IAAM,4BAAN,MAAgC;CAC9B,cAA0C;AACxC,SAAOA,gBAAAA,oCAAoC,IAAI;;CAGjD,oBAAoB;AAKlB,SAJgB,KAAK,aAIP,CAAC,UAAU,EAAE,QAAQ;;CAGrC,cACE,QACA,UACA,0BACG;EACH,MAAM,kBAAkBC,0BAAAA,gBAAgB,eACtC,QAAQ,WACR,KAAA,GACA,QAAQ,MACR,KAAA,GACA,QAAQ,SACT;EACD,MAAM,UAAU,KAAK,aAAa;EAClC,MAAM,gBAAgB,QAAQ,UAAU;EACxC,MAAM,cAAc,iBAAiB,gBAAgB;EAErD,MAAM,kBAAkB,iBAAiB,UAAU,MAChD,YAAY,SAAS,SAAS,mBAChC;EAED,IAAI;AACJ,MAAI,mBAAmB,YACrB,WAAU,gBAAgB,4BAA4B,YAAY;WACzD,CAAC,yBACV,WAAU,IAAIC,UAAAA,QAAQ;GACpB,MAAM;GACN,gBAAgB;GACjB,CAAC;AAGJ,MAAI,QACF,SAAQ,QAAQ;GAAE,GAAG,QAAQ;IAAQ,eAAe;GAAQ;AAG9D,MACE,kBAAkB,KAAA,KAClB,cAAcC,gBAAAA,4BAA4B,KAAA,GAC1C;AACA,OAAI,YAAY,KAAA,EACd,WAAU,EAAE;AAEb,WAAgBA,gBAAAA,0BACf,cAAcA,gBAAAA;;AAGlB,SAAO,QAAQ,IAAI,SAAS,SAAS;;CAGvC,yBAAyB,UAAsC;AAC7D,MAAIH,gBAAAA,oCAAoC,KAAK,KAAA,EAC3C,iBAAA,mCAAmC,SAAS;;;AAKlD,MAAM,qCAAqC,IAAI,2BAA2B"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/singletons/async_local_storage/index.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { RunTree } from \"langsmith\";\nimport {\n AsyncLocalStorageInterface,\n getGlobalAsyncLocalStorageInstance,\n setGlobalAsyncLocalStorageInstance,\n _CONTEXT_VARIABLES_KEY,\n} from \"./globals.js\";\nimport { CallbackManager } from \"../../callbacks/manager.js\";\nimport { LangChainTracer } from \"../../tracers/tracer_langchain.js\";\n\nexport class MockAsyncLocalStorage implements AsyncLocalStorageInterface {\n getStore(): any {\n return undefined;\n }\n\n run<T>(_store: any, callback: () => T): T {\n return callback();\n }\n\n enterWith(_store: any) {\n return undefined;\n }\n}\n\nconst mockAsyncLocalStorage = new MockAsyncLocalStorage();\n\nconst LC_CHILD_KEY = Symbol.for(\"lc:child_config\");\n\nclass AsyncLocalStorageProvider {\n getInstance(): AsyncLocalStorageInterface {\n return getGlobalAsyncLocalStorageInstance() ?? mockAsyncLocalStorage;\n }\n\n getRunnableConfig() {\n const storage = this.getInstance();\n // this has the runnable config\n // which means that we should also have an instance of a LangChainTracer\n // with the run map prepopulated\n return storage.getStore()?.extra?.[LC_CHILD_KEY];\n }\n\n runWithConfig<T>(\n config: any,\n callback: () => T,\n avoidCreatingRootRunTree?: boolean\n ): T {\n const callbackManager = CallbackManager._configureSync(\n config?.callbacks,\n undefined,\n config?.tags,\n undefined,\n config?.metadata\n );\n const storage = this.getInstance();\n const previousValue = storage.getStore();\n const parentRunId = callbackManager?.getParentRunId();\n\n const langChainTracer = callbackManager?.handlers?.find(\n (handler) => handler?.name === \"langchain_tracer\"\n ) as LangChainTracer | undefined;\n\n let runTree;\n if (langChainTracer && parentRunId) {\n runTree = langChainTracer.getRunTreeWithTracingConfig(parentRunId);\n } else if (!avoidCreatingRootRunTree) {\n runTree = new RunTree({\n name: \"<runnable_lambda>\",\n tracingEnabled: false,\n });\n }\n\n if (runTree) {\n runTree.extra = { ...runTree.extra, [LC_CHILD_KEY]: config };\n }\n\n if (\n previousValue !== undefined &&\n previousValue[_CONTEXT_VARIABLES_KEY] !== undefined\n ) {\n if (runTree === undefined) {\n runTree = {};\n }\n (runTree as any)[_CONTEXT_VARIABLES_KEY] =\n previousValue[_CONTEXT_VARIABLES_KEY];\n }\n\n return storage.run(runTree, callback);\n }\n\n initializeGlobalInstance(instance: AsyncLocalStorageInterface) {\n if (getGlobalAsyncLocalStorageInstance() === undefined) {\n setGlobalAsyncLocalStorageInstance(instance);\n }\n }\n}\n\nconst AsyncLocalStorageProviderSingleton = new AsyncLocalStorageProvider();\n\nexport { AsyncLocalStorageProviderSingleton, type AsyncLocalStorageInterface };\n"],"mappings":";;;;AAWA,IAAa,wBAAb,MAAyE;CACvE,WAAgB;CAIhB,IAAO,QAAa,UAAsB;AACxC,SAAO,UAAU;;CAGnB,UAAU,QAAa;;AAKzB,MAAM,wBAAwB,IAAI,uBAAuB;AAEzD,MAAM,eAAe,OAAO,IAAI,kBAAkB;AAElD,IAAM,4BAAN,MAAgC;CAC9B,cAA0C;AACxC,SAAO,oCAAoC,IAAI;;CAGjD,oBAAoB;AAKlB,SAJgB,KAAK,aAAa,CAInB,UAAU,EAAE,QAAQ;;CAGrC,cACE,QACA,UACA,0BACG;EACH,MAAM,kBAAkB,gBAAgB,eACtC,QAAQ,WACR,KAAA,GACA,QAAQ,MACR,KAAA,GACA,QAAQ,SACT;EACD,MAAM,UAAU,KAAK,aAAa;EAClC,MAAM,gBAAgB,QAAQ,UAAU;EACxC,MAAM,cAAc,iBAAiB,gBAAgB;EAErD,MAAM,kBAAkB,iBAAiB,UAAU,MAChD,YAAY,SAAS,SAAS,mBAChC;EAED,IAAI;AACJ,MAAI,mBAAmB,YACrB,WAAU,gBAAgB,4BAA4B,YAAY;WACzD,CAAC,yBACV,WAAU,IAAI,QAAQ;GACpB,MAAM;GACN,gBAAgB;GACjB,CAAC;AAGJ,MAAI,QACF,SAAQ,QAAQ;GAAE,GAAG,QAAQ;IAAQ,eAAe;GAAQ;AAG9D,MACE,kBAAkB,KAAA,KAClB,cAAc,4BAA4B,KAAA,GAC1C;AACA,OAAI,YAAY,KAAA,EACd,WAAU,EAAE;AAEb,WAAgB,0BACf,cAAc;;AAGlB,SAAO,QAAQ,IAAI,SAAS,SAAS;;CAGvC,yBAAyB,UAAsC;AAC7D,MAAI,oCAAoC,KAAK,KAAA,EAC3C,oCAAmC,SAAS;;;AAKlD,MAAM,qCAAqC,IAAI,2BAA2B"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/singletons/async_local_storage/index.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { RunTree } from \"langsmith\";\nimport {\n AsyncLocalStorageInterface,\n getGlobalAsyncLocalStorageInstance,\n setGlobalAsyncLocalStorageInstance,\n _CONTEXT_VARIABLES_KEY,\n} from \"./globals.js\";\nimport { CallbackManager } from \"../../callbacks/manager.js\";\nimport { LangChainTracer } from \"../../tracers/tracer_langchain.js\";\n\nexport class MockAsyncLocalStorage implements AsyncLocalStorageInterface {\n getStore(): any {\n return undefined;\n }\n\n run<T>(_store: any, callback: () => T): T {\n return callback();\n }\n\n enterWith(_store: any) {\n return undefined;\n }\n}\n\nconst mockAsyncLocalStorage = new MockAsyncLocalStorage();\n\nconst LC_CHILD_KEY = Symbol.for(\"lc:child_config\");\n\nclass AsyncLocalStorageProvider {\n getInstance(): AsyncLocalStorageInterface {\n return getGlobalAsyncLocalStorageInstance() ?? mockAsyncLocalStorage;\n }\n\n getRunnableConfig() {\n const storage = this.getInstance();\n // this has the runnable config\n // which means that we should also have an instance of a LangChainTracer\n // with the run map prepopulated\n return storage.getStore()?.extra?.[LC_CHILD_KEY];\n }\n\n runWithConfig<T>(\n config: any,\n callback: () => T,\n avoidCreatingRootRunTree?: boolean\n ): T {\n const callbackManager = CallbackManager._configureSync(\n config?.callbacks,\n undefined,\n config?.tags,\n undefined,\n config?.metadata\n );\n const storage = this.getInstance();\n const previousValue = storage.getStore();\n const parentRunId = callbackManager?.getParentRunId();\n\n const langChainTracer = callbackManager?.handlers?.find(\n (handler) => handler?.name === \"langchain_tracer\"\n ) as LangChainTracer | undefined;\n\n let runTree;\n if (langChainTracer && parentRunId) {\n runTree = langChainTracer.getRunTreeWithTracingConfig(parentRunId);\n } else if (!avoidCreatingRootRunTree) {\n runTree = new RunTree({\n name: \"<runnable_lambda>\",\n tracingEnabled: false,\n });\n }\n\n if (runTree) {\n runTree.extra = { ...runTree.extra, [LC_CHILD_KEY]: config };\n }\n\n if (\n previousValue !== undefined &&\n previousValue[_CONTEXT_VARIABLES_KEY] !== undefined\n ) {\n if (runTree === undefined) {\n runTree = {};\n }\n (runTree as any)[_CONTEXT_VARIABLES_KEY] =\n previousValue[_CONTEXT_VARIABLES_KEY];\n }\n\n return storage.run(runTree, callback);\n }\n\n initializeGlobalInstance(instance: AsyncLocalStorageInterface) {\n if (getGlobalAsyncLocalStorageInstance() === undefined) {\n setGlobalAsyncLocalStorageInstance(instance);\n }\n }\n}\n\nconst AsyncLocalStorageProviderSingleton = new AsyncLocalStorageProvider();\n\nexport { AsyncLocalStorageProviderSingleton, type AsyncLocalStorageInterface };\n"],"mappings":";;;;AAWA,IAAa,wBAAb,MAAyE;CACvE,WAAgB;CAIhB,IAAO,QAAa,UAAsB;AACxC,SAAO,UAAU;;CAGnB,UAAU,QAAa;;AAKzB,MAAM,wBAAwB,IAAI,uBAAuB;AAEzD,MAAM,eAAe,OAAO,IAAI,kBAAkB;AAElD,IAAM,4BAAN,MAAgC;CAC9B,cAA0C;AACxC,SAAO,oCAAoC,IAAI;;CAGjD,oBAAoB;AAKlB,SAJgB,KAAK,aAIP,CAAC,UAAU,EAAE,QAAQ;;CAGrC,cACE,QACA,UACA,0BACG;EACH,MAAM,kBAAkB,gBAAgB,eACtC,QAAQ,WACR,KAAA,GACA,QAAQ,MACR,KAAA,GACA,QAAQ,SACT;EACD,MAAM,UAAU,KAAK,aAAa;EAClC,MAAM,gBAAgB,QAAQ,UAAU;EACxC,MAAM,cAAc,iBAAiB,gBAAgB;EAErD,MAAM,kBAAkB,iBAAiB,UAAU,MAChD,YAAY,SAAS,SAAS,mBAChC;EAED,IAAI;AACJ,MAAI,mBAAmB,YACrB,WAAU,gBAAgB,4BAA4B,YAAY;WACzD,CAAC,yBACV,WAAU,IAAI,QAAQ;GACpB,MAAM;GACN,gBAAgB;GACjB,CAAC;AAGJ,MAAI,QACF,SAAQ,QAAQ;GAAE,GAAG,QAAQ;IAAQ,eAAe;GAAQ;AAG9D,MACE,kBAAkB,KAAA,KAClB,cAAc,4BAA4B,KAAA,GAC1C;AACA,OAAI,YAAY,KAAA,EACd,WAAU,EAAE;AAEb,WAAgB,0BACf,cAAc;;AAGlB,SAAO,QAAQ,IAAI,SAAS,SAAS;;CAGvC,yBAAyB,UAAsC;AAC7D,MAAI,oCAAoC,KAAK,KAAA,EAC3C,oCAAmC,SAAS;;;AAKlD,MAAM,qCAAqC,IAAI,2BAA2B"}
@@ -1 +1 @@
1
- {"version":3,"file":"fake_model_builder.cjs","names":["BaseChatModel","BaseMessage","RunnableLambda","AIMessage"],"sources":["../../src/testing/fake_model_builder.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { CallbackManagerForLLMRun } from \"../callbacks/manager.js\";\nimport {\n BaseChatModel,\n BaseChatModelCallOptions,\n} from \"../language_models/chat_models.js\";\nimport {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n StructuredOutputMethodParams,\n} from \"../language_models/base.js\";\nimport { BaseMessage, AIMessage } from \"../messages/index.js\";\nimport type { ToolCall } from \"../messages/tool.js\";\nimport type { ChatResult } from \"../outputs.js\";\nimport { Runnable, RunnableLambda } from \"../runnables/base.js\";\nimport { StructuredTool } from \"../tools/index.js\";\nimport type { InteropZodType } from \"../utils/types/zod.js\";\nimport type { ToolSpec } from \"../utils/testing/chat_models.js\";\n\ntype ResponseFactory = (messages: BaseMessage[]) => BaseMessage | Error;\n\ntype QueueEntry =\n | { kind: \"message\"; message: BaseMessage }\n | { kind: \"toolCalls\"; toolCalls: ToolCall[] }\n | { kind: \"error\"; error: Error }\n | { kind: \"factory\"; factory: ResponseFactory };\n\ninterface FakeModelCall {\n messages: BaseMessage[];\n options: any;\n}\n\ninterface FakeModelState {\n callIndex: number;\n calls: FakeModelCall[];\n}\n\nfunction deriveContent(messages: BaseMessage[]): string {\n return messages\n .map((m) => m.text)\n .filter(Boolean)\n .join(\"-\");\n}\n\nlet idCounter = 0;\nfunction nextToolCallId(): string {\n idCounter += 1;\n return `fake_tc_${idCounter}`;\n}\n\n/**\n * A fake chat model for testing, created via {@link fakeModel}.\n *\n * Queue responses with `.respond()` and `.respondWithTools()`, then\n * pass the instance directly wherever a chat model is expected.\n * Responses are consumed in first-in-first-out order — one per `invoke()` call.\n * When all queued responses are consumed, further invocations throw.\n */\nexport class FakeBuiltModel extends BaseChatModel {\n private queue: QueueEntry[] = [];\n\n private _alwaysThrowError: Error | undefined;\n\n private _structuredResponseValue: any;\n\n private _tools: (StructuredTool | ToolSpec)[] = [];\n\n private _state: FakeModelState = { callIndex: 0, calls: [] };\n\n /**\n * All invocations recorded by this model, in order.\n * Each entry contains the `messages` array and `options` that were\n * passed to `invoke()`.\n */\n get calls(): FakeModelCall[] {\n return this._state.calls;\n }\n\n /**\n * The number of times this model has been invoked.\n */\n get callCount(): number {\n return this._state.calls.length;\n }\n\n constructor() {\n super({});\n }\n\n _llmType(): string {\n return \"fake-model-builder\";\n }\n\n _combineLLMOutput() {\n return [];\n }\n\n /**\n * Enqueue a response that the model will return on its next invocation.\n * @param entry A {@link BaseMessage} to return, an `Error` to throw, or\n * a factory `(messages) => BaseMessage | Error` for dynamic responses.\n * @returns `this`, for chaining.\n */\n respond(entry: BaseMessage | Error | ResponseFactory): this {\n if (typeof entry === \"function\") {\n this.queue.push({ kind: \"factory\", factory: entry });\n } else if (BaseMessage.isInstance(entry)) {\n this.queue.push({ kind: \"message\", message: entry });\n } else {\n this.queue.push({ kind: \"error\", error: entry });\n }\n return this;\n }\n\n /**\n * Enqueue an {@link AIMessage} that carries the given tool calls.\n * Content is derived from the input messages at invocation time.\n * @param toolCalls Array of tool calls. Each entry needs `name` and\n * `args`; `id` is optional and auto-generated when omitted.\n * @returns `this`, for chaining.\n */\n respondWithTools(\n toolCalls: Array<{ name: string; args: Record<string, any>; id?: string }>\n ): this {\n this.queue.push({\n kind: \"toolCalls\",\n toolCalls: toolCalls.map((tc) => ({\n name: tc.name,\n args: tc.args,\n id: tc.id ?? nextToolCallId(),\n type: \"tool_call\" as const,\n })),\n });\n return this;\n }\n\n /**\n * Make every invocation throw the given error, regardless of the queue.\n * @param error The error to throw.\n * @returns `this`, for chaining.\n */\n alwaysThrow(error: Error): this {\n this._alwaysThrowError = error;\n return this;\n }\n\n /**\n * Set the value that {@link withStructuredOutput} will resolve to.\n * @param value The structured object to return.\n * @returns `this`, for chaining.\n */\n structuredResponse(value: Record<string, any>): this {\n this._structuredResponseValue = value;\n return this;\n }\n\n /**\n * Bind tools to the model. Returns a new model that shares the same\n * response queue and call history.\n * @param tools The tools to bind, as {@link StructuredTool} instances or\n * plain {@link ToolSpec} objects.\n * @returns A new RunnableBinding with the tools bound.\n */\n bindTools(tools: (StructuredTool | ToolSpec)[]) {\n const merged = [...this._tools, ...tools];\n const next = new FakeBuiltModel();\n next.queue = this.queue;\n next._alwaysThrowError = this._alwaysThrowError;\n next._structuredResponseValue = this._structuredResponseValue;\n next._tools = merged;\n next._state = this._state;\n\n return next.withConfig({} as BaseChatModelCallOptions);\n }\n\n /**\n * Returns a {@link Runnable} that produces the {@link structuredResponse}\n * value. The schema argument is accepted for compatibility but ignored.\n * @param _params Schema or params (ignored).\n * @param _config Options (ignored).\n * @returns A Runnable that resolves to the structured response value.\n */\n withStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n _params:\n | StructuredOutputMethodParams<RunOutput, boolean>\n | InteropZodType<RunOutput>\n | Record<string, any>,\n _config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n > {\n const { _structuredResponseValue } = this;\n return RunnableLambda.from(async () => {\n return _structuredResponseValue as RunOutput;\n }) as Runnable;\n }\n\n async _generate(\n messages: BaseMessage[],\n options?: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n this._state.calls.push({ messages: [...messages], options });\n\n const currentCallIndex = this._state.callIndex;\n this._state.callIndex += 1;\n\n if (this._alwaysThrowError) {\n throw this._alwaysThrowError;\n }\n\n const entry = this.queue[currentCallIndex];\n if (!entry) {\n throw new Error(\n `FakeModel: no response queued for invocation ${currentCallIndex} (${this.queue.length} total queued).`\n );\n }\n\n if (entry.kind === \"error\") {\n throw entry.error;\n }\n\n if (entry.kind === \"factory\") {\n const result = entry.factory(messages);\n if (!BaseMessage.isInstance(result)) {\n throw result;\n }\n return {\n generations: [{ text: \"\", message: result }],\n };\n }\n\n if (entry.kind === \"message\") {\n return {\n generations: [{ text: \"\", message: entry.message }],\n };\n }\n\n const content = deriveContent(messages);\n const message = new AIMessage({\n content,\n id: currentCallIndex.toString(),\n tool_calls:\n entry.toolCalls.length > 0\n ? entry.toolCalls.map((tc) => ({\n ...tc,\n type: \"tool_call\" as const,\n }))\n : undefined,\n });\n\n return {\n generations: [{ text: content, message }],\n llmOutput: {},\n };\n }\n}\n\n/**\n * Creates a new {@link FakeBuiltModel} for testing.\n *\n * Returns a chainable builder — queue responses, then pass the model\n * anywhere a chat model is expected. Responses are consumed in FIFO\n * order, one per `invoke()` call.\n *\n * ## API summary\n *\n * | Method | Description |\n * | --- | --- |\n * | `fakeModel()` | Creates a new fake chat model. Returns a chainable builder. |\n * | `.respond(message)` | Queue an `AIMessage` (or any `BaseMessage`) to return on the next invocation. |\n * | `.respond(error)` | Queue an `Error` to throw on the next invocation. |\n * | `.respond(factory)` | Queue a function `(messages) => BaseMessage \\| Error` for dynamic responses. |\n * | `.respondWithTools(toolCalls)` | Shorthand for `.respond()` with tool calls. Each entry needs `name` and `args`; `id` is optional. |\n * | `.alwaysThrow(error)` | Make every invocation throw this error, regardless of the queue. |\n * | `.structuredResponse(value)` | Set the value returned by `.withStructuredOutput()`. |\n * | `.bindTools(tools)` | Bind tools to the model. Returns a `RunnableBinding` that shares the response queue and call recording. |\n * | `.withStructuredOutput(schema)` | Returns a runnable that produces the `.structuredResponse()` value. |\n * | `.calls` | Array of `{ messages, options }` for every invocation (read-only). |\n * | `.callCount` | Number of times the model has been invoked. |\n *\n * @example\n * ```typescript\n * const model = fakeModel()\n * .respondWithTools([{ name: \"search\", args: { query: \"weather\" } }])\n * .respond(new AIMessage(\"Sunny and warm.\"));\n *\n * const r1 = await model.invoke([new HumanMessage(\"What's the weather?\")]);\n * // r1.tool_calls[0].name === \"search\"\n *\n * const r2 = await model.invoke([new HumanMessage(\"Thanks\")]);\n * // r2.content === \"Sunny and warm.\"\n * ```\n */\nexport function fakeModel(): FakeBuiltModel {\n return new FakeBuiltModel();\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"fake_model_builder.cjs","names":["BaseChatModel","BaseMessage","RunnableLambda","AIMessage"],"sources":["../../src/testing/fake_model_builder.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { CallbackManagerForLLMRun } from \"../callbacks/manager.js\";\nimport {\n BaseChatModel,\n BaseChatModelCallOptions,\n} from \"../language_models/chat_models.js\";\nimport {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n StructuredOutputMethodParams,\n} from \"../language_models/base.js\";\nimport { BaseMessage, AIMessage } from \"../messages/index.js\";\nimport type { ToolCall } from \"../messages/tool.js\";\nimport type { ChatResult } from \"../outputs.js\";\nimport { Runnable, RunnableLambda } from \"../runnables/base.js\";\nimport { StructuredTool } from \"../tools/index.js\";\nimport type { InteropZodType } from \"../utils/types/zod.js\";\nimport type { ToolSpec } from \"../utils/testing/chat_models.js\";\n\ntype ResponseFactory = (messages: BaseMessage[]) => BaseMessage | Error;\n\ntype QueueEntry =\n | { kind: \"message\"; message: BaseMessage }\n | { kind: \"toolCalls\"; toolCalls: ToolCall[] }\n | { kind: \"error\"; error: Error }\n | { kind: \"factory\"; factory: ResponseFactory };\n\ninterface FakeModelCall {\n messages: BaseMessage[];\n options: any;\n}\n\ninterface FakeModelState {\n callIndex: number;\n calls: FakeModelCall[];\n}\n\nfunction deriveContent(messages: BaseMessage[]): string {\n return messages\n .map((m) => m.text)\n .filter(Boolean)\n .join(\"-\");\n}\n\nlet idCounter = 0;\nfunction nextToolCallId(): string {\n idCounter += 1;\n return `fake_tc_${idCounter}`;\n}\n\n/**\n * A fake chat model for testing, created via {@link fakeModel}.\n *\n * Queue responses with `.respond()` and `.respondWithTools()`, then\n * pass the instance directly wherever a chat model is expected.\n * Responses are consumed in first-in-first-out order — one per `invoke()` call.\n * When all queued responses are consumed, further invocations throw.\n */\nexport class FakeBuiltModel extends BaseChatModel {\n private queue: QueueEntry[] = [];\n\n private _alwaysThrowError: Error | undefined;\n\n private _structuredResponseValue: any;\n\n private _tools: (StructuredTool | ToolSpec)[] = [];\n\n private _state: FakeModelState = { callIndex: 0, calls: [] };\n\n /**\n * All invocations recorded by this model, in order.\n * Each entry contains the `messages` array and `options` that were\n * passed to `invoke()`.\n */\n get calls(): FakeModelCall[] {\n return this._state.calls;\n }\n\n /**\n * The number of times this model has been invoked.\n */\n get callCount(): number {\n return this._state.calls.length;\n }\n\n constructor() {\n super({});\n }\n\n _llmType(): string {\n return \"fake-model-builder\";\n }\n\n _combineLLMOutput() {\n return [];\n }\n\n /**\n * Enqueue a response that the model will return on its next invocation.\n * @param entry A {@link BaseMessage} to return, an `Error` to throw, or\n * a factory `(messages) => BaseMessage | Error` for dynamic responses.\n * @returns `this`, for chaining.\n */\n respond(entry: BaseMessage | Error | ResponseFactory): this {\n if (typeof entry === \"function\") {\n this.queue.push({ kind: \"factory\", factory: entry });\n } else if (BaseMessage.isInstance(entry)) {\n this.queue.push({ kind: \"message\", message: entry });\n } else {\n this.queue.push({ kind: \"error\", error: entry });\n }\n return this;\n }\n\n /**\n * Enqueue an {@link AIMessage} that carries the given tool calls.\n * Content is derived from the input messages at invocation time.\n * @param toolCalls Array of tool calls. Each entry needs `name` and\n * `args`; `id` is optional and auto-generated when omitted.\n * @returns `this`, for chaining.\n */\n respondWithTools(\n toolCalls: Array<{ name: string; args: Record<string, any>; id?: string }>\n ): this {\n this.queue.push({\n kind: \"toolCalls\",\n toolCalls: toolCalls.map((tc) => ({\n name: tc.name,\n args: tc.args,\n id: tc.id ?? nextToolCallId(),\n type: \"tool_call\" as const,\n })),\n });\n return this;\n }\n\n /**\n * Make every invocation throw the given error, regardless of the queue.\n * @param error The error to throw.\n * @returns `this`, for chaining.\n */\n alwaysThrow(error: Error): this {\n this._alwaysThrowError = error;\n return this;\n }\n\n /**\n * Set the value that {@link withStructuredOutput} will resolve to.\n * @param value The structured object to return.\n * @returns `this`, for chaining.\n */\n structuredResponse(value: Record<string, any>): this {\n this._structuredResponseValue = value;\n return this;\n }\n\n /**\n * Bind tools to the model. Returns a new model that shares the same\n * response queue and call history.\n * @param tools The tools to bind, as {@link StructuredTool} instances or\n * plain {@link ToolSpec} objects.\n * @returns A new RunnableBinding with the tools bound.\n */\n bindTools(tools: (StructuredTool | ToolSpec)[]) {\n const merged = [...this._tools, ...tools];\n const next = new FakeBuiltModel();\n next.queue = this.queue;\n next._alwaysThrowError = this._alwaysThrowError;\n next._structuredResponseValue = this._structuredResponseValue;\n next._tools = merged;\n next._state = this._state;\n\n return next.withConfig({} as BaseChatModelCallOptions);\n }\n\n /**\n * Returns a {@link Runnable} that produces the {@link structuredResponse}\n * value. The schema argument is accepted for compatibility but ignored.\n * @param _params Schema or params (ignored).\n * @param _config Options (ignored).\n * @returns A Runnable that resolves to the structured response value.\n */\n withStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n _params:\n | StructuredOutputMethodParams<RunOutput, boolean>\n | InteropZodType<RunOutput>\n | Record<string, any>,\n _config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n > {\n const { _structuredResponseValue } = this;\n return RunnableLambda.from(async () => {\n return _structuredResponseValue as RunOutput;\n }) as Runnable;\n }\n\n async _generate(\n messages: BaseMessage[],\n options?: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n this._state.calls.push({ messages: [...messages], options });\n\n const currentCallIndex = this._state.callIndex;\n this._state.callIndex += 1;\n\n if (this._alwaysThrowError) {\n throw this._alwaysThrowError;\n }\n\n const entry = this.queue[currentCallIndex];\n if (!entry) {\n throw new Error(\n `FakeModel: no response queued for invocation ${currentCallIndex} (${this.queue.length} total queued).`\n );\n }\n\n if (entry.kind === \"error\") {\n throw entry.error;\n }\n\n if (entry.kind === \"factory\") {\n const result = entry.factory(messages);\n if (!BaseMessage.isInstance(result)) {\n throw result;\n }\n return {\n generations: [{ text: \"\", message: result }],\n };\n }\n\n if (entry.kind === \"message\") {\n return {\n generations: [{ text: \"\", message: entry.message }],\n };\n }\n\n const content = deriveContent(messages);\n const message = new AIMessage({\n content,\n id: currentCallIndex.toString(),\n tool_calls:\n entry.toolCalls.length > 0\n ? entry.toolCalls.map((tc) => ({\n ...tc,\n type: \"tool_call\" as const,\n }))\n : undefined,\n });\n\n return {\n generations: [{ text: content, message }],\n llmOutput: {},\n };\n }\n}\n\n/**\n * Creates a new {@link FakeBuiltModel} for testing.\n *\n * Returns a chainable builder — queue responses, then pass the model\n * anywhere a chat model is expected. Responses are consumed in FIFO\n * order, one per `invoke()` call.\n *\n * ## API summary\n *\n * | Method | Description |\n * | --- | --- |\n * | `fakeModel()` | Creates a new fake chat model. Returns a chainable builder. |\n * | `.respond(message)` | Queue an `AIMessage` (or any `BaseMessage`) to return on the next invocation. |\n * | `.respond(error)` | Queue an `Error` to throw on the next invocation. |\n * | `.respond(factory)` | Queue a function `(messages) => BaseMessage \\| Error` for dynamic responses. |\n * | `.respondWithTools(toolCalls)` | Shorthand for `.respond()` with tool calls. Each entry needs `name` and `args`; `id` is optional. |\n * | `.alwaysThrow(error)` | Make every invocation throw this error, regardless of the queue. |\n * | `.structuredResponse(value)` | Set the value returned by `.withStructuredOutput()`. |\n * | `.bindTools(tools)` | Bind tools to the model. Returns a `RunnableBinding` that shares the response queue and call recording. |\n * | `.withStructuredOutput(schema)` | Returns a runnable that produces the `.structuredResponse()` value. |\n * | `.calls` | Array of `{ messages, options }` for every invocation (read-only). |\n * | `.callCount` | Number of times the model has been invoked. |\n *\n * @example\n * ```typescript\n * const model = fakeModel()\n * .respondWithTools([{ name: \"search\", args: { query: \"weather\" } }])\n * .respond(new AIMessage(\"Sunny and warm.\"));\n *\n * const r1 = await model.invoke([new HumanMessage(\"What's the weather?\")]);\n * // r1.tool_calls[0].name === \"search\"\n *\n * const r2 = await model.invoke([new HumanMessage(\"Thanks\")]);\n * // r2.content === \"Sunny and warm.\"\n * ```\n */\nexport function fakeModel(): FakeBuiltModel {\n return new FakeBuiltModel();\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"fake_model_builder.js","names":[],"sources":["../../src/testing/fake_model_builder.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { CallbackManagerForLLMRun } from \"../callbacks/manager.js\";\nimport {\n BaseChatModel,\n BaseChatModelCallOptions,\n} from \"../language_models/chat_models.js\";\nimport {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n StructuredOutputMethodParams,\n} from \"../language_models/base.js\";\nimport { BaseMessage, AIMessage } from \"../messages/index.js\";\nimport type { ToolCall } from \"../messages/tool.js\";\nimport type { ChatResult } from \"../outputs.js\";\nimport { Runnable, RunnableLambda } from \"../runnables/base.js\";\nimport { StructuredTool } from \"../tools/index.js\";\nimport type { InteropZodType } from \"../utils/types/zod.js\";\nimport type { ToolSpec } from \"../utils/testing/chat_models.js\";\n\ntype ResponseFactory = (messages: BaseMessage[]) => BaseMessage | Error;\n\ntype QueueEntry =\n | { kind: \"message\"; message: BaseMessage }\n | { kind: \"toolCalls\"; toolCalls: ToolCall[] }\n | { kind: \"error\"; error: Error }\n | { kind: \"factory\"; factory: ResponseFactory };\n\ninterface FakeModelCall {\n messages: BaseMessage[];\n options: any;\n}\n\ninterface FakeModelState {\n callIndex: number;\n calls: FakeModelCall[];\n}\n\nfunction deriveContent(messages: BaseMessage[]): string {\n return messages\n .map((m) => m.text)\n .filter(Boolean)\n .join(\"-\");\n}\n\nlet idCounter = 0;\nfunction nextToolCallId(): string {\n idCounter += 1;\n return `fake_tc_${idCounter}`;\n}\n\n/**\n * A fake chat model for testing, created via {@link fakeModel}.\n *\n * Queue responses with `.respond()` and `.respondWithTools()`, then\n * pass the instance directly wherever a chat model is expected.\n * Responses are consumed in first-in-first-out order — one per `invoke()` call.\n * When all queued responses are consumed, further invocations throw.\n */\nexport class FakeBuiltModel extends BaseChatModel {\n private queue: QueueEntry[] = [];\n\n private _alwaysThrowError: Error | undefined;\n\n private _structuredResponseValue: any;\n\n private _tools: (StructuredTool | ToolSpec)[] = [];\n\n private _state: FakeModelState = { callIndex: 0, calls: [] };\n\n /**\n * All invocations recorded by this model, in order.\n * Each entry contains the `messages` array and `options` that were\n * passed to `invoke()`.\n */\n get calls(): FakeModelCall[] {\n return this._state.calls;\n }\n\n /**\n * The number of times this model has been invoked.\n */\n get callCount(): number {\n return this._state.calls.length;\n }\n\n constructor() {\n super({});\n }\n\n _llmType(): string {\n return \"fake-model-builder\";\n }\n\n _combineLLMOutput() {\n return [];\n }\n\n /**\n * Enqueue a response that the model will return on its next invocation.\n * @param entry A {@link BaseMessage} to return, an `Error` to throw, or\n * a factory `(messages) => BaseMessage | Error` for dynamic responses.\n * @returns `this`, for chaining.\n */\n respond(entry: BaseMessage | Error | ResponseFactory): this {\n if (typeof entry === \"function\") {\n this.queue.push({ kind: \"factory\", factory: entry });\n } else if (BaseMessage.isInstance(entry)) {\n this.queue.push({ kind: \"message\", message: entry });\n } else {\n this.queue.push({ kind: \"error\", error: entry });\n }\n return this;\n }\n\n /**\n * Enqueue an {@link AIMessage} that carries the given tool calls.\n * Content is derived from the input messages at invocation time.\n * @param toolCalls Array of tool calls. Each entry needs `name` and\n * `args`; `id` is optional and auto-generated when omitted.\n * @returns `this`, for chaining.\n */\n respondWithTools(\n toolCalls: Array<{ name: string; args: Record<string, any>; id?: string }>\n ): this {\n this.queue.push({\n kind: \"toolCalls\",\n toolCalls: toolCalls.map((tc) => ({\n name: tc.name,\n args: tc.args,\n id: tc.id ?? nextToolCallId(),\n type: \"tool_call\" as const,\n })),\n });\n return this;\n }\n\n /**\n * Make every invocation throw the given error, regardless of the queue.\n * @param error The error to throw.\n * @returns `this`, for chaining.\n */\n alwaysThrow(error: Error): this {\n this._alwaysThrowError = error;\n return this;\n }\n\n /**\n * Set the value that {@link withStructuredOutput} will resolve to.\n * @param value The structured object to return.\n * @returns `this`, for chaining.\n */\n structuredResponse(value: Record<string, any>): this {\n this._structuredResponseValue = value;\n return this;\n }\n\n /**\n * Bind tools to the model. Returns a new model that shares the same\n * response queue and call history.\n * @param tools The tools to bind, as {@link StructuredTool} instances or\n * plain {@link ToolSpec} objects.\n * @returns A new RunnableBinding with the tools bound.\n */\n bindTools(tools: (StructuredTool | ToolSpec)[]) {\n const merged = [...this._tools, ...tools];\n const next = new FakeBuiltModel();\n next.queue = this.queue;\n next._alwaysThrowError = this._alwaysThrowError;\n next._structuredResponseValue = this._structuredResponseValue;\n next._tools = merged;\n next._state = this._state;\n\n return next.withConfig({} as BaseChatModelCallOptions);\n }\n\n /**\n * Returns a {@link Runnable} that produces the {@link structuredResponse}\n * value. The schema argument is accepted for compatibility but ignored.\n * @param _params Schema or params (ignored).\n * @param _config Options (ignored).\n * @returns A Runnable that resolves to the structured response value.\n */\n withStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n _params:\n | StructuredOutputMethodParams<RunOutput, boolean>\n | InteropZodType<RunOutput>\n | Record<string, any>,\n _config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n > {\n const { _structuredResponseValue } = this;\n return RunnableLambda.from(async () => {\n return _structuredResponseValue as RunOutput;\n }) as Runnable;\n }\n\n async _generate(\n messages: BaseMessage[],\n options?: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n this._state.calls.push({ messages: [...messages], options });\n\n const currentCallIndex = this._state.callIndex;\n this._state.callIndex += 1;\n\n if (this._alwaysThrowError) {\n throw this._alwaysThrowError;\n }\n\n const entry = this.queue[currentCallIndex];\n if (!entry) {\n throw new Error(\n `FakeModel: no response queued for invocation ${currentCallIndex} (${this.queue.length} total queued).`\n );\n }\n\n if (entry.kind === \"error\") {\n throw entry.error;\n }\n\n if (entry.kind === \"factory\") {\n const result = entry.factory(messages);\n if (!BaseMessage.isInstance(result)) {\n throw result;\n }\n return {\n generations: [{ text: \"\", message: result }],\n };\n }\n\n if (entry.kind === \"message\") {\n return {\n generations: [{ text: \"\", message: entry.message }],\n };\n }\n\n const content = deriveContent(messages);\n const message = new AIMessage({\n content,\n id: currentCallIndex.toString(),\n tool_calls:\n entry.toolCalls.length > 0\n ? entry.toolCalls.map((tc) => ({\n ...tc,\n type: \"tool_call\" as const,\n }))\n : undefined,\n });\n\n return {\n generations: [{ text: content, message }],\n llmOutput: {},\n };\n }\n}\n\n/**\n * Creates a new {@link FakeBuiltModel} for testing.\n *\n * Returns a chainable builder — queue responses, then pass the model\n * anywhere a chat model is expected. Responses are consumed in FIFO\n * order, one per `invoke()` call.\n *\n * ## API summary\n *\n * | Method | Description |\n * | --- | --- |\n * | `fakeModel()` | Creates a new fake chat model. Returns a chainable builder. |\n * | `.respond(message)` | Queue an `AIMessage` (or any `BaseMessage`) to return on the next invocation. |\n * | `.respond(error)` | Queue an `Error` to throw on the next invocation. |\n * | `.respond(factory)` | Queue a function `(messages) => BaseMessage \\| Error` for dynamic responses. |\n * | `.respondWithTools(toolCalls)` | Shorthand for `.respond()` with tool calls. Each entry needs `name` and `args`; `id` is optional. |\n * | `.alwaysThrow(error)` | Make every invocation throw this error, regardless of the queue. |\n * | `.structuredResponse(value)` | Set the value returned by `.withStructuredOutput()`. |\n * | `.bindTools(tools)` | Bind tools to the model. Returns a `RunnableBinding` that shares the response queue and call recording. |\n * | `.withStructuredOutput(schema)` | Returns a runnable that produces the `.structuredResponse()` value. |\n * | `.calls` | Array of `{ messages, options }` for every invocation (read-only). |\n * | `.callCount` | Number of times the model has been invoked. |\n *\n * @example\n * ```typescript\n * const model = fakeModel()\n * .respondWithTools([{ name: \"search\", args: { query: \"weather\" } }])\n * .respond(new AIMessage(\"Sunny and warm.\"));\n *\n * const r1 = await model.invoke([new HumanMessage(\"What's the weather?\")]);\n * // r1.tool_calls[0].name === \"search\"\n *\n * const r2 = await model.invoke([new HumanMessage(\"Thanks\")]);\n * // r2.content === \"Sunny and warm.\"\n * ```\n */\nexport function fakeModel(): FakeBuiltModel {\n return new FakeBuiltModel();\n}\n"],"mappings":";;;;;;AAqCA,SAAS,cAAc,UAAiC;AACtD,QAAO,SACJ,KAAK,MAAM,EAAE,KAAK,CAClB,OAAO,QAAQ,CACf,KAAK,IAAI;;AAGd,IAAI,YAAY;AAChB,SAAS,iBAAyB;AAChC,cAAa;AACb,QAAO,WAAW;;;;;;;;;;AAWpB,IAAa,iBAAb,MAAa,uBAAuB,cAAc;CAChD,QAA8B,EAAE;CAEhC;CAEA;CAEA,SAAgD,EAAE;CAElD,SAAiC;EAAE,WAAW;EAAG,OAAO,EAAE;EAAE;;;;;;CAO5D,IAAI,QAAyB;AAC3B,SAAO,KAAK,OAAO;;;;;CAMrB,IAAI,YAAoB;AACtB,SAAO,KAAK,OAAO,MAAM;;CAG3B,cAAc;AACZ,QAAM,EAAE,CAAC;;CAGX,WAAmB;AACjB,SAAO;;CAGT,oBAAoB;AAClB,SAAO,EAAE;;;;;;;;CASX,QAAQ,OAAoD;AAC1D,MAAI,OAAO,UAAU,WACnB,MAAK,MAAM,KAAK;GAAE,MAAM;GAAW,SAAS;GAAO,CAAC;WAC3C,YAAY,WAAW,MAAM,CACtC,MAAK,MAAM,KAAK;GAAE,MAAM;GAAW,SAAS;GAAO,CAAC;MAEpD,MAAK,MAAM,KAAK;GAAE,MAAM;GAAS,OAAO;GAAO,CAAC;AAElD,SAAO;;;;;;;;;CAUT,iBACE,WACM;AACN,OAAK,MAAM,KAAK;GACd,MAAM;GACN,WAAW,UAAU,KAAK,QAAQ;IAChC,MAAM,GAAG;IACT,MAAM,GAAG;IACT,IAAI,GAAG,MAAM,gBAAgB;IAC7B,MAAM;IACP,EAAE;GACJ,CAAC;AACF,SAAO;;;;;;;CAQT,YAAY,OAAoB;AAC9B,OAAK,oBAAoB;AACzB,SAAO;;;;;;;CAQT,mBAAmB,OAAkC;AACnD,OAAK,2BAA2B;AAChC,SAAO;;;;;;;;;CAUT,UAAU,OAAsC;EAC9C,MAAM,SAAS,CAAC,GAAG,KAAK,QAAQ,GAAG,MAAM;EACzC,MAAM,OAAO,IAAI,gBAAgB;AACjC,OAAK,QAAQ,KAAK;AAClB,OAAK,oBAAoB,KAAK;AAC9B,OAAK,2BAA2B,KAAK;AACrC,OAAK,SAAS;AACd,OAAK,SAAS,KAAK;AAEnB,SAAO,KAAK,WAAW,EAAE,CAA6B;;;;;;;;;CAUxD,qBAGE,SAIA,SAMI;EACJ,MAAM,EAAE,6BAA6B;AACrC,SAAO,eAAe,KAAK,YAAY;AACrC,UAAO;IACP;;CAGJ,MAAM,UACJ,UACA,SACA,aACqB;AACrB,OAAK,OAAO,MAAM,KAAK;GAAE,UAAU,CAAC,GAAG,SAAS;GAAE;GAAS,CAAC;EAE5D,MAAM,mBAAmB,KAAK,OAAO;AACrC,OAAK,OAAO,aAAa;AAEzB,MAAI,KAAK,kBACP,OAAM,KAAK;EAGb,MAAM,QAAQ,KAAK,MAAM;AACzB,MAAI,CAAC,MACH,OAAM,IAAI,MACR,gDAAgD,iBAAiB,IAAI,KAAK,MAAM,OAAO,iBACxF;AAGH,MAAI,MAAM,SAAS,QACjB,OAAM,MAAM;AAGd,MAAI,MAAM,SAAS,WAAW;GAC5B,MAAM,SAAS,MAAM,QAAQ,SAAS;AACtC,OAAI,CAAC,YAAY,WAAW,OAAO,CACjC,OAAM;AAER,UAAO,EACL,aAAa,CAAC;IAAE,MAAM;IAAI,SAAS;IAAQ,CAAC,EAC7C;;AAGH,MAAI,MAAM,SAAS,UACjB,QAAO,EACL,aAAa,CAAC;GAAE,MAAM;GAAI,SAAS,MAAM;GAAS,CAAC,EACpD;EAGH,MAAM,UAAU,cAAc,SAAS;AAavC,SAAO;GACL,aAAa,CAAC;IAAE,MAAM;IAAS,SAbjB,IAAI,UAAU;KAC5B;KACA,IAAI,iBAAiB,UAAU;KAC/B,YACE,MAAM,UAAU,SAAS,IACrB,MAAM,UAAU,KAAK,QAAQ;MAC3B,GAAG;MACH,MAAM;MACP,EAAE,GACH,KAAA;KACP,CAAC;IAGwC,CAAC;GACzC,WAAW,EAAE;GACd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCL,SAAgB,YAA4B;AAC1C,QAAO,IAAI,gBAAgB"}
1
+ {"version":3,"file":"fake_model_builder.js","names":[],"sources":["../../src/testing/fake_model_builder.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { CallbackManagerForLLMRun } from \"../callbacks/manager.js\";\nimport {\n BaseChatModel,\n BaseChatModelCallOptions,\n} from \"../language_models/chat_models.js\";\nimport {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n StructuredOutputMethodParams,\n} from \"../language_models/base.js\";\nimport { BaseMessage, AIMessage } from \"../messages/index.js\";\nimport type { ToolCall } from \"../messages/tool.js\";\nimport type { ChatResult } from \"../outputs.js\";\nimport { Runnable, RunnableLambda } from \"../runnables/base.js\";\nimport { StructuredTool } from \"../tools/index.js\";\nimport type { InteropZodType } from \"../utils/types/zod.js\";\nimport type { ToolSpec } from \"../utils/testing/chat_models.js\";\n\ntype ResponseFactory = (messages: BaseMessage[]) => BaseMessage | Error;\n\ntype QueueEntry =\n | { kind: \"message\"; message: BaseMessage }\n | { kind: \"toolCalls\"; toolCalls: ToolCall[] }\n | { kind: \"error\"; error: Error }\n | { kind: \"factory\"; factory: ResponseFactory };\n\ninterface FakeModelCall {\n messages: BaseMessage[];\n options: any;\n}\n\ninterface FakeModelState {\n callIndex: number;\n calls: FakeModelCall[];\n}\n\nfunction deriveContent(messages: BaseMessage[]): string {\n return messages\n .map((m) => m.text)\n .filter(Boolean)\n .join(\"-\");\n}\n\nlet idCounter = 0;\nfunction nextToolCallId(): string {\n idCounter += 1;\n return `fake_tc_${idCounter}`;\n}\n\n/**\n * A fake chat model for testing, created via {@link fakeModel}.\n *\n * Queue responses with `.respond()` and `.respondWithTools()`, then\n * pass the instance directly wherever a chat model is expected.\n * Responses are consumed in first-in-first-out order — one per `invoke()` call.\n * When all queued responses are consumed, further invocations throw.\n */\nexport class FakeBuiltModel extends BaseChatModel {\n private queue: QueueEntry[] = [];\n\n private _alwaysThrowError: Error | undefined;\n\n private _structuredResponseValue: any;\n\n private _tools: (StructuredTool | ToolSpec)[] = [];\n\n private _state: FakeModelState = { callIndex: 0, calls: [] };\n\n /**\n * All invocations recorded by this model, in order.\n * Each entry contains the `messages` array and `options` that were\n * passed to `invoke()`.\n */\n get calls(): FakeModelCall[] {\n return this._state.calls;\n }\n\n /**\n * The number of times this model has been invoked.\n */\n get callCount(): number {\n return this._state.calls.length;\n }\n\n constructor() {\n super({});\n }\n\n _llmType(): string {\n return \"fake-model-builder\";\n }\n\n _combineLLMOutput() {\n return [];\n }\n\n /**\n * Enqueue a response that the model will return on its next invocation.\n * @param entry A {@link BaseMessage} to return, an `Error` to throw, or\n * a factory `(messages) => BaseMessage | Error` for dynamic responses.\n * @returns `this`, for chaining.\n */\n respond(entry: BaseMessage | Error | ResponseFactory): this {\n if (typeof entry === \"function\") {\n this.queue.push({ kind: \"factory\", factory: entry });\n } else if (BaseMessage.isInstance(entry)) {\n this.queue.push({ kind: \"message\", message: entry });\n } else {\n this.queue.push({ kind: \"error\", error: entry });\n }\n return this;\n }\n\n /**\n * Enqueue an {@link AIMessage} that carries the given tool calls.\n * Content is derived from the input messages at invocation time.\n * @param toolCalls Array of tool calls. Each entry needs `name` and\n * `args`; `id` is optional and auto-generated when omitted.\n * @returns `this`, for chaining.\n */\n respondWithTools(\n toolCalls: Array<{ name: string; args: Record<string, any>; id?: string }>\n ): this {\n this.queue.push({\n kind: \"toolCalls\",\n toolCalls: toolCalls.map((tc) => ({\n name: tc.name,\n args: tc.args,\n id: tc.id ?? nextToolCallId(),\n type: \"tool_call\" as const,\n })),\n });\n return this;\n }\n\n /**\n * Make every invocation throw the given error, regardless of the queue.\n * @param error The error to throw.\n * @returns `this`, for chaining.\n */\n alwaysThrow(error: Error): this {\n this._alwaysThrowError = error;\n return this;\n }\n\n /**\n * Set the value that {@link withStructuredOutput} will resolve to.\n * @param value The structured object to return.\n * @returns `this`, for chaining.\n */\n structuredResponse(value: Record<string, any>): this {\n this._structuredResponseValue = value;\n return this;\n }\n\n /**\n * Bind tools to the model. Returns a new model that shares the same\n * response queue and call history.\n * @param tools The tools to bind, as {@link StructuredTool} instances or\n * plain {@link ToolSpec} objects.\n * @returns A new RunnableBinding with the tools bound.\n */\n bindTools(tools: (StructuredTool | ToolSpec)[]) {\n const merged = [...this._tools, ...tools];\n const next = new FakeBuiltModel();\n next.queue = this.queue;\n next._alwaysThrowError = this._alwaysThrowError;\n next._structuredResponseValue = this._structuredResponseValue;\n next._tools = merged;\n next._state = this._state;\n\n return next.withConfig({} as BaseChatModelCallOptions);\n }\n\n /**\n * Returns a {@link Runnable} that produces the {@link structuredResponse}\n * value. The schema argument is accepted for compatibility but ignored.\n * @param _params Schema or params (ignored).\n * @param _config Options (ignored).\n * @returns A Runnable that resolves to the structured response value.\n */\n withStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n _params:\n | StructuredOutputMethodParams<RunOutput, boolean>\n | InteropZodType<RunOutput>\n | Record<string, any>,\n _config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n > {\n const { _structuredResponseValue } = this;\n return RunnableLambda.from(async () => {\n return _structuredResponseValue as RunOutput;\n }) as Runnable;\n }\n\n async _generate(\n messages: BaseMessage[],\n options?: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n this._state.calls.push({ messages: [...messages], options });\n\n const currentCallIndex = this._state.callIndex;\n this._state.callIndex += 1;\n\n if (this._alwaysThrowError) {\n throw this._alwaysThrowError;\n }\n\n const entry = this.queue[currentCallIndex];\n if (!entry) {\n throw new Error(\n `FakeModel: no response queued for invocation ${currentCallIndex} (${this.queue.length} total queued).`\n );\n }\n\n if (entry.kind === \"error\") {\n throw entry.error;\n }\n\n if (entry.kind === \"factory\") {\n const result = entry.factory(messages);\n if (!BaseMessage.isInstance(result)) {\n throw result;\n }\n return {\n generations: [{ text: \"\", message: result }],\n };\n }\n\n if (entry.kind === \"message\") {\n return {\n generations: [{ text: \"\", message: entry.message }],\n };\n }\n\n const content = deriveContent(messages);\n const message = new AIMessage({\n content,\n id: currentCallIndex.toString(),\n tool_calls:\n entry.toolCalls.length > 0\n ? entry.toolCalls.map((tc) => ({\n ...tc,\n type: \"tool_call\" as const,\n }))\n : undefined,\n });\n\n return {\n generations: [{ text: content, message }],\n llmOutput: {},\n };\n }\n}\n\n/**\n * Creates a new {@link FakeBuiltModel} for testing.\n *\n * Returns a chainable builder — queue responses, then pass the model\n * anywhere a chat model is expected. Responses are consumed in FIFO\n * order, one per `invoke()` call.\n *\n * ## API summary\n *\n * | Method | Description |\n * | --- | --- |\n * | `fakeModel()` | Creates a new fake chat model. Returns a chainable builder. |\n * | `.respond(message)` | Queue an `AIMessage` (or any `BaseMessage`) to return on the next invocation. |\n * | `.respond(error)` | Queue an `Error` to throw on the next invocation. |\n * | `.respond(factory)` | Queue a function `(messages) => BaseMessage \\| Error` for dynamic responses. |\n * | `.respondWithTools(toolCalls)` | Shorthand for `.respond()` with tool calls. Each entry needs `name` and `args`; `id` is optional. |\n * | `.alwaysThrow(error)` | Make every invocation throw this error, regardless of the queue. |\n * | `.structuredResponse(value)` | Set the value returned by `.withStructuredOutput()`. |\n * | `.bindTools(tools)` | Bind tools to the model. Returns a `RunnableBinding` that shares the response queue and call recording. |\n * | `.withStructuredOutput(schema)` | Returns a runnable that produces the `.structuredResponse()` value. |\n * | `.calls` | Array of `{ messages, options }` for every invocation (read-only). |\n * | `.callCount` | Number of times the model has been invoked. |\n *\n * @example\n * ```typescript\n * const model = fakeModel()\n * .respondWithTools([{ name: \"search\", args: { query: \"weather\" } }])\n * .respond(new AIMessage(\"Sunny and warm.\"));\n *\n * const r1 = await model.invoke([new HumanMessage(\"What's the weather?\")]);\n * // r1.tool_calls[0].name === \"search\"\n *\n * const r2 = await model.invoke([new HumanMessage(\"Thanks\")]);\n * // r2.content === \"Sunny and warm.\"\n * ```\n */\nexport function fakeModel(): FakeBuiltModel {\n return new FakeBuiltModel();\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"matchers.cjs","names":["BaseMessage","HumanMessage","AIMessage","SystemMessage","ToolMessage"],"sources":["../../src/testing/matchers.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { BaseMessage } from \"../messages/index.js\";\nimport { HumanMessage } from \"../messages/index.js\";\nimport { AIMessage } from \"../messages/index.js\";\nimport { SystemMessage } from \"../messages/index.js\";\nimport { ToolMessage } from \"../messages/index.js\";\n\n/**\n * The `this` context that Vitest and Jest provide to custom matchers\n * via `expect.extend`.\n *\n * Compatible with both frameworks:\n * - https://vitest.dev/guide/extending-matchers.html\n * - https://jestjs.io/docs/expect#expectextendmatchers\n */\ninterface ExpectExtendThis {\n isNot?: boolean;\n equals(a: unknown, b: unknown): boolean;\n utils: {\n matcherHint(name: string, received?: string, expected?: string): string;\n printReceived(value: unknown): string;\n printExpected(value: unknown): string;\n };\n}\n\ninterface ExpectationResult {\n pass: boolean;\n message: () => string;\n actual?: unknown;\n expected?: unknown;\n}\n\nfunction getMessageTypeName(msg: unknown): string {\n if (!BaseMessage.isInstance(msg)) return typeof msg;\n return msg.constructor.name || msg.type;\n}\n\nfunction makeMessageTypeMatcher(\n typeName: string,\n isInstance: (obj: unknown) => boolean\n) {\n return function (\n this: ExpectExtendThis,\n received: unknown,\n expected?: string | Record<string, unknown>\n ): ExpectationResult {\n const { isNot, utils } = this;\n\n const instancePass = isInstance(received);\n if (!instancePass) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: ${isNot ? \"not \" : \"\"}${typeName}\\n` +\n `Received: ${getMessageTypeName(received)}`,\n actual: getMessageTypeName(received),\n expected: typeName,\n };\n }\n\n if (expected === undefined) {\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: not ${typeName}\\n` +\n `Received: ${typeName}`,\n };\n }\n\n const msg = received as BaseMessage;\n if (typeof expected === \"string\") {\n const contentPass = msg.content === expected;\n return {\n pass: contentPass,\n message: () =>\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: ${typeName} with content ${utils.printExpected(expected)}\\n` +\n `Received: ${typeName} with content ${utils.printReceived(msg.content)}`,\n actual: msg.content,\n expected,\n };\n }\n\n const fieldsPass = Object.entries(expected).every(([key, value]) =>\n this.equals((msg as any)[key], value)\n );\n return {\n pass: fieldsPass,\n message: () => {\n const receivedFields: Record<string, unknown> = {};\n for (const key of Object.keys(expected)) {\n receivedFields[key] = (msg as any)[key];\n }\n return (\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: ${typeName} matching ${utils.printExpected(expected)}\\n` +\n `Received: ${typeName} with ${utils.printReceived(receivedFields)}`\n );\n },\n actual: (() => {\n const receivedFields: Record<string, unknown> = {};\n for (const key of Object.keys(expected)) {\n receivedFields[key] = (msg as any)[key];\n }\n return receivedFields;\n })(),\n expected,\n };\n };\n}\n\nexport const toBeHumanMessage = makeMessageTypeMatcher(\n \"HumanMessage\",\n HumanMessage.isInstance\n);\n\nexport const toBeAIMessage = makeMessageTypeMatcher(\n \"AIMessage\",\n AIMessage.isInstance\n);\n\nexport const toBeSystemMessage = makeMessageTypeMatcher(\n \"SystemMessage\",\n SystemMessage.isInstance\n);\n\nexport const toBeToolMessage = makeMessageTypeMatcher(\n \"ToolMessage\",\n ToolMessage.isInstance\n);\n\nexport function toHaveToolCalls(\n this: ExpectExtendThis,\n received: unknown,\n expected: Array<Record<string, unknown>>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!AIMessage.isInstance(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Expected: AIMessage\\n` +\n `Received: ${getMessageTypeName(received)}`,\n };\n }\n\n const actual = received.tool_calls ?? [];\n\n if (actual.length !== expected.length) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Expected ${isNot ? \"not \" : \"\"}${expected.length} tool call(s), received ${actual.length}`,\n actual: actual.length,\n expected: expected.length,\n };\n }\n\n const unmatched = expected.filter(\n (exp) =>\n !actual.some((tc) =>\n Object.entries(exp).every(([key, value]) =>\n this.equals((tc as any)[key], value)\n )\n )\n );\n\n if (unmatched.length > 0) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Could not find matching tool call(s) for:\\n` +\n `${utils.printExpected(unmatched)}\\n` +\n `Received tool calls: ${utils.printReceived(actual.map((tc) => ({ name: tc.name, id: tc.id, args: tc.args })))}`,\n actual: actual.map((tc) => ({ name: tc.name, id: tc.id, args: tc.args })),\n expected,\n };\n }\n\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Expected AIMessage not to have matching tool calls`,\n };\n}\n\nexport function toHaveToolCallCount(\n this: ExpectExtendThis,\n received: unknown,\n expected: number\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!AIMessage.isInstance(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCallCount\")}\\n\\n` +\n `Expected: AIMessage\\n` +\n `Received: ${getMessageTypeName(received)}`,\n };\n }\n\n const actual = received.tool_calls?.length ?? 0;\n const pass = actual === expected;\n\n return {\n pass,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCallCount\")}\\n\\n` +\n `Expected ${isNot ? \"not \" : \"\"}${expected} tool call(s)\\n` +\n `Received: ${actual}`,\n actual,\n expected,\n };\n}\n\nexport function toContainToolCall(\n this: ExpectExtendThis,\n received: unknown,\n expected: Record<string, unknown>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!AIMessage.isInstance(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toContainToolCall\")}\\n\\n` +\n `Expected: AIMessage\\n` +\n `Received: ${getMessageTypeName(received)}`,\n };\n }\n\n const actual = received.tool_calls ?? [];\n const found = actual.some((tc) =>\n Object.entries(expected).every(([key, value]) =>\n this.equals((tc as any)[key], value)\n )\n );\n\n return {\n pass: found,\n message: () =>\n `${utils.matcherHint(\"toContainToolCall\")}\\n\\n` +\n `Expected AIMessage ${isNot ? \"not \" : \"\"}to contain a tool call matching ${utils.printExpected(expected)}\\n` +\n `Received tool calls: ${utils.printReceived(actual.map((tc) => ({ name: tc.name, id: tc.id })))}`,\n actual: actual.map((tc) => ({ name: tc.name, id: tc.id })),\n expected,\n };\n}\n\nexport function toHaveToolMessages(\n this: ExpectExtendThis,\n received: unknown,\n expected: Array<Record<string, unknown>>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!Array.isArray(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Expected an array of messages\\n` +\n `Received: ${typeof received}`,\n };\n }\n\n const toolMessages = (received as BaseMessage[]).filter(\n ToolMessage.isInstance\n );\n\n if (toolMessages.length !== expected.length) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Expected ${isNot ? \"not \" : \"\"}${expected.length} tool message(s), found ${toolMessages.length}`,\n actual: toolMessages.length,\n expected: expected.length,\n };\n }\n\n for (let i = 0; i < expected.length; i++) {\n const match = Object.entries(expected[i]).every(([key, value]) =>\n this.equals((toolMessages[i] as any)[key], value)\n );\n if (!match) {\n return {\n pass: false,\n message: () => {\n const receivedFields: Record<string, unknown> = {};\n for (const key of Object.keys(expected[i])) {\n receivedFields[key] = (toolMessages[i] as any)[key];\n }\n return (\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Tool message at index ${i} did not match:\\n` +\n `Expected: ${utils.printExpected(expected[i])}\\n` +\n `Received: ${utils.printReceived(receivedFields)}`\n );\n },\n actual: toolMessages[i],\n expected: expected[i],\n };\n }\n }\n\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Expected messages not to contain matching tool messages`,\n };\n}\n\nexport function toHaveBeenInterrupted(\n this: ExpectExtendThis,\n received: unknown,\n expectedValue?: unknown\n): ExpectationResult {\n const { isNot, utils } = this;\n\n const result = received as Record<string, any>;\n const interrupts = result?.__interrupt__;\n const hasInterrupt = Array.isArray(interrupts) && interrupts.length > 0;\n\n if (!hasInterrupt) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveBeenInterrupted\")}\\n\\n` +\n `Expected result ${isNot ? \"not \" : \"\"}to have been interrupted\\n` +\n `Received __interrupt__: ${utils.printReceived(interrupts)}`,\n };\n }\n\n if (expectedValue === undefined) {\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveBeenInterrupted\")}\\n\\n` +\n `Expected result not to have been interrupted\\n` +\n `Received ${interrupts.length} interrupt(s)`,\n };\n }\n\n const actualValue = interrupts[0]?.value;\n const valuePass = this.equals(actualValue, expectedValue);\n\n return {\n pass: valuePass,\n message: () =>\n `${utils.matcherHint(\"toHaveBeenInterrupted\")}\\n\\n` +\n `Expected interrupt value: ${utils.printExpected(expectedValue)}\\n` +\n `Received interrupt value: ${utils.printReceived(actualValue)}`,\n actual: actualValue,\n expected: expectedValue,\n };\n}\n\nexport function toHaveStructuredResponse(\n this: ExpectExtendThis,\n received: unknown,\n expected?: Record<string, unknown>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n const result = received as Record<string, any>;\n const structuredResponse = result?.structuredResponse;\n const isDefined = structuredResponse !== undefined;\n\n if (!isDefined) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveStructuredResponse\")}\\n\\n` +\n `Expected result ${isNot ? \"not \" : \"\"}to have a structured response\\n` +\n `Received structuredResponse: undefined`,\n };\n }\n\n if (expected === undefined) {\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveStructuredResponse\")}\\n\\n` +\n `Expected result not to have a structured response`,\n };\n }\n\n const fieldsPass = Object.entries(expected).every(([key, value]) =>\n this.equals(structuredResponse[key], value)\n );\n\n return {\n pass: fieldsPass,\n message: () =>\n `${utils.matcherHint(\"toHaveStructuredResponse\")}\\n\\n` +\n `Expected structured response: ${utils.printExpected(expected)}\\n` +\n `Received structured response: ${utils.printReceived(structuredResponse)}`,\n actual: structuredResponse,\n expected,\n };\n}\n\n/**\n * All matcher functions bundled for convenient use with `expect.extend()`.\n */\nexport const langchainMatchers = {\n toBeHumanMessage,\n toBeAIMessage,\n toBeSystemMessage,\n toBeToolMessage,\n toHaveToolCalls,\n toHaveToolCallCount,\n toContainToolCall,\n toHaveToolMessages,\n toHaveBeenInterrupted,\n toHaveStructuredResponse,\n};\n\nexport interface LangChainMatchers<R = unknown> {\n toBeHumanMessage(expected?: string | { content?: string; id?: string }): R;\n toBeAIMessage(expected?: string | { content?: string; name?: string }): R;\n toBeSystemMessage(\n expected?: string | { content?: string; additional_kwargs?: object }\n ): R;\n toBeToolMessage(\n expected?:\n | string\n | {\n content?: string;\n name?: string;\n status?: string;\n tool_call_id?: string;\n }\n ): R;\n toHaveToolCalls(\n expected: Array<{\n name?: string;\n id?: string;\n args?: Record<string, unknown>;\n }>\n ): R;\n toHaveToolCallCount(expected: number): R;\n toContainToolCall(expected: {\n name?: string;\n id?: string;\n args?: Record<string, unknown>;\n }): R;\n toHaveToolMessages(\n expected: Array<{\n content?: string;\n name?: string;\n status?: string;\n tool_call_id?: string;\n }>\n ): R;\n toHaveBeenInterrupted(expectedValue?: unknown): R;\n toHaveStructuredResponse(expected?: Record<string, unknown>): R;\n}\n\ndeclare module \"vitest\" {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n interface Matchers<T = any> extends LangChainMatchers<T> {}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"matchers.cjs","names":["BaseMessage","HumanMessage","AIMessage","SystemMessage","ToolMessage","result"],"sources":["../../src/testing/matchers.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { BaseMessage } from \"../messages/index.js\";\nimport { HumanMessage } from \"../messages/index.js\";\nimport { AIMessage } from \"../messages/index.js\";\nimport { SystemMessage } from \"../messages/index.js\";\nimport { ToolMessage } from \"../messages/index.js\";\n\n/**\n * The `this` context that Vitest and Jest provide to custom matchers\n * via `expect.extend`.\n *\n * Compatible with both frameworks:\n * - https://vitest.dev/guide/extending-matchers.html\n * - https://jestjs.io/docs/expect#expectextendmatchers\n */\ninterface ExpectExtendThis {\n isNot?: boolean;\n equals(a: unknown, b: unknown): boolean;\n utils: {\n matcherHint(name: string, received?: string, expected?: string): string;\n printReceived(value: unknown): string;\n printExpected(value: unknown): string;\n };\n}\n\ninterface ExpectationResult {\n pass: boolean;\n message: () => string;\n actual?: unknown;\n expected?: unknown;\n}\n\nfunction getMessageTypeName(msg: unknown): string {\n if (!BaseMessage.isInstance(msg)) return typeof msg;\n return msg.constructor.name || msg.type;\n}\n\nfunction makeMessageTypeMatcher(\n typeName: string,\n isInstance: (obj: unknown) => boolean\n) {\n return function (\n this: ExpectExtendThis,\n received: unknown,\n expected?: string | Record<string, unknown>\n ): ExpectationResult {\n const { isNot, utils } = this;\n\n const instancePass = isInstance(received);\n if (!instancePass) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: ${isNot ? \"not \" : \"\"}${typeName}\\n` +\n `Received: ${getMessageTypeName(received)}`,\n actual: getMessageTypeName(received),\n expected: typeName,\n };\n }\n\n if (expected === undefined) {\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: not ${typeName}\\n` +\n `Received: ${typeName}`,\n };\n }\n\n const msg = received as BaseMessage;\n if (typeof expected === \"string\") {\n const contentPass = msg.content === expected;\n return {\n pass: contentPass,\n message: () =>\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: ${typeName} with content ${utils.printExpected(expected)}\\n` +\n `Received: ${typeName} with content ${utils.printReceived(msg.content)}`,\n actual: msg.content,\n expected,\n };\n }\n\n const fieldsPass = Object.entries(expected).every(([key, value]) =>\n this.equals((msg as any)[key], value)\n );\n return {\n pass: fieldsPass,\n message: () => {\n const receivedFields: Record<string, unknown> = {};\n for (const key of Object.keys(expected)) {\n receivedFields[key] = (msg as any)[key];\n }\n return (\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: ${typeName} matching ${utils.printExpected(expected)}\\n` +\n `Received: ${typeName} with ${utils.printReceived(receivedFields)}`\n );\n },\n actual: (() => {\n const receivedFields: Record<string, unknown> = {};\n for (const key of Object.keys(expected)) {\n receivedFields[key] = (msg as any)[key];\n }\n return receivedFields;\n })(),\n expected,\n };\n };\n}\n\nexport const toBeHumanMessage = makeMessageTypeMatcher(\n \"HumanMessage\",\n HumanMessage.isInstance\n);\n\nexport const toBeAIMessage = makeMessageTypeMatcher(\n \"AIMessage\",\n AIMessage.isInstance\n);\n\nexport const toBeSystemMessage = makeMessageTypeMatcher(\n \"SystemMessage\",\n SystemMessage.isInstance\n);\n\nexport const toBeToolMessage = makeMessageTypeMatcher(\n \"ToolMessage\",\n ToolMessage.isInstance\n);\n\nexport function toHaveToolCalls(\n this: ExpectExtendThis,\n received: unknown,\n expected: Array<Record<string, unknown>>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!AIMessage.isInstance(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Expected: AIMessage\\n` +\n `Received: ${getMessageTypeName(received)}`,\n };\n }\n\n const actual = received.tool_calls ?? [];\n\n if (actual.length !== expected.length) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Expected ${isNot ? \"not \" : \"\"}${expected.length} tool call(s), received ${actual.length}`,\n actual: actual.length,\n expected: expected.length,\n };\n }\n\n const unmatched = expected.filter(\n (exp) =>\n !actual.some((tc) =>\n Object.entries(exp).every(([key, value]) =>\n this.equals((tc as any)[key], value)\n )\n )\n );\n\n if (unmatched.length > 0) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Could not find matching tool call(s) for:\\n` +\n `${utils.printExpected(unmatched)}\\n` +\n `Received tool calls: ${utils.printReceived(actual.map((tc) => ({ name: tc.name, id: tc.id, args: tc.args })))}`,\n actual: actual.map((tc) => ({ name: tc.name, id: tc.id, args: tc.args })),\n expected,\n };\n }\n\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Expected AIMessage not to have matching tool calls`,\n };\n}\n\nexport function toHaveToolCallCount(\n this: ExpectExtendThis,\n received: unknown,\n expected: number\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!AIMessage.isInstance(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCallCount\")}\\n\\n` +\n `Expected: AIMessage\\n` +\n `Received: ${getMessageTypeName(received)}`,\n };\n }\n\n const actual = received.tool_calls?.length ?? 0;\n const pass = actual === expected;\n\n return {\n pass,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCallCount\")}\\n\\n` +\n `Expected ${isNot ? \"not \" : \"\"}${expected} tool call(s)\\n` +\n `Received: ${actual}`,\n actual,\n expected,\n };\n}\n\nexport function toContainToolCall(\n this: ExpectExtendThis,\n received: unknown,\n expected: Record<string, unknown>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!AIMessage.isInstance(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toContainToolCall\")}\\n\\n` +\n `Expected: AIMessage\\n` +\n `Received: ${getMessageTypeName(received)}`,\n };\n }\n\n const actual = received.tool_calls ?? [];\n const found = actual.some((tc) =>\n Object.entries(expected).every(([key, value]) =>\n this.equals((tc as any)[key], value)\n )\n );\n\n return {\n pass: found,\n message: () =>\n `${utils.matcherHint(\"toContainToolCall\")}\\n\\n` +\n `Expected AIMessage ${isNot ? \"not \" : \"\"}to contain a tool call matching ${utils.printExpected(expected)}\\n` +\n `Received tool calls: ${utils.printReceived(actual.map((tc) => ({ name: tc.name, id: tc.id })))}`,\n actual: actual.map((tc) => ({ name: tc.name, id: tc.id })),\n expected,\n };\n}\n\nexport function toHaveToolMessages(\n this: ExpectExtendThis,\n received: unknown,\n expected: Array<Record<string, unknown>>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!Array.isArray(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Expected an array of messages\\n` +\n `Received: ${typeof received}`,\n };\n }\n\n const toolMessages = (received as BaseMessage[]).filter(\n ToolMessage.isInstance\n );\n\n if (toolMessages.length !== expected.length) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Expected ${isNot ? \"not \" : \"\"}${expected.length} tool message(s), found ${toolMessages.length}`,\n actual: toolMessages.length,\n expected: expected.length,\n };\n }\n\n for (let i = 0; i < expected.length; i++) {\n const match = Object.entries(expected[i]).every(([key, value]) =>\n this.equals((toolMessages[i] as any)[key], value)\n );\n if (!match) {\n return {\n pass: false,\n message: () => {\n const receivedFields: Record<string, unknown> = {};\n for (const key of Object.keys(expected[i])) {\n receivedFields[key] = (toolMessages[i] as any)[key];\n }\n return (\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Tool message at index ${i} did not match:\\n` +\n `Expected: ${utils.printExpected(expected[i])}\\n` +\n `Received: ${utils.printReceived(receivedFields)}`\n );\n },\n actual: toolMessages[i],\n expected: expected[i],\n };\n }\n }\n\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Expected messages not to contain matching tool messages`,\n };\n}\n\nexport function toHaveBeenInterrupted(\n this: ExpectExtendThis,\n received: unknown,\n expectedValue?: unknown\n): ExpectationResult {\n const { isNot, utils } = this;\n\n const result = received as Record<string, any>;\n const interrupts = result?.__interrupt__;\n const hasInterrupt = Array.isArray(interrupts) && interrupts.length > 0;\n\n if (!hasInterrupt) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveBeenInterrupted\")}\\n\\n` +\n `Expected result ${isNot ? \"not \" : \"\"}to have been interrupted\\n` +\n `Received __interrupt__: ${utils.printReceived(interrupts)}`,\n };\n }\n\n if (expectedValue === undefined) {\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveBeenInterrupted\")}\\n\\n` +\n `Expected result not to have been interrupted\\n` +\n `Received ${interrupts.length} interrupt(s)`,\n };\n }\n\n const actualValue = interrupts[0]?.value;\n const valuePass = this.equals(actualValue, expectedValue);\n\n return {\n pass: valuePass,\n message: () =>\n `${utils.matcherHint(\"toHaveBeenInterrupted\")}\\n\\n` +\n `Expected interrupt value: ${utils.printExpected(expectedValue)}\\n` +\n `Received interrupt value: ${utils.printReceived(actualValue)}`,\n actual: actualValue,\n expected: expectedValue,\n };\n}\n\nexport function toHaveStructuredResponse(\n this: ExpectExtendThis,\n received: unknown,\n expected?: Record<string, unknown>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n const result = received as Record<string, any>;\n const structuredResponse = result?.structuredResponse;\n const isDefined = structuredResponse !== undefined;\n\n if (!isDefined) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveStructuredResponse\")}\\n\\n` +\n `Expected result ${isNot ? \"not \" : \"\"}to have a structured response\\n` +\n `Received structuredResponse: undefined`,\n };\n }\n\n if (expected === undefined) {\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveStructuredResponse\")}\\n\\n` +\n `Expected result not to have a structured response`,\n };\n }\n\n const fieldsPass = Object.entries(expected).every(([key, value]) =>\n this.equals(structuredResponse[key], value)\n );\n\n return {\n pass: fieldsPass,\n message: () =>\n `${utils.matcherHint(\"toHaveStructuredResponse\")}\\n\\n` +\n `Expected structured response: ${utils.printExpected(expected)}\\n` +\n `Received structured response: ${utils.printReceived(structuredResponse)}`,\n actual: structuredResponse,\n expected,\n };\n}\n\n/**\n * All matcher functions bundled for convenient use with `expect.extend()`.\n */\nexport const langchainMatchers = {\n toBeHumanMessage,\n toBeAIMessage,\n toBeSystemMessage,\n toBeToolMessage,\n toHaveToolCalls,\n toHaveToolCallCount,\n toContainToolCall,\n toHaveToolMessages,\n toHaveBeenInterrupted,\n toHaveStructuredResponse,\n};\n\nexport interface LangChainMatchers<R = unknown> {\n toBeHumanMessage(expected?: string | { content?: string; id?: string }): R;\n toBeAIMessage(expected?: string | { content?: string; name?: string }): R;\n toBeSystemMessage(\n expected?: string | { content?: string; additional_kwargs?: object }\n ): R;\n toBeToolMessage(\n expected?:\n | string\n | {\n content?: string;\n name?: string;\n status?: string;\n tool_call_id?: string;\n }\n ): R;\n toHaveToolCalls(\n expected: Array<{\n name?: string;\n id?: string;\n args?: Record<string, unknown>;\n }>\n ): R;\n toHaveToolCallCount(expected: number): R;\n toContainToolCall(expected: {\n name?: string;\n id?: string;\n args?: Record<string, unknown>;\n }): R;\n toHaveToolMessages(\n expected: Array<{\n content?: string;\n name?: string;\n status?: string;\n tool_call_id?: string;\n }>\n ): R;\n toHaveBeenInterrupted(expectedValue?: unknown): R;\n toHaveStructuredResponse(expected?: Record<string, unknown>): R;\n}\n\ndeclare module \"vitest\" {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n interface Matchers<T = any> extends LangChainMatchers<T> {}\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"matchers.js","names":[],"sources":["../../src/testing/matchers.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { BaseMessage } from \"../messages/index.js\";\nimport { HumanMessage } from \"../messages/index.js\";\nimport { AIMessage } from \"../messages/index.js\";\nimport { SystemMessage } from \"../messages/index.js\";\nimport { ToolMessage } from \"../messages/index.js\";\n\n/**\n * The `this` context that Vitest and Jest provide to custom matchers\n * via `expect.extend`.\n *\n * Compatible with both frameworks:\n * - https://vitest.dev/guide/extending-matchers.html\n * - https://jestjs.io/docs/expect#expectextendmatchers\n */\ninterface ExpectExtendThis {\n isNot?: boolean;\n equals(a: unknown, b: unknown): boolean;\n utils: {\n matcherHint(name: string, received?: string, expected?: string): string;\n printReceived(value: unknown): string;\n printExpected(value: unknown): string;\n };\n}\n\ninterface ExpectationResult {\n pass: boolean;\n message: () => string;\n actual?: unknown;\n expected?: unknown;\n}\n\nfunction getMessageTypeName(msg: unknown): string {\n if (!BaseMessage.isInstance(msg)) return typeof msg;\n return msg.constructor.name || msg.type;\n}\n\nfunction makeMessageTypeMatcher(\n typeName: string,\n isInstance: (obj: unknown) => boolean\n) {\n return function (\n this: ExpectExtendThis,\n received: unknown,\n expected?: string | Record<string, unknown>\n ): ExpectationResult {\n const { isNot, utils } = this;\n\n const instancePass = isInstance(received);\n if (!instancePass) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: ${isNot ? \"not \" : \"\"}${typeName}\\n` +\n `Received: ${getMessageTypeName(received)}`,\n actual: getMessageTypeName(received),\n expected: typeName,\n };\n }\n\n if (expected === undefined) {\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: not ${typeName}\\n` +\n `Received: ${typeName}`,\n };\n }\n\n const msg = received as BaseMessage;\n if (typeof expected === \"string\") {\n const contentPass = msg.content === expected;\n return {\n pass: contentPass,\n message: () =>\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: ${typeName} with content ${utils.printExpected(expected)}\\n` +\n `Received: ${typeName} with content ${utils.printReceived(msg.content)}`,\n actual: msg.content,\n expected,\n };\n }\n\n const fieldsPass = Object.entries(expected).every(([key, value]) =>\n this.equals((msg as any)[key], value)\n );\n return {\n pass: fieldsPass,\n message: () => {\n const receivedFields: Record<string, unknown> = {};\n for (const key of Object.keys(expected)) {\n receivedFields[key] = (msg as any)[key];\n }\n return (\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: ${typeName} matching ${utils.printExpected(expected)}\\n` +\n `Received: ${typeName} with ${utils.printReceived(receivedFields)}`\n );\n },\n actual: (() => {\n const receivedFields: Record<string, unknown> = {};\n for (const key of Object.keys(expected)) {\n receivedFields[key] = (msg as any)[key];\n }\n return receivedFields;\n })(),\n expected,\n };\n };\n}\n\nexport const toBeHumanMessage = makeMessageTypeMatcher(\n \"HumanMessage\",\n HumanMessage.isInstance\n);\n\nexport const toBeAIMessage = makeMessageTypeMatcher(\n \"AIMessage\",\n AIMessage.isInstance\n);\n\nexport const toBeSystemMessage = makeMessageTypeMatcher(\n \"SystemMessage\",\n SystemMessage.isInstance\n);\n\nexport const toBeToolMessage = makeMessageTypeMatcher(\n \"ToolMessage\",\n ToolMessage.isInstance\n);\n\nexport function toHaveToolCalls(\n this: ExpectExtendThis,\n received: unknown,\n expected: Array<Record<string, unknown>>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!AIMessage.isInstance(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Expected: AIMessage\\n` +\n `Received: ${getMessageTypeName(received)}`,\n };\n }\n\n const actual = received.tool_calls ?? [];\n\n if (actual.length !== expected.length) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Expected ${isNot ? \"not \" : \"\"}${expected.length} tool call(s), received ${actual.length}`,\n actual: actual.length,\n expected: expected.length,\n };\n }\n\n const unmatched = expected.filter(\n (exp) =>\n !actual.some((tc) =>\n Object.entries(exp).every(([key, value]) =>\n this.equals((tc as any)[key], value)\n )\n )\n );\n\n if (unmatched.length > 0) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Could not find matching tool call(s) for:\\n` +\n `${utils.printExpected(unmatched)}\\n` +\n `Received tool calls: ${utils.printReceived(actual.map((tc) => ({ name: tc.name, id: tc.id, args: tc.args })))}`,\n actual: actual.map((tc) => ({ name: tc.name, id: tc.id, args: tc.args })),\n expected,\n };\n }\n\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Expected AIMessage not to have matching tool calls`,\n };\n}\n\nexport function toHaveToolCallCount(\n this: ExpectExtendThis,\n received: unknown,\n expected: number\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!AIMessage.isInstance(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCallCount\")}\\n\\n` +\n `Expected: AIMessage\\n` +\n `Received: ${getMessageTypeName(received)}`,\n };\n }\n\n const actual = received.tool_calls?.length ?? 0;\n const pass = actual === expected;\n\n return {\n pass,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCallCount\")}\\n\\n` +\n `Expected ${isNot ? \"not \" : \"\"}${expected} tool call(s)\\n` +\n `Received: ${actual}`,\n actual,\n expected,\n };\n}\n\nexport function toContainToolCall(\n this: ExpectExtendThis,\n received: unknown,\n expected: Record<string, unknown>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!AIMessage.isInstance(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toContainToolCall\")}\\n\\n` +\n `Expected: AIMessage\\n` +\n `Received: ${getMessageTypeName(received)}`,\n };\n }\n\n const actual = received.tool_calls ?? [];\n const found = actual.some((tc) =>\n Object.entries(expected).every(([key, value]) =>\n this.equals((tc as any)[key], value)\n )\n );\n\n return {\n pass: found,\n message: () =>\n `${utils.matcherHint(\"toContainToolCall\")}\\n\\n` +\n `Expected AIMessage ${isNot ? \"not \" : \"\"}to contain a tool call matching ${utils.printExpected(expected)}\\n` +\n `Received tool calls: ${utils.printReceived(actual.map((tc) => ({ name: tc.name, id: tc.id })))}`,\n actual: actual.map((tc) => ({ name: tc.name, id: tc.id })),\n expected,\n };\n}\n\nexport function toHaveToolMessages(\n this: ExpectExtendThis,\n received: unknown,\n expected: Array<Record<string, unknown>>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!Array.isArray(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Expected an array of messages\\n` +\n `Received: ${typeof received}`,\n };\n }\n\n const toolMessages = (received as BaseMessage[]).filter(\n ToolMessage.isInstance\n );\n\n if (toolMessages.length !== expected.length) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Expected ${isNot ? \"not \" : \"\"}${expected.length} tool message(s), found ${toolMessages.length}`,\n actual: toolMessages.length,\n expected: expected.length,\n };\n }\n\n for (let i = 0; i < expected.length; i++) {\n const match = Object.entries(expected[i]).every(([key, value]) =>\n this.equals((toolMessages[i] as any)[key], value)\n );\n if (!match) {\n return {\n pass: false,\n message: () => {\n const receivedFields: Record<string, unknown> = {};\n for (const key of Object.keys(expected[i])) {\n receivedFields[key] = (toolMessages[i] as any)[key];\n }\n return (\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Tool message at index ${i} did not match:\\n` +\n `Expected: ${utils.printExpected(expected[i])}\\n` +\n `Received: ${utils.printReceived(receivedFields)}`\n );\n },\n actual: toolMessages[i],\n expected: expected[i],\n };\n }\n }\n\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Expected messages not to contain matching tool messages`,\n };\n}\n\nexport function toHaveBeenInterrupted(\n this: ExpectExtendThis,\n received: unknown,\n expectedValue?: unknown\n): ExpectationResult {\n const { isNot, utils } = this;\n\n const result = received as Record<string, any>;\n const interrupts = result?.__interrupt__;\n const hasInterrupt = Array.isArray(interrupts) && interrupts.length > 0;\n\n if (!hasInterrupt) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveBeenInterrupted\")}\\n\\n` +\n `Expected result ${isNot ? \"not \" : \"\"}to have been interrupted\\n` +\n `Received __interrupt__: ${utils.printReceived(interrupts)}`,\n };\n }\n\n if (expectedValue === undefined) {\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveBeenInterrupted\")}\\n\\n` +\n `Expected result not to have been interrupted\\n` +\n `Received ${interrupts.length} interrupt(s)`,\n };\n }\n\n const actualValue = interrupts[0]?.value;\n const valuePass = this.equals(actualValue, expectedValue);\n\n return {\n pass: valuePass,\n message: () =>\n `${utils.matcherHint(\"toHaveBeenInterrupted\")}\\n\\n` +\n `Expected interrupt value: ${utils.printExpected(expectedValue)}\\n` +\n `Received interrupt value: ${utils.printReceived(actualValue)}`,\n actual: actualValue,\n expected: expectedValue,\n };\n}\n\nexport function toHaveStructuredResponse(\n this: ExpectExtendThis,\n received: unknown,\n expected?: Record<string, unknown>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n const result = received as Record<string, any>;\n const structuredResponse = result?.structuredResponse;\n const isDefined = structuredResponse !== undefined;\n\n if (!isDefined) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveStructuredResponse\")}\\n\\n` +\n `Expected result ${isNot ? \"not \" : \"\"}to have a structured response\\n` +\n `Received structuredResponse: undefined`,\n };\n }\n\n if (expected === undefined) {\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveStructuredResponse\")}\\n\\n` +\n `Expected result not to have a structured response`,\n };\n }\n\n const fieldsPass = Object.entries(expected).every(([key, value]) =>\n this.equals(structuredResponse[key], value)\n );\n\n return {\n pass: fieldsPass,\n message: () =>\n `${utils.matcherHint(\"toHaveStructuredResponse\")}\\n\\n` +\n `Expected structured response: ${utils.printExpected(expected)}\\n` +\n `Received structured response: ${utils.printReceived(structuredResponse)}`,\n actual: structuredResponse,\n expected,\n };\n}\n\n/**\n * All matcher functions bundled for convenient use with `expect.extend()`.\n */\nexport const langchainMatchers = {\n toBeHumanMessage,\n toBeAIMessage,\n toBeSystemMessage,\n toBeToolMessage,\n toHaveToolCalls,\n toHaveToolCallCount,\n toContainToolCall,\n toHaveToolMessages,\n toHaveBeenInterrupted,\n toHaveStructuredResponse,\n};\n\nexport interface LangChainMatchers<R = unknown> {\n toBeHumanMessage(expected?: string | { content?: string; id?: string }): R;\n toBeAIMessage(expected?: string | { content?: string; name?: string }): R;\n toBeSystemMessage(\n expected?: string | { content?: string; additional_kwargs?: object }\n ): R;\n toBeToolMessage(\n expected?:\n | string\n | {\n content?: string;\n name?: string;\n status?: string;\n tool_call_id?: string;\n }\n ): R;\n toHaveToolCalls(\n expected: Array<{\n name?: string;\n id?: string;\n args?: Record<string, unknown>;\n }>\n ): R;\n toHaveToolCallCount(expected: number): R;\n toContainToolCall(expected: {\n name?: string;\n id?: string;\n args?: Record<string, unknown>;\n }): R;\n toHaveToolMessages(\n expected: Array<{\n content?: string;\n name?: string;\n status?: string;\n tool_call_id?: string;\n }>\n ): R;\n toHaveBeenInterrupted(expectedValue?: unknown): R;\n toHaveStructuredResponse(expected?: Record<string, unknown>): R;\n}\n\ndeclare module \"vitest\" {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n interface Matchers<T = any> extends LangChainMatchers<T> {}\n}\n"],"mappings":";;;;;;;AAgCA,SAAS,mBAAmB,KAAsB;AAChD,KAAI,CAAC,YAAY,WAAW,IAAI,CAAE,QAAO,OAAO;AAChD,QAAO,IAAI,YAAY,QAAQ,IAAI;;AAGrC,SAAS,uBACP,UACA,YACA;AACA,QAAO,SAEL,UACA,UACmB;EACnB,MAAM,EAAE,OAAO,UAAU;AAGzB,MAAI,CADiB,WAAW,SAAS,CAEvC,QAAO;GACL,MAAM;GACN,eACE,GAAG,MAAM,YAAY,OAAO,YAAY,KAAA,GAAW,KAAA,EAAU,CAAC,gBACjD,QAAQ,SAAS,KAAK,SAAS,cAC/B,mBAAmB,SAAS;GAC3C,QAAQ,mBAAmB,SAAS;GACpC,UAAU;GACX;AAGH,MAAI,aAAa,KAAA,EACf,QAAO;GACL,MAAM;GACN,eACE,GAAG,MAAM,YAAY,OAAO,YAAY,KAAA,GAAW,KAAA,EAAU,CAAC,oBAC7C,SAAS,cACb;GAChB;EAGH,MAAM,MAAM;AACZ,MAAI,OAAO,aAAa,SAEtB,QAAO;GACL,MAFkB,IAAI,YAAY;GAGlC,eACE,GAAG,MAAM,YAAY,OAAO,YAAY,KAAA,GAAW,KAAA,EAAU,CAAC,gBACjD,SAAS,gBAAgB,MAAM,cAAc,SAAS,CAAC,cACvD,SAAS,gBAAgB,MAAM,cAAc,IAAI,QAAQ;GACxE,QAAQ,IAAI;GACZ;GACD;AAMH,SAAO;GACL,MAJiB,OAAO,QAAQ,SAAS,CAAC,OAAO,CAAC,KAAK,WACvD,KAAK,OAAQ,IAAY,MAAM,MAAM,CACtC;GAGC,eAAe;IACb,MAAM,iBAA0C,EAAE;AAClD,SAAK,MAAM,OAAO,OAAO,KAAK,SAAS,CACrC,gBAAe,OAAQ,IAAY;AAErC,WACE,GAAG,MAAM,YAAY,OAAO,YAAY,KAAA,GAAW,KAAA,EAAU,CAAC,gBACjD,SAAS,YAAY,MAAM,cAAc,SAAS,CAAC,cACnD,SAAS,QAAQ,MAAM,cAAc,eAAe;;GAGrE,eAAe;IACb,MAAM,iBAA0C,EAAE;AAClD,SAAK,MAAM,OAAO,OAAO,KAAK,SAAS,CACrC,gBAAe,OAAQ,IAAY;AAErC,WAAO;OACL;GACJ;GACD;;;AAIL,MAAa,mBAAmB,uBAC9B,gBACA,aAAa,WACd;AAED,MAAa,gBAAgB,uBAC3B,aACA,UAAU,WACX;AAED,MAAa,oBAAoB,uBAC/B,iBACA,cAAc,WACf;AAED,MAAa,kBAAkB,uBAC7B,eACA,YAAY,WACb;AAED,SAAgB,gBAEd,UACA,UACmB;CACnB,MAAM,EAAE,OAAO,UAAU;AAEzB,KAAI,CAAC,UAAU,WAAW,SAAS,CACjC,QAAO;EACL,MAAM;EACN,eACE,GAAG,MAAM,YAAY,kBAAkB,CAAC,qCAE3B,mBAAmB,SAAS;EAC5C;CAGH,MAAM,SAAS,SAAS,cAAc,EAAE;AAExC,KAAI,OAAO,WAAW,SAAS,OAC7B,QAAO;EACL,MAAM;EACN,eACE,GAAG,MAAM,YAAY,kBAAkB,CAAC,eAC5B,QAAQ,SAAS,KAAK,SAAS,OAAO,0BAA0B,OAAO;EACrF,QAAQ,OAAO;EACf,UAAU,SAAS;EACpB;CAGH,MAAM,YAAY,SAAS,QACxB,QACC,CAAC,OAAO,MAAM,OACZ,OAAO,QAAQ,IAAI,CAAC,OAAO,CAAC,KAAK,WAC/B,KAAK,OAAQ,GAAW,MAAM,MAAM,CACrC,CACF,CACJ;AAED,KAAI,UAAU,SAAS,EACrB,QAAO;EACL,MAAM;EACN,eACE,GAAG,MAAM,YAAY,kBAAkB,CAAC,iDAErC,MAAM,cAAc,UAAU,CAAC,yBACV,MAAM,cAAc,OAAO,KAAK,QAAQ;GAAE,MAAM,GAAG;GAAM,IAAI,GAAG;GAAI,MAAM,GAAG;GAAM,EAAE,CAAC;EAChH,QAAQ,OAAO,KAAK,QAAQ;GAAE,MAAM,GAAG;GAAM,IAAI,GAAG;GAAI,MAAM,GAAG;GAAM,EAAE;EACzE;EACD;AAGH,QAAO;EACL,MAAM;EACN,eACE,GAAG,MAAM,YAAY,kBAAkB,CAAC;EAE3C;;AAGH,SAAgB,oBAEd,UACA,UACmB;CACnB,MAAM,EAAE,OAAO,UAAU;AAEzB,KAAI,CAAC,UAAU,WAAW,SAAS,CACjC,QAAO;EACL,MAAM;EACN,eACE,GAAG,MAAM,YAAY,sBAAsB,CAAC,qCAE/B,mBAAmB,SAAS;EAC5C;CAGH,MAAM,SAAS,SAAS,YAAY,UAAU;AAG9C,QAAO;EACL,MAHW,WAAW;EAItB,eACE,GAAG,MAAM,YAAY,sBAAsB,CAAC,eAChC,QAAQ,SAAS,KAAK,SAAS,2BAC9B;EACf;EACA;EACD;;AAGH,SAAgB,kBAEd,UACA,UACmB;CACnB,MAAM,EAAE,OAAO,UAAU;AAEzB,KAAI,CAAC,UAAU,WAAW,SAAS,CACjC,QAAO;EACL,MAAM;EACN,eACE,GAAG,MAAM,YAAY,oBAAoB,CAAC,qCAE7B,mBAAmB,SAAS;EAC5C;CAGH,MAAM,SAAS,SAAS,cAAc,EAAE;AAOxC,QAAO;EACL,MAPY,OAAO,MAAM,OACzB,OAAO,QAAQ,SAAS,CAAC,OAAO,CAAC,KAAK,WACpC,KAAK,OAAQ,GAAW,MAAM,MAAM,CACrC,CACF;EAIC,eACE,GAAG,MAAM,YAAY,oBAAoB,CAAC,yBACpB,QAAQ,SAAS,GAAG,kCAAkC,MAAM,cAAc,SAAS,CAAC,yBAClF,MAAM,cAAc,OAAO,KAAK,QAAQ;GAAE,MAAM,GAAG;GAAM,IAAI,GAAG;GAAI,EAAE,CAAC;EACjG,QAAQ,OAAO,KAAK,QAAQ;GAAE,MAAM,GAAG;GAAM,IAAI,GAAG;GAAI,EAAE;EAC1D;EACD;;AAGH,SAAgB,mBAEd,UACA,UACmB;CACnB,MAAM,EAAE,OAAO,UAAU;AAEzB,KAAI,CAAC,MAAM,QAAQ,SAAS,CAC1B,QAAO;EACL,MAAM;EACN,eACE,GAAG,MAAM,YAAY,qBAAqB,CAAC,+CAE9B,OAAO;EACvB;CAGH,MAAM,eAAgB,SAA2B,OAC/C,YAAY,WACb;AAED,KAAI,aAAa,WAAW,SAAS,OACnC,QAAO;EACL,MAAM;EACN,eACE,GAAG,MAAM,YAAY,qBAAqB,CAAC,eAC/B,QAAQ,SAAS,KAAK,SAAS,OAAO,0BAA0B,aAAa;EAC3F,QAAQ,aAAa;EACrB,UAAU,SAAS;EACpB;AAGH,MAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,IAInC,KAAI,CAHU,OAAO,QAAQ,SAAS,GAAG,CAAC,OAAO,CAAC,KAAK,WACrD,KAAK,OAAQ,aAAa,GAAW,MAAM,MAAM,CAClD,CAEC,QAAO;EACL,MAAM;EACN,eAAe;GACb,MAAM,iBAA0C,EAAE;AAClD,QAAK,MAAM,OAAO,OAAO,KAAK,SAAS,GAAG,CACxC,gBAAe,OAAQ,aAAa,GAAW;AAEjD,UACE,GAAG,MAAM,YAAY,qBAAqB,CAAC,4BAClB,EAAE,6BACd,MAAM,cAAc,SAAS,GAAG,CAAC,cACjC,MAAM,cAAc,eAAe;;EAGpD,QAAQ,aAAa;EACrB,UAAU,SAAS;EACpB;AAIL,QAAO;EACL,MAAM;EACN,eACE,GAAG,MAAM,YAAY,qBAAqB,CAAC;EAE9C;;AAGH,SAAgB,sBAEd,UACA,eACmB;CACnB,MAAM,EAAE,OAAO,UAAU;CAGzB,MAAM,aADS,UACY;AAG3B,KAAI,EAFiB,MAAM,QAAQ,WAAW,IAAI,WAAW,SAAS,GAGpE,QAAO;EACL,MAAM;EACN,eACE,GAAG,MAAM,YAAY,wBAAwB,CAAC,sBAC3B,QAAQ,SAAS,GAAG,oDACZ,MAAM,cAAc,WAAW;EAC7D;AAGH,KAAI,kBAAkB,KAAA,EACpB,QAAO;EACL,MAAM;EACN,eACE,GAAG,MAAM,YAAY,wBAAwB,CAAC,6DAElC,WAAW,OAAO;EACjC;CAGH,MAAM,cAAc,WAAW,IAAI;AAGnC,QAAO;EACL,MAHgB,KAAK,OAAO,aAAa,cAAc;EAIvD,eACE,GAAG,MAAM,YAAY,wBAAwB,CAAC,gCACjB,MAAM,cAAc,cAAc,CAAC,8BACnC,MAAM,cAAc,YAAY;EAC/D,QAAQ;EACR,UAAU;EACX;;AAGH,SAAgB,yBAEd,UACA,UACmB;CACnB,MAAM,EAAE,OAAO,UAAU;CAGzB,MAAM,qBADS,UACoB;AAGnC,KAAI,EAFc,uBAAuB,KAAA,GAGvC,QAAO;EACL,MAAM;EACN,eACE,GAAG,MAAM,YAAY,2BAA2B,CAAC,sBAC9B,QAAQ,SAAS,GAAG;EAE1C;AAGH,KAAI,aAAa,KAAA,EACf,QAAO;EACL,MAAM;EACN,eACE,GAAG,MAAM,YAAY,2BAA2B,CAAC;EAEpD;AAOH,QAAO;EACL,MALiB,OAAO,QAAQ,SAAS,CAAC,OAAO,CAAC,KAAK,WACvD,KAAK,OAAO,mBAAmB,MAAM,MAAM,CAC5C;EAIC,eACE,GAAG,MAAM,YAAY,2BAA2B,CAAC,oCAChB,MAAM,cAAc,SAAS,CAAC,kCAC9B,MAAM,cAAc,mBAAmB;EAC1E,QAAQ;EACR;EACD;;;;;AAMH,MAAa,oBAAoB;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"matchers.js","names":["result"],"sources":["../../src/testing/matchers.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { BaseMessage } from \"../messages/index.js\";\nimport { HumanMessage } from \"../messages/index.js\";\nimport { AIMessage } from \"../messages/index.js\";\nimport { SystemMessage } from \"../messages/index.js\";\nimport { ToolMessage } from \"../messages/index.js\";\n\n/**\n * The `this` context that Vitest and Jest provide to custom matchers\n * via `expect.extend`.\n *\n * Compatible with both frameworks:\n * - https://vitest.dev/guide/extending-matchers.html\n * - https://jestjs.io/docs/expect#expectextendmatchers\n */\ninterface ExpectExtendThis {\n isNot?: boolean;\n equals(a: unknown, b: unknown): boolean;\n utils: {\n matcherHint(name: string, received?: string, expected?: string): string;\n printReceived(value: unknown): string;\n printExpected(value: unknown): string;\n };\n}\n\ninterface ExpectationResult {\n pass: boolean;\n message: () => string;\n actual?: unknown;\n expected?: unknown;\n}\n\nfunction getMessageTypeName(msg: unknown): string {\n if (!BaseMessage.isInstance(msg)) return typeof msg;\n return msg.constructor.name || msg.type;\n}\n\nfunction makeMessageTypeMatcher(\n typeName: string,\n isInstance: (obj: unknown) => boolean\n) {\n return function (\n this: ExpectExtendThis,\n received: unknown,\n expected?: string | Record<string, unknown>\n ): ExpectationResult {\n const { isNot, utils } = this;\n\n const instancePass = isInstance(received);\n if (!instancePass) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: ${isNot ? \"not \" : \"\"}${typeName}\\n` +\n `Received: ${getMessageTypeName(received)}`,\n actual: getMessageTypeName(received),\n expected: typeName,\n };\n }\n\n if (expected === undefined) {\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: not ${typeName}\\n` +\n `Received: ${typeName}`,\n };\n }\n\n const msg = received as BaseMessage;\n if (typeof expected === \"string\") {\n const contentPass = msg.content === expected;\n return {\n pass: contentPass,\n message: () =>\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: ${typeName} with content ${utils.printExpected(expected)}\\n` +\n `Received: ${typeName} with content ${utils.printReceived(msg.content)}`,\n actual: msg.content,\n expected,\n };\n }\n\n const fieldsPass = Object.entries(expected).every(([key, value]) =>\n this.equals((msg as any)[key], value)\n );\n return {\n pass: fieldsPass,\n message: () => {\n const receivedFields: Record<string, unknown> = {};\n for (const key of Object.keys(expected)) {\n receivedFields[key] = (msg as any)[key];\n }\n return (\n `${utils.matcherHint(`toBe${typeName}`, undefined, undefined)}\\n\\n` +\n `Expected: ${typeName} matching ${utils.printExpected(expected)}\\n` +\n `Received: ${typeName} with ${utils.printReceived(receivedFields)}`\n );\n },\n actual: (() => {\n const receivedFields: Record<string, unknown> = {};\n for (const key of Object.keys(expected)) {\n receivedFields[key] = (msg as any)[key];\n }\n return receivedFields;\n })(),\n expected,\n };\n };\n}\n\nexport const toBeHumanMessage = makeMessageTypeMatcher(\n \"HumanMessage\",\n HumanMessage.isInstance\n);\n\nexport const toBeAIMessage = makeMessageTypeMatcher(\n \"AIMessage\",\n AIMessage.isInstance\n);\n\nexport const toBeSystemMessage = makeMessageTypeMatcher(\n \"SystemMessage\",\n SystemMessage.isInstance\n);\n\nexport const toBeToolMessage = makeMessageTypeMatcher(\n \"ToolMessage\",\n ToolMessage.isInstance\n);\n\nexport function toHaveToolCalls(\n this: ExpectExtendThis,\n received: unknown,\n expected: Array<Record<string, unknown>>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!AIMessage.isInstance(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Expected: AIMessage\\n` +\n `Received: ${getMessageTypeName(received)}`,\n };\n }\n\n const actual = received.tool_calls ?? [];\n\n if (actual.length !== expected.length) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Expected ${isNot ? \"not \" : \"\"}${expected.length} tool call(s), received ${actual.length}`,\n actual: actual.length,\n expected: expected.length,\n };\n }\n\n const unmatched = expected.filter(\n (exp) =>\n !actual.some((tc) =>\n Object.entries(exp).every(([key, value]) =>\n this.equals((tc as any)[key], value)\n )\n )\n );\n\n if (unmatched.length > 0) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Could not find matching tool call(s) for:\\n` +\n `${utils.printExpected(unmatched)}\\n` +\n `Received tool calls: ${utils.printReceived(actual.map((tc) => ({ name: tc.name, id: tc.id, args: tc.args })))}`,\n actual: actual.map((tc) => ({ name: tc.name, id: tc.id, args: tc.args })),\n expected,\n };\n }\n\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCalls\")}\\n\\n` +\n `Expected AIMessage not to have matching tool calls`,\n };\n}\n\nexport function toHaveToolCallCount(\n this: ExpectExtendThis,\n received: unknown,\n expected: number\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!AIMessage.isInstance(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCallCount\")}\\n\\n` +\n `Expected: AIMessage\\n` +\n `Received: ${getMessageTypeName(received)}`,\n };\n }\n\n const actual = received.tool_calls?.length ?? 0;\n const pass = actual === expected;\n\n return {\n pass,\n message: () =>\n `${utils.matcherHint(\"toHaveToolCallCount\")}\\n\\n` +\n `Expected ${isNot ? \"not \" : \"\"}${expected} tool call(s)\\n` +\n `Received: ${actual}`,\n actual,\n expected,\n };\n}\n\nexport function toContainToolCall(\n this: ExpectExtendThis,\n received: unknown,\n expected: Record<string, unknown>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!AIMessage.isInstance(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toContainToolCall\")}\\n\\n` +\n `Expected: AIMessage\\n` +\n `Received: ${getMessageTypeName(received)}`,\n };\n }\n\n const actual = received.tool_calls ?? [];\n const found = actual.some((tc) =>\n Object.entries(expected).every(([key, value]) =>\n this.equals((tc as any)[key], value)\n )\n );\n\n return {\n pass: found,\n message: () =>\n `${utils.matcherHint(\"toContainToolCall\")}\\n\\n` +\n `Expected AIMessage ${isNot ? \"not \" : \"\"}to contain a tool call matching ${utils.printExpected(expected)}\\n` +\n `Received tool calls: ${utils.printReceived(actual.map((tc) => ({ name: tc.name, id: tc.id })))}`,\n actual: actual.map((tc) => ({ name: tc.name, id: tc.id })),\n expected,\n };\n}\n\nexport function toHaveToolMessages(\n this: ExpectExtendThis,\n received: unknown,\n expected: Array<Record<string, unknown>>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n if (!Array.isArray(received)) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Expected an array of messages\\n` +\n `Received: ${typeof received}`,\n };\n }\n\n const toolMessages = (received as BaseMessage[]).filter(\n ToolMessage.isInstance\n );\n\n if (toolMessages.length !== expected.length) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Expected ${isNot ? \"not \" : \"\"}${expected.length} tool message(s), found ${toolMessages.length}`,\n actual: toolMessages.length,\n expected: expected.length,\n };\n }\n\n for (let i = 0; i < expected.length; i++) {\n const match = Object.entries(expected[i]).every(([key, value]) =>\n this.equals((toolMessages[i] as any)[key], value)\n );\n if (!match) {\n return {\n pass: false,\n message: () => {\n const receivedFields: Record<string, unknown> = {};\n for (const key of Object.keys(expected[i])) {\n receivedFields[key] = (toolMessages[i] as any)[key];\n }\n return (\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Tool message at index ${i} did not match:\\n` +\n `Expected: ${utils.printExpected(expected[i])}\\n` +\n `Received: ${utils.printReceived(receivedFields)}`\n );\n },\n actual: toolMessages[i],\n expected: expected[i],\n };\n }\n }\n\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveToolMessages\")}\\n\\n` +\n `Expected messages not to contain matching tool messages`,\n };\n}\n\nexport function toHaveBeenInterrupted(\n this: ExpectExtendThis,\n received: unknown,\n expectedValue?: unknown\n): ExpectationResult {\n const { isNot, utils } = this;\n\n const result = received as Record<string, any>;\n const interrupts = result?.__interrupt__;\n const hasInterrupt = Array.isArray(interrupts) && interrupts.length > 0;\n\n if (!hasInterrupt) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveBeenInterrupted\")}\\n\\n` +\n `Expected result ${isNot ? \"not \" : \"\"}to have been interrupted\\n` +\n `Received __interrupt__: ${utils.printReceived(interrupts)}`,\n };\n }\n\n if (expectedValue === undefined) {\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveBeenInterrupted\")}\\n\\n` +\n `Expected result not to have been interrupted\\n` +\n `Received ${interrupts.length} interrupt(s)`,\n };\n }\n\n const actualValue = interrupts[0]?.value;\n const valuePass = this.equals(actualValue, expectedValue);\n\n return {\n pass: valuePass,\n message: () =>\n `${utils.matcherHint(\"toHaveBeenInterrupted\")}\\n\\n` +\n `Expected interrupt value: ${utils.printExpected(expectedValue)}\\n` +\n `Received interrupt value: ${utils.printReceived(actualValue)}`,\n actual: actualValue,\n expected: expectedValue,\n };\n}\n\nexport function toHaveStructuredResponse(\n this: ExpectExtendThis,\n received: unknown,\n expected?: Record<string, unknown>\n): ExpectationResult {\n const { isNot, utils } = this;\n\n const result = received as Record<string, any>;\n const structuredResponse = result?.structuredResponse;\n const isDefined = structuredResponse !== undefined;\n\n if (!isDefined) {\n return {\n pass: false,\n message: () =>\n `${utils.matcherHint(\"toHaveStructuredResponse\")}\\n\\n` +\n `Expected result ${isNot ? \"not \" : \"\"}to have a structured response\\n` +\n `Received structuredResponse: undefined`,\n };\n }\n\n if (expected === undefined) {\n return {\n pass: true,\n message: () =>\n `${utils.matcherHint(\"toHaveStructuredResponse\")}\\n\\n` +\n `Expected result not to have a structured response`,\n };\n }\n\n const fieldsPass = Object.entries(expected).every(([key, value]) =>\n this.equals(structuredResponse[key], value)\n );\n\n return {\n pass: fieldsPass,\n message: () =>\n `${utils.matcherHint(\"toHaveStructuredResponse\")}\\n\\n` +\n `Expected structured response: ${utils.printExpected(expected)}\\n` +\n `Received structured response: ${utils.printReceived(structuredResponse)}`,\n actual: structuredResponse,\n expected,\n };\n}\n\n/**\n * All matcher functions bundled for convenient use with `expect.extend()`.\n */\nexport const langchainMatchers = {\n toBeHumanMessage,\n toBeAIMessage,\n toBeSystemMessage,\n toBeToolMessage,\n toHaveToolCalls,\n toHaveToolCallCount,\n toContainToolCall,\n toHaveToolMessages,\n toHaveBeenInterrupted,\n toHaveStructuredResponse,\n};\n\nexport interface LangChainMatchers<R = unknown> {\n toBeHumanMessage(expected?: string | { content?: string; id?: string }): R;\n toBeAIMessage(expected?: string | { content?: string; name?: string }): R;\n toBeSystemMessage(\n expected?: string | { content?: string; additional_kwargs?: object }\n ): R;\n toBeToolMessage(\n expected?:\n | string\n | {\n content?: string;\n name?: string;\n status?: string;\n tool_call_id?: string;\n }\n ): R;\n toHaveToolCalls(\n expected: Array<{\n name?: string;\n id?: string;\n args?: Record<string, unknown>;\n }>\n ): R;\n toHaveToolCallCount(expected: number): R;\n toContainToolCall(expected: {\n name?: string;\n id?: string;\n args?: Record<string, unknown>;\n }): R;\n toHaveToolMessages(\n expected: Array<{\n content?: string;\n name?: string;\n status?: string;\n tool_call_id?: string;\n }>\n ): R;\n toHaveBeenInterrupted(expectedValue?: unknown): R;\n toHaveStructuredResponse(expected?: Record<string, unknown>): R;\n}\n\ndeclare module \"vitest\" {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n interface Matchers<T = any> extends LangChainMatchers<T> {}\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"console.cjs","names":["BaseTracer"],"sources":["../../src/tracers/console.ts"],"sourcesContent":["import { BaseTracer, type AgentRun, type Run } from \"./base.js\";\n\ninterface CSPair {\n open: string;\n close: string;\n}\n\nconst styles: {\n bold: CSPair;\n color: Record<\"grey\" | \"green\" | \"cyan\" | \"red\" | \"blue\", CSPair>;\n} = {\n bold: { open: \"\\u001b[1m\", close: \"\\u001b[22m\" },\n color: {\n grey: { open: \"\\u001b[90m\", close: \"\\u001b[39m\" },\n green: { open: \"\\u001b[32m\", close: \"\\u001b[39m\" },\n cyan: { open: \"\\u001b[36m\", close: \"\\u001b[39m\" },\n red: { open: \"\\u001b[31m\", close: \"\\u001b[39m\" },\n blue: { open: \"\\u001b[34m\", close: \"\\u001b[39m\" },\n },\n};\n\nfunction wrap(style: CSPair, text: string) {\n return `${style.open}${text}${style.close}`;\n}\n\nfunction tryJsonStringify(obj: unknown, fallback: string) {\n try {\n return JSON.stringify(obj, null, 2);\n } catch {\n return fallback;\n }\n}\n\nfunction formatKVMapItem(value: unknown) {\n if (typeof value === \"string\") {\n return value.trim();\n }\n\n if (value === null || value === undefined) {\n return value;\n }\n\n return tryJsonStringify(value, value.toString());\n}\n\nfunction elapsed(run: Run): string {\n if (!run.end_time) return \"\";\n const elapsed = run.end_time - run.start_time;\n if (elapsed < 1000) {\n return `${elapsed}ms`;\n }\n return `${(elapsed / 1000).toFixed(2)}s`;\n}\n\nconst { color } = styles;\n\n/**\n * A tracer that logs all events to the console. It extends from the\n * `BaseTracer` class and overrides its methods to provide custom logging\n * functionality.\n * @example\n * ```typescript\n *\n * const llm = new ChatAnthropic({\n * temperature: 0,\n * tags: [\"example\", \"callbacks\", \"constructor\"],\n * callbacks: [new ConsoleCallbackHandler()],\n * });\n *\n * ```\n */\nexport class ConsoleCallbackHandler extends BaseTracer {\n name = \"console_callback_handler\" as const;\n\n /**\n * Method used to persist the run. In this case, it simply returns a\n * resolved promise as there's no persistence logic.\n * @param _run The run to persist.\n * @returns A resolved promise.\n */\n protected persistRun(_run: Run) {\n return Promise.resolve();\n }\n\n // utility methods\n\n /**\n * Method used to get all the parent runs of a given run.\n * @param run The run whose parents are to be retrieved.\n * @returns An array of parent runs.\n */\n getParents(run: Run) {\n const parents: Run[] = [];\n let currentRun = run;\n while (currentRun.parent_run_id) {\n const parent = this.runMap.get(currentRun.parent_run_id);\n if (parent) {\n parents.push(parent);\n currentRun = parent;\n } else {\n break;\n }\n }\n return parents;\n }\n\n /**\n * Method used to get a string representation of the run's lineage, which\n * is used in logging.\n * @param run The run whose lineage is to be retrieved.\n * @returns A string representation of the run's lineage.\n */\n getBreadcrumbs(run: Run) {\n const parents = this.getParents(run).reverse();\n const string = [...parents, run]\n .map((parent, i, arr) => {\n const name = `${parent.execution_order}:${parent.run_type}:${parent.name}`;\n return i === arr.length - 1 ? wrap(styles.bold, name) : name;\n })\n .join(\" > \");\n return wrap(color.grey, string);\n }\n\n // logging methods\n\n /**\n * Method used to log the start of a chain run.\n * @param run The chain run that has started.\n * @returns void\n */\n onChainStart(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(\n color.green,\n \"[chain/start]\"\n )} [${crumbs}] Entering Chain run with input: ${tryJsonStringify(\n run.inputs,\n \"[inputs]\"\n )}`\n );\n }\n\n /**\n * Method used to log the end of a chain run.\n * @param run The chain run that has ended.\n * @returns void\n */\n onChainEnd(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(color.cyan, \"[chain/end]\")} [${crumbs}] [${elapsed(\n run\n )}] Exiting Chain run with output: ${tryJsonStringify(\n run.outputs,\n \"[outputs]\"\n )}`\n );\n }\n\n /**\n * Method used to log any errors of a chain run.\n * @param run The chain run that has errored.\n * @returns void\n */\n onChainError(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(color.red, \"[chain/error]\")} [${crumbs}] [${elapsed(\n run\n )}] Chain run errored with error: ${tryJsonStringify(\n run.error,\n \"[error]\"\n )}`\n );\n }\n\n /**\n * Method used to log the start of an LLM run.\n * @param run The LLM run that has started.\n * @returns void\n */\n onLLMStart(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n const inputs =\n \"prompts\" in run.inputs\n ? { prompts: (run.inputs.prompts as string[]).map((p) => p.trim()) }\n : run.inputs;\n console.log(\n `${wrap(\n color.green,\n \"[llm/start]\"\n )} [${crumbs}] Entering LLM run with input: ${tryJsonStringify(\n inputs,\n \"[inputs]\"\n )}`\n );\n }\n\n /**\n * Method used to log the end of an LLM run.\n * @param run The LLM run that has ended.\n * @returns void\n */\n onLLMEnd(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(color.cyan, \"[llm/end]\")} [${crumbs}] [${elapsed(\n run\n )}] Exiting LLM run with output: ${tryJsonStringify(\n run.outputs,\n \"[response]\"\n )}`\n );\n }\n\n /**\n * Method used to log any errors of an LLM run.\n * @param run The LLM run that has errored.\n * @returns void\n */\n onLLMError(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(color.red, \"[llm/error]\")} [${crumbs}] [${elapsed(\n run\n )}] LLM run errored with error: ${tryJsonStringify(run.error, \"[error]\")}`\n );\n }\n\n /**\n * Method used to log the start of a tool run.\n * @param run The tool run that has started.\n * @returns void\n */\n onToolStart(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(\n color.green,\n \"[tool/start]\"\n )} [${crumbs}] Entering Tool run with input: \"${formatKVMapItem(\n run.inputs.input\n )}\"`\n );\n }\n\n /**\n * Method used to log the end of a tool run.\n * @param run The tool run that has ended.\n * @returns void\n */\n onToolEnd(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n\n console.log(\n `${wrap(color.cyan, \"[tool/end]\")} [${crumbs}] [${elapsed(\n run\n )}] Exiting Tool run with output: \"${formatKVMapItem(\n run.outputs?.output\n )}\"`\n );\n }\n\n /**\n * Method used to log any errors of a tool run.\n * @param run The tool run that has errored.\n * @returns void\n */\n onToolError(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(color.red, \"[tool/error]\")} [${crumbs}] [${elapsed(\n run\n )}] Tool run errored with error: ${tryJsonStringify(\n run.error,\n \"[error]\"\n )}`\n );\n }\n\n /**\n * Method used to log the start of a retriever run.\n * @param run The retriever run that has started.\n * @returns void\n */\n onRetrieverStart(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(\n color.green,\n \"[retriever/start]\"\n )} [${crumbs}] Entering Retriever run with input: ${tryJsonStringify(\n run.inputs,\n \"[inputs]\"\n )}`\n );\n }\n\n /**\n * Method used to log the end of a retriever run.\n * @param run The retriever run that has ended.\n * @returns void\n */\n onRetrieverEnd(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(color.cyan, \"[retriever/end]\")} [${crumbs}] [${elapsed(\n run\n )}] Exiting Retriever run with output: ${tryJsonStringify(\n run.outputs,\n \"[outputs]\"\n )}`\n );\n }\n\n /**\n * Method used to log any errors of a retriever run.\n * @param run The retriever run that has errored.\n * @returns void\n */\n onRetrieverError(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(color.red, \"[retriever/error]\")} [${crumbs}] [${elapsed(\n run\n )}] Retriever run errored with error: ${tryJsonStringify(\n run.error,\n \"[error]\"\n )}`\n );\n }\n\n /**\n * Method used to log the action selected by the agent.\n * @param run The run in which the agent action occurred.\n * @returns void\n */\n onAgentAction(run: Run) {\n const agentRun = run as AgentRun;\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(\n color.blue,\n \"[agent/action]\"\n )} [${crumbs}] Agent selected action: ${tryJsonStringify(\n agentRun.actions[agentRun.actions.length - 1],\n \"[action]\"\n )}`\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"console.cjs","names":["BaseTracer"],"sources":["../../src/tracers/console.ts"],"sourcesContent":["import { BaseTracer, type AgentRun, type Run } from \"./base.js\";\n\ninterface CSPair {\n open: string;\n close: string;\n}\n\nconst styles: {\n bold: CSPair;\n color: Record<\"grey\" | \"green\" | \"cyan\" | \"red\" | \"blue\", CSPair>;\n} = {\n bold: { open: \"\\u001b[1m\", close: \"\\u001b[22m\" },\n color: {\n grey: { open: \"\\u001b[90m\", close: \"\\u001b[39m\" },\n green: { open: \"\\u001b[32m\", close: \"\\u001b[39m\" },\n cyan: { open: \"\\u001b[36m\", close: \"\\u001b[39m\" },\n red: { open: \"\\u001b[31m\", close: \"\\u001b[39m\" },\n blue: { open: \"\\u001b[34m\", close: \"\\u001b[39m\" },\n },\n};\n\nfunction wrap(style: CSPair, text: string) {\n return `${style.open}${text}${style.close}`;\n}\n\nfunction tryJsonStringify(obj: unknown, fallback: string) {\n try {\n return JSON.stringify(obj, null, 2);\n } catch {\n return fallback;\n }\n}\n\nfunction formatKVMapItem(value: unknown) {\n if (typeof value === \"string\") {\n return value.trim();\n }\n\n if (value === null || value === undefined) {\n return value;\n }\n\n return tryJsonStringify(value, value.toString());\n}\n\nfunction elapsed(run: Run): string {\n if (!run.end_time) return \"\";\n const elapsed = run.end_time - run.start_time;\n if (elapsed < 1000) {\n return `${elapsed}ms`;\n }\n return `${(elapsed / 1000).toFixed(2)}s`;\n}\n\nconst { color } = styles;\n\n/**\n * A tracer that logs all events to the console. It extends from the\n * `BaseTracer` class and overrides its methods to provide custom logging\n * functionality.\n * @example\n * ```typescript\n *\n * const llm = new ChatAnthropic({\n * temperature: 0,\n * tags: [\"example\", \"callbacks\", \"constructor\"],\n * callbacks: [new ConsoleCallbackHandler()],\n * });\n *\n * ```\n */\nexport class ConsoleCallbackHandler extends BaseTracer {\n name = \"console_callback_handler\" as const;\n\n /**\n * Method used to persist the run. In this case, it simply returns a\n * resolved promise as there's no persistence logic.\n * @param _run The run to persist.\n * @returns A resolved promise.\n */\n protected persistRun(_run: Run) {\n return Promise.resolve();\n }\n\n // utility methods\n\n /**\n * Method used to get all the parent runs of a given run.\n * @param run The run whose parents are to be retrieved.\n * @returns An array of parent runs.\n */\n getParents(run: Run) {\n const parents: Run[] = [];\n let currentRun = run;\n while (currentRun.parent_run_id) {\n const parent = this.runMap.get(currentRun.parent_run_id);\n if (parent) {\n parents.push(parent);\n currentRun = parent;\n } else {\n break;\n }\n }\n return parents;\n }\n\n /**\n * Method used to get a string representation of the run's lineage, which\n * is used in logging.\n * @param run The run whose lineage is to be retrieved.\n * @returns A string representation of the run's lineage.\n */\n getBreadcrumbs(run: Run) {\n const parents = this.getParents(run).reverse();\n const string = [...parents, run]\n .map((parent, i, arr) => {\n const name = `${parent.execution_order}:${parent.run_type}:${parent.name}`;\n return i === arr.length - 1 ? wrap(styles.bold, name) : name;\n })\n .join(\" > \");\n return wrap(color.grey, string);\n }\n\n // logging methods\n\n /**\n * Method used to log the start of a chain run.\n * @param run The chain run that has started.\n * @returns void\n */\n onChainStart(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(\n color.green,\n \"[chain/start]\"\n )} [${crumbs}] Entering Chain run with input: ${tryJsonStringify(\n run.inputs,\n \"[inputs]\"\n )}`\n );\n }\n\n /**\n * Method used to log the end of a chain run.\n * @param run The chain run that has ended.\n * @returns void\n */\n onChainEnd(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(color.cyan, \"[chain/end]\")} [${crumbs}] [${elapsed(\n run\n )}] Exiting Chain run with output: ${tryJsonStringify(\n run.outputs,\n \"[outputs]\"\n )}`\n );\n }\n\n /**\n * Method used to log any errors of a chain run.\n * @param run The chain run that has errored.\n * @returns void\n */\n onChainError(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(color.red, \"[chain/error]\")} [${crumbs}] [${elapsed(\n run\n )}] Chain run errored with error: ${tryJsonStringify(\n run.error,\n \"[error]\"\n )}`\n );\n }\n\n /**\n * Method used to log the start of an LLM run.\n * @param run The LLM run that has started.\n * @returns void\n */\n onLLMStart(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n const inputs =\n \"prompts\" in run.inputs\n ? { prompts: (run.inputs.prompts as string[]).map((p) => p.trim()) }\n : run.inputs;\n console.log(\n `${wrap(\n color.green,\n \"[llm/start]\"\n )} [${crumbs}] Entering LLM run with input: ${tryJsonStringify(\n inputs,\n \"[inputs]\"\n )}`\n );\n }\n\n /**\n * Method used to log the end of an LLM run.\n * @param run The LLM run that has ended.\n * @returns void\n */\n onLLMEnd(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(color.cyan, \"[llm/end]\")} [${crumbs}] [${elapsed(\n run\n )}] Exiting LLM run with output: ${tryJsonStringify(\n run.outputs,\n \"[response]\"\n )}`\n );\n }\n\n /**\n * Method used to log any errors of an LLM run.\n * @param run The LLM run that has errored.\n * @returns void\n */\n onLLMError(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(color.red, \"[llm/error]\")} [${crumbs}] [${elapsed(\n run\n )}] LLM run errored with error: ${tryJsonStringify(run.error, \"[error]\")}`\n );\n }\n\n /**\n * Method used to log the start of a tool run.\n * @param run The tool run that has started.\n * @returns void\n */\n onToolStart(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(\n color.green,\n \"[tool/start]\"\n )} [${crumbs}] Entering Tool run with input: \"${formatKVMapItem(\n run.inputs.input\n )}\"`\n );\n }\n\n /**\n * Method used to log the end of a tool run.\n * @param run The tool run that has ended.\n * @returns void\n */\n onToolEnd(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n\n console.log(\n `${wrap(color.cyan, \"[tool/end]\")} [${crumbs}] [${elapsed(\n run\n )}] Exiting Tool run with output: \"${formatKVMapItem(\n run.outputs?.output\n )}\"`\n );\n }\n\n /**\n * Method used to log any errors of a tool run.\n * @param run The tool run that has errored.\n * @returns void\n */\n onToolError(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(color.red, \"[tool/error]\")} [${crumbs}] [${elapsed(\n run\n )}] Tool run errored with error: ${tryJsonStringify(\n run.error,\n \"[error]\"\n )}`\n );\n }\n\n /**\n * Method used to log the start of a retriever run.\n * @param run The retriever run that has started.\n * @returns void\n */\n onRetrieverStart(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(\n color.green,\n \"[retriever/start]\"\n )} [${crumbs}] Entering Retriever run with input: ${tryJsonStringify(\n run.inputs,\n \"[inputs]\"\n )}`\n );\n }\n\n /**\n * Method used to log the end of a retriever run.\n * @param run The retriever run that has ended.\n * @returns void\n */\n onRetrieverEnd(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(color.cyan, \"[retriever/end]\")} [${crumbs}] [${elapsed(\n run\n )}] Exiting Retriever run with output: ${tryJsonStringify(\n run.outputs,\n \"[outputs]\"\n )}`\n );\n }\n\n /**\n * Method used to log any errors of a retriever run.\n * @param run The retriever run that has errored.\n * @returns void\n */\n onRetrieverError(run: Run) {\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(color.red, \"[retriever/error]\")} [${crumbs}] [${elapsed(\n run\n )}] Retriever run errored with error: ${tryJsonStringify(\n run.error,\n \"[error]\"\n )}`\n );\n }\n\n /**\n * Method used to log the action selected by the agent.\n * @param run The run in which the agent action occurred.\n * @returns void\n */\n onAgentAction(run: Run) {\n const agentRun = run as AgentRun;\n const crumbs = this.getBreadcrumbs(run);\n console.log(\n `${wrap(\n color.blue,\n \"[agent/action]\"\n )} [${crumbs}] Agent selected action: ${tryJsonStringify(\n agentRun.actions[agentRun.actions.length - 1],\n \"[action]\"\n )}`\n );\n }\n}\n"],"mappings":"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"}