langchain 0.4.0.dev0__py3-none-any.whl → 1.0.0__py3-none-any.whl

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.

Potentially problematic release.


This version of langchain might be problematic. Click here for more details.

Files changed (1364) hide show
  1. langchain/__init__.py +2 -452
  2. langchain/agents/__init__.py +9 -178
  3. langchain/agents/factory.py +1582 -0
  4. langchain/agents/middleware/__init__.py +80 -0
  5. langchain/agents/middleware/_execution.py +388 -0
  6. langchain/agents/middleware/_redaction.py +350 -0
  7. langchain/agents/middleware/context_editing.py +274 -0
  8. langchain/agents/middleware/file_search.py +382 -0
  9. langchain/agents/middleware/human_in_the_loop.py +351 -0
  10. langchain/agents/middleware/model_call_limit.py +210 -0
  11. langchain/agents/middleware/model_fallback.py +137 -0
  12. langchain/agents/middleware/pii.py +317 -0
  13. langchain/agents/middleware/shell_tool.py +718 -0
  14. langchain/agents/middleware/summarization.py +249 -0
  15. langchain/agents/middleware/todo.py +219 -0
  16. langchain/agents/middleware/tool_call_limit.py +333 -0
  17. langchain/agents/middleware/tool_emulator.py +200 -0
  18. langchain/agents/middleware/tool_retry.py +384 -0
  19. langchain/agents/middleware/tool_selection.py +310 -0
  20. langchain/agents/middleware/types.py +1572 -0
  21. langchain/agents/structured_output.py +426 -0
  22. langchain/chat_models/__init__.py +7 -72
  23. langchain/chat_models/base.py +268 -358
  24. langchain/embeddings/__init__.py +7 -217
  25. langchain/embeddings/base.py +31 -43
  26. langchain/messages/__init__.py +72 -0
  27. langchain/rate_limiters/__init__.py +13 -0
  28. langchain/tools/__init__.py +17 -197
  29. langchain/tools/tool_node.py +1700 -0
  30. langchain-1.0.0.dist-info/METADATA +87 -0
  31. langchain-1.0.0.dist-info/RECORD +34 -0
  32. {langchain-0.4.0.dev0.dist-info → langchain-1.0.0.dist-info}/WHEEL +1 -1
  33. langchain/_api/__init__.py +0 -28
  34. langchain/_api/deprecation.py +0 -32
  35. langchain/_api/interactive_env.py +0 -5
  36. langchain/_api/module_import.py +0 -153
  37. langchain/_api/path.py +0 -3
  38. langchain/adapters/__init__.py +0 -0
  39. langchain/adapters/openai.py +0 -63
  40. langchain/agents/agent.py +0 -1824
  41. langchain/agents/agent_iterator.py +0 -438
  42. langchain/agents/agent_toolkits/__init__.py +0 -167
  43. langchain/agents/agent_toolkits/ainetwork/__init__.py +0 -1
  44. langchain/agents/agent_toolkits/ainetwork/toolkit.py +0 -25
  45. langchain/agents/agent_toolkits/amadeus/toolkit.py +0 -23
  46. langchain/agents/agent_toolkits/azure_cognitive_services.py +0 -29
  47. langchain/agents/agent_toolkits/base.py +0 -3
  48. langchain/agents/agent_toolkits/clickup/__init__.py +0 -0
  49. langchain/agents/agent_toolkits/clickup/toolkit.py +0 -25
  50. langchain/agents/agent_toolkits/conversational_retrieval/__init__.py +0 -0
  51. langchain/agents/agent_toolkits/conversational_retrieval/openai_functions.py +0 -87
  52. langchain/agents/agent_toolkits/conversational_retrieval/tool.py +0 -3
  53. langchain/agents/agent_toolkits/csv/__init__.py +0 -28
  54. langchain/agents/agent_toolkits/file_management/__init__.py +0 -31
  55. langchain/agents/agent_toolkits/file_management/toolkit.py +0 -29
  56. langchain/agents/agent_toolkits/github/__init__.py +0 -1
  57. langchain/agents/agent_toolkits/github/toolkit.py +0 -69
  58. langchain/agents/agent_toolkits/gitlab/__init__.py +0 -1
  59. langchain/agents/agent_toolkits/gitlab/toolkit.py +0 -25
  60. langchain/agents/agent_toolkits/gmail/__init__.py +0 -1
  61. langchain/agents/agent_toolkits/gmail/toolkit.py +0 -23
  62. langchain/agents/agent_toolkits/jira/__init__.py +0 -1
  63. langchain/agents/agent_toolkits/jira/toolkit.py +0 -23
  64. langchain/agents/agent_toolkits/json/__init__.py +0 -1
  65. langchain/agents/agent_toolkits/json/base.py +0 -25
  66. langchain/agents/agent_toolkits/json/prompt.py +0 -24
  67. langchain/agents/agent_toolkits/json/toolkit.py +0 -23
  68. langchain/agents/agent_toolkits/multion/__init__.py +0 -1
  69. langchain/agents/agent_toolkits/multion/toolkit.py +0 -25
  70. langchain/agents/agent_toolkits/nasa/__init__.py +0 -1
  71. langchain/agents/agent_toolkits/nasa/toolkit.py +0 -23
  72. langchain/agents/agent_toolkits/nla/__init__.py +0 -0
  73. langchain/agents/agent_toolkits/nla/tool.py +0 -23
  74. langchain/agents/agent_toolkits/nla/toolkit.py +0 -23
  75. langchain/agents/agent_toolkits/office365/__init__.py +0 -1
  76. langchain/agents/agent_toolkits/office365/toolkit.py +0 -25
  77. langchain/agents/agent_toolkits/openapi/__init__.py +0 -1
  78. langchain/agents/agent_toolkits/openapi/base.py +0 -25
  79. langchain/agents/agent_toolkits/openapi/planner.py +0 -52
  80. langchain/agents/agent_toolkits/openapi/planner_prompt.py +0 -103
  81. langchain/agents/agent_toolkits/openapi/prompt.py +0 -29
  82. langchain/agents/agent_toolkits/openapi/spec.py +0 -30
  83. langchain/agents/agent_toolkits/openapi/toolkit.py +0 -30
  84. langchain/agents/agent_toolkits/pandas/__init__.py +0 -28
  85. langchain/agents/agent_toolkits/playwright/__init__.py +0 -29
  86. langchain/agents/agent_toolkits/playwright/toolkit.py +0 -27
  87. langchain/agents/agent_toolkits/powerbi/__init__.py +0 -1
  88. langchain/agents/agent_toolkits/powerbi/base.py +0 -25
  89. langchain/agents/agent_toolkits/powerbi/chat_base.py +0 -27
  90. langchain/agents/agent_toolkits/powerbi/prompt.py +0 -36
  91. langchain/agents/agent_toolkits/powerbi/toolkit.py +0 -25
  92. langchain/agents/agent_toolkits/python/__init__.py +0 -28
  93. langchain/agents/agent_toolkits/slack/__init__.py +0 -1
  94. langchain/agents/agent_toolkits/slack/toolkit.py +0 -23
  95. langchain/agents/agent_toolkits/spark/__init__.py +0 -28
  96. langchain/agents/agent_toolkits/spark_sql/__init__.py +0 -1
  97. langchain/agents/agent_toolkits/spark_sql/base.py +0 -25
  98. langchain/agents/agent_toolkits/spark_sql/prompt.py +0 -27
  99. langchain/agents/agent_toolkits/spark_sql/toolkit.py +0 -25
  100. langchain/agents/agent_toolkits/sql/__init__.py +0 -1
  101. langchain/agents/agent_toolkits/sql/base.py +0 -23
  102. langchain/agents/agent_toolkits/sql/prompt.py +0 -29
  103. langchain/agents/agent_toolkits/sql/toolkit.py +0 -25
  104. langchain/agents/agent_toolkits/steam/__init__.py +0 -1
  105. langchain/agents/agent_toolkits/steam/toolkit.py +0 -23
  106. langchain/agents/agent_toolkits/vectorstore/__init__.py +0 -1
  107. langchain/agents/agent_toolkits/vectorstore/base.py +0 -219
  108. langchain/agents/agent_toolkits/vectorstore/prompt.py +0 -11
  109. langchain/agents/agent_toolkits/vectorstore/toolkit.py +0 -97
  110. langchain/agents/agent_toolkits/xorbits/__init__.py +0 -28
  111. langchain/agents/agent_toolkits/zapier/__init__.py +0 -1
  112. langchain/agents/agent_toolkits/zapier/toolkit.py +0 -25
  113. langchain/agents/agent_types.py +0 -57
  114. langchain/agents/chat/__init__.py +0 -0
  115. langchain/agents/chat/base.py +0 -180
  116. langchain/agents/chat/output_parser.py +0 -74
  117. langchain/agents/chat/prompt.py +0 -29
  118. langchain/agents/conversational/__init__.py +0 -1
  119. langchain/agents/conversational/base.py +0 -178
  120. langchain/agents/conversational/output_parser.py +0 -51
  121. langchain/agents/conversational/prompt.py +0 -35
  122. langchain/agents/conversational_chat/__init__.py +0 -1
  123. langchain/agents/conversational_chat/base.py +0 -183
  124. langchain/agents/conversational_chat/output_parser.py +0 -57
  125. langchain/agents/conversational_chat/prompt.py +0 -56
  126. langchain/agents/format_scratchpad/__init__.py +0 -25
  127. langchain/agents/format_scratchpad/log.py +0 -25
  128. langchain/agents/format_scratchpad/log_to_messages.py +0 -26
  129. langchain/agents/format_scratchpad/openai_functions.py +0 -80
  130. langchain/agents/format_scratchpad/openai_tools.py +0 -5
  131. langchain/agents/format_scratchpad/tools.py +0 -65
  132. langchain/agents/format_scratchpad/xml.py +0 -52
  133. langchain/agents/initialize.py +0 -105
  134. langchain/agents/json_chat/__init__.py +0 -0
  135. langchain/agents/json_chat/base.py +0 -196
  136. langchain/agents/json_chat/prompt.py +0 -8
  137. langchain/agents/load_tools.py +0 -13
  138. langchain/agents/loading.py +0 -148
  139. langchain/agents/mrkl/__init__.py +0 -1
  140. langchain/agents/mrkl/base.py +0 -218
  141. langchain/agents/mrkl/output_parser.py +0 -103
  142. langchain/agents/mrkl/prompt.py +0 -15
  143. langchain/agents/openai_assistant/__init__.py +0 -3
  144. langchain/agents/openai_assistant/base.py +0 -818
  145. langchain/agents/openai_functions_agent/__init__.py +0 -0
  146. langchain/agents/openai_functions_agent/agent_token_buffer_memory.py +0 -103
  147. langchain/agents/openai_functions_agent/base.py +0 -382
  148. langchain/agents/openai_functions_multi_agent/__init__.py +0 -0
  149. langchain/agents/openai_functions_multi_agent/base.py +0 -337
  150. langchain/agents/openai_tools/__init__.py +0 -0
  151. langchain/agents/openai_tools/base.py +0 -109
  152. langchain/agents/output_parsers/__init__.py +0 -35
  153. langchain/agents/output_parsers/json.py +0 -64
  154. langchain/agents/output_parsers/openai_functions.py +0 -103
  155. langchain/agents/output_parsers/openai_tools.py +0 -77
  156. langchain/agents/output_parsers/react_json_single_input.py +0 -87
  157. langchain/agents/output_parsers/react_single_input.py +0 -102
  158. langchain/agents/output_parsers/self_ask.py +0 -53
  159. langchain/agents/output_parsers/tools.py +0 -121
  160. langchain/agents/output_parsers/xml.py +0 -126
  161. langchain/agents/react/__init__.py +0 -1
  162. langchain/agents/react/agent.py +0 -145
  163. langchain/agents/react/base.py +0 -189
  164. langchain/agents/react/output_parser.py +0 -35
  165. langchain/agents/react/textworld_prompt.py +0 -51
  166. langchain/agents/react/wiki_prompt.py +0 -70
  167. langchain/agents/schema.py +0 -37
  168. langchain/agents/self_ask_with_search/__init__.py +0 -4
  169. langchain/agents/self_ask_with_search/base.py +0 -219
  170. langchain/agents/self_ask_with_search/output_parser.py +0 -4
  171. langchain/agents/self_ask_with_search/prompt.py +0 -43
  172. langchain/agents/structured_chat/__init__.py +0 -0
  173. langchain/agents/structured_chat/base.py +0 -309
  174. langchain/agents/structured_chat/output_parser.py +0 -112
  175. langchain/agents/structured_chat/prompt.py +0 -34
  176. langchain/agents/tool_calling_agent/__init__.py +0 -0
  177. langchain/agents/tool_calling_agent/base.py +0 -111
  178. langchain/agents/tools.py +0 -50
  179. langchain/agents/types.py +0 -27
  180. langchain/agents/utils.py +0 -19
  181. langchain/agents/xml/__init__.py +0 -0
  182. langchain/agents/xml/base.py +0 -237
  183. langchain/agents/xml/prompt.py +0 -21
  184. langchain/base_language.py +0 -7
  185. langchain/cache.py +0 -72
  186. langchain/callbacks/__init__.py +0 -139
  187. langchain/callbacks/aim_callback.py +0 -33
  188. langchain/callbacks/argilla_callback.py +0 -25
  189. langchain/callbacks/arize_callback.py +0 -25
  190. langchain/callbacks/arthur_callback.py +0 -25
  191. langchain/callbacks/base.py +0 -29
  192. langchain/callbacks/clearml_callback.py +0 -25
  193. langchain/callbacks/comet_ml_callback.py +0 -25
  194. langchain/callbacks/confident_callback.py +0 -25
  195. langchain/callbacks/context_callback.py +0 -25
  196. langchain/callbacks/file.py +0 -3
  197. langchain/callbacks/flyte_callback.py +0 -25
  198. langchain/callbacks/human.py +0 -33
  199. langchain/callbacks/infino_callback.py +0 -25
  200. langchain/callbacks/labelstudio_callback.py +0 -33
  201. langchain/callbacks/llmonitor_callback.py +0 -27
  202. langchain/callbacks/manager.py +0 -89
  203. langchain/callbacks/mlflow_callback.py +0 -38
  204. langchain/callbacks/openai_info.py +0 -25
  205. langchain/callbacks/promptlayer_callback.py +0 -27
  206. langchain/callbacks/sagemaker_callback.py +0 -27
  207. langchain/callbacks/stdout.py +0 -3
  208. langchain/callbacks/streaming_aiter.py +0 -86
  209. langchain/callbacks/streaming_aiter_final_only.py +0 -100
  210. langchain/callbacks/streaming_stdout.py +0 -5
  211. langchain/callbacks/streaming_stdout_final_only.py +0 -96
  212. langchain/callbacks/streamlit/__init__.py +0 -86
  213. langchain/callbacks/streamlit/mutable_expander.py +0 -33
  214. langchain/callbacks/streamlit/streamlit_callback_handler.py +0 -49
  215. langchain/callbacks/tracers/__init__.py +0 -38
  216. langchain/callbacks/tracers/base.py +0 -6
  217. langchain/callbacks/tracers/comet.py +0 -30
  218. langchain/callbacks/tracers/evaluation.py +0 -8
  219. langchain/callbacks/tracers/langchain.py +0 -8
  220. langchain/callbacks/tracers/langchain_v1.py +0 -3
  221. langchain/callbacks/tracers/log_stream.py +0 -9
  222. langchain/callbacks/tracers/logging.py +0 -57
  223. langchain/callbacks/tracers/root_listeners.py +0 -3
  224. langchain/callbacks/tracers/run_collector.py +0 -3
  225. langchain/callbacks/tracers/schemas.py +0 -27
  226. langchain/callbacks/tracers/stdout.py +0 -6
  227. langchain/callbacks/tracers/wandb.py +0 -27
  228. langchain/callbacks/trubrics_callback.py +0 -25
  229. langchain/callbacks/utils.py +0 -48
  230. langchain/callbacks/wandb_callback.py +0 -25
  231. langchain/callbacks/whylabs_callback.py +0 -25
  232. langchain/chains/__init__.py +0 -96
  233. langchain/chains/api/__init__.py +0 -1
  234. langchain/chains/api/base.py +0 -398
  235. langchain/chains/api/news_docs.py +0 -31
  236. langchain/chains/api/open_meteo_docs.py +0 -32
  237. langchain/chains/api/openapi/__init__.py +0 -0
  238. langchain/chains/api/openapi/chain.py +0 -23
  239. langchain/chains/api/openapi/prompts.py +0 -27
  240. langchain/chains/api/openapi/requests_chain.py +0 -29
  241. langchain/chains/api/openapi/response_chain.py +0 -29
  242. langchain/chains/api/podcast_docs.py +0 -27
  243. langchain/chains/api/prompt.py +0 -35
  244. langchain/chains/api/tmdb_docs.py +0 -36
  245. langchain/chains/base.py +0 -806
  246. langchain/chains/chat_vector_db/__init__.py +0 -0
  247. langchain/chains/chat_vector_db/prompts.py +0 -19
  248. langchain/chains/combine_documents/__init__.py +0 -15
  249. langchain/chains/combine_documents/base.py +0 -293
  250. langchain/chains/combine_documents/map_reduce.py +0 -303
  251. langchain/chains/combine_documents/map_rerank.py +0 -249
  252. langchain/chains/combine_documents/reduce.py +0 -382
  253. langchain/chains/combine_documents/refine.py +0 -237
  254. langchain/chains/combine_documents/stuff.py +0 -292
  255. langchain/chains/constitutional_ai/__init__.py +0 -2
  256. langchain/chains/constitutional_ai/base.py +0 -328
  257. langchain/chains/constitutional_ai/models.py +0 -11
  258. langchain/chains/constitutional_ai/principles.py +0 -278
  259. langchain/chains/constitutional_ai/prompts.py +0 -120
  260. langchain/chains/conversation/__init__.py +0 -1
  261. langchain/chains/conversation/base.py +0 -146
  262. langchain/chains/conversation/memory.py +0 -45
  263. langchain/chains/conversation/prompt.py +0 -28
  264. langchain/chains/conversational_retrieval/__init__.py +0 -1
  265. langchain/chains/conversational_retrieval/base.py +0 -576
  266. langchain/chains/conversational_retrieval/prompts.py +0 -19
  267. langchain/chains/elasticsearch_database/__init__.py +0 -3
  268. langchain/chains/elasticsearch_database/base.py +0 -212
  269. langchain/chains/elasticsearch_database/prompts.py +0 -35
  270. langchain/chains/ernie_functions/__init__.py +0 -44
  271. langchain/chains/ernie_functions/base.py +0 -49
  272. langchain/chains/example_generator.py +0 -22
  273. langchain/chains/flare/__init__.py +0 -1
  274. langchain/chains/flare/base.py +0 -284
  275. langchain/chains/flare/prompts.py +0 -46
  276. langchain/chains/graph_qa/__init__.py +0 -0
  277. langchain/chains/graph_qa/arangodb.py +0 -23
  278. langchain/chains/graph_qa/base.py +0 -23
  279. langchain/chains/graph_qa/cypher.py +0 -39
  280. langchain/chains/graph_qa/cypher_utils.py +0 -27
  281. langchain/chains/graph_qa/falkordb.py +0 -29
  282. langchain/chains/graph_qa/gremlin.py +0 -36
  283. langchain/chains/graph_qa/hugegraph.py +0 -23
  284. langchain/chains/graph_qa/kuzu.py +0 -29
  285. langchain/chains/graph_qa/nebulagraph.py +0 -23
  286. langchain/chains/graph_qa/neptune_cypher.py +0 -39
  287. langchain/chains/graph_qa/neptune_sparql.py +0 -36
  288. langchain/chains/graph_qa/ontotext_graphdb.py +0 -25
  289. langchain/chains/graph_qa/prompts.py +0 -96
  290. langchain/chains/graph_qa/sparql.py +0 -23
  291. langchain/chains/history_aware_retriever.py +0 -68
  292. langchain/chains/hyde/__init__.py +0 -4
  293. langchain/chains/hyde/base.py +0 -124
  294. langchain/chains/hyde/prompts.py +0 -46
  295. langchain/chains/llm.py +0 -447
  296. langchain/chains/llm_bash/__init__.py +0 -10
  297. langchain/chains/llm_checker/__init__.py +0 -4
  298. langchain/chains/llm_checker/base.py +0 -205
  299. langchain/chains/llm_checker/prompt.py +0 -30
  300. langchain/chains/llm_math/__init__.py +0 -4
  301. langchain/chains/llm_math/base.py +0 -319
  302. langchain/chains/llm_math/prompt.py +0 -43
  303. langchain/chains/llm_requests.py +0 -23
  304. langchain/chains/llm_summarization_checker/__init__.py +0 -7
  305. langchain/chains/llm_summarization_checker/base.py +0 -217
  306. langchain/chains/llm_summarization_checker/prompts/are_all_true_prompt.txt +0 -38
  307. langchain/chains/llm_summarization_checker/prompts/check_facts.txt +0 -10
  308. langchain/chains/llm_summarization_checker/prompts/create_facts.txt +0 -10
  309. langchain/chains/llm_summarization_checker/prompts/revise_summary.txt +0 -17
  310. langchain/chains/llm_symbolic_math/__init__.py +0 -10
  311. langchain/chains/loading.py +0 -734
  312. langchain/chains/mapreduce.py +0 -121
  313. langchain/chains/moderation.py +0 -135
  314. langchain/chains/natbot/__init__.py +0 -4
  315. langchain/chains/natbot/base.py +0 -165
  316. langchain/chains/natbot/crawler.py +0 -472
  317. langchain/chains/natbot/prompt.py +0 -143
  318. langchain/chains/openai_functions/__init__.py +0 -44
  319. langchain/chains/openai_functions/base.py +0 -237
  320. langchain/chains/openai_functions/citation_fuzzy_match.py +0 -169
  321. langchain/chains/openai_functions/extraction.py +0 -197
  322. langchain/chains/openai_functions/openapi.py +0 -409
  323. langchain/chains/openai_functions/qa_with_structure.py +0 -142
  324. langchain/chains/openai_functions/tagging.py +0 -174
  325. langchain/chains/openai_functions/utils.py +0 -40
  326. langchain/chains/openai_tools/__init__.py +0 -3
  327. langchain/chains/openai_tools/extraction.py +0 -79
  328. langchain/chains/prompt_selector.py +0 -65
  329. langchain/chains/qa_generation/__init__.py +0 -0
  330. langchain/chains/qa_generation/base.py +0 -128
  331. langchain/chains/qa_generation/prompt.py +0 -50
  332. langchain/chains/qa_with_sources/__init__.py +0 -5
  333. langchain/chains/qa_with_sources/base.py +0 -266
  334. langchain/chains/qa_with_sources/loading.py +0 -209
  335. langchain/chains/qa_with_sources/map_reduce_prompt.py +0 -54
  336. langchain/chains/qa_with_sources/refine_prompts.py +0 -37
  337. langchain/chains/qa_with_sources/retrieval.py +0 -75
  338. langchain/chains/qa_with_sources/stuff_prompt.py +0 -43
  339. langchain/chains/qa_with_sources/vector_db.py +0 -88
  340. langchain/chains/query_constructor/__init__.py +0 -3
  341. langchain/chains/query_constructor/base.py +0 -378
  342. langchain/chains/query_constructor/ir.py +0 -23
  343. langchain/chains/query_constructor/parser.py +0 -272
  344. langchain/chains/query_constructor/prompt.py +0 -226
  345. langchain/chains/query_constructor/schema.py +0 -14
  346. langchain/chains/question_answering/__init__.py +0 -6
  347. langchain/chains/question_answering/chain.py +0 -279
  348. langchain/chains/question_answering/map_reduce_prompt.py +0 -80
  349. langchain/chains/question_answering/map_rerank_prompt.py +0 -66
  350. langchain/chains/question_answering/refine_prompts.py +0 -72
  351. langchain/chains/question_answering/stuff_prompt.py +0 -33
  352. langchain/chains/retrieval.py +0 -67
  353. langchain/chains/retrieval_qa/__init__.py +0 -1
  354. langchain/chains/retrieval_qa/base.py +0 -374
  355. langchain/chains/retrieval_qa/prompt.py +0 -11
  356. langchain/chains/router/__init__.py +0 -12
  357. langchain/chains/router/base.py +0 -154
  358. langchain/chains/router/embedding_router.py +0 -96
  359. langchain/chains/router/llm_router.py +0 -198
  360. langchain/chains/router/multi_prompt.py +0 -184
  361. langchain/chains/router/multi_prompt_prompt.py +0 -32
  362. langchain/chains/router/multi_retrieval_prompt.py +0 -30
  363. langchain/chains/router/multi_retrieval_qa.py +0 -127
  364. langchain/chains/sequential.py +0 -220
  365. langchain/chains/sql_database/__init__.py +0 -1
  366. langchain/chains/sql_database/prompt.py +0 -282
  367. langchain/chains/sql_database/query.py +0 -167
  368. langchain/chains/structured_output/__init__.py +0 -6
  369. langchain/chains/structured_output/base.py +0 -584
  370. langchain/chains/summarize/__init__.py +0 -6
  371. langchain/chains/summarize/chain.py +0 -174
  372. langchain/chains/summarize/map_reduce_prompt.py +0 -10
  373. langchain/chains/summarize/refine_prompts.py +0 -23
  374. langchain/chains/summarize/stuff_prompt.py +0 -10
  375. langchain/chains/transform.py +0 -88
  376. langchain/chat_loaders/__init__.py +0 -19
  377. langchain/chat_loaders/base.py +0 -3
  378. langchain/chat_loaders/facebook_messenger.py +0 -32
  379. langchain/chat_loaders/gmail.py +0 -23
  380. langchain/chat_loaders/imessage.py +0 -23
  381. langchain/chat_loaders/langsmith.py +0 -30
  382. langchain/chat_loaders/slack.py +0 -23
  383. langchain/chat_loaders/telegram.py +0 -23
  384. langchain/chat_loaders/utils.py +0 -36
  385. langchain/chat_loaders/whatsapp.py +0 -23
  386. langchain/chat_models/anthropic.py +0 -30
  387. langchain/chat_models/anyscale.py +0 -23
  388. langchain/chat_models/azure_openai.py +0 -23
  389. langchain/chat_models/azureml_endpoint.py +0 -30
  390. langchain/chat_models/baichuan.py +0 -23
  391. langchain/chat_models/baidu_qianfan_endpoint.py +0 -27
  392. langchain/chat_models/bedrock.py +0 -27
  393. langchain/chat_models/cohere.py +0 -23
  394. langchain/chat_models/databricks.py +0 -23
  395. langchain/chat_models/ernie.py +0 -23
  396. langchain/chat_models/everlyai.py +0 -23
  397. langchain/chat_models/fake.py +0 -30
  398. langchain/chat_models/fireworks.py +0 -23
  399. langchain/chat_models/gigachat.py +0 -23
  400. langchain/chat_models/google_palm.py +0 -30
  401. langchain/chat_models/human.py +0 -23
  402. langchain/chat_models/hunyuan.py +0 -23
  403. langchain/chat_models/javelin_ai_gateway.py +0 -30
  404. langchain/chat_models/jinachat.py +0 -23
  405. langchain/chat_models/konko.py +0 -23
  406. langchain/chat_models/litellm.py +0 -30
  407. langchain/chat_models/meta.py +0 -25
  408. langchain/chat_models/minimax.py +0 -23
  409. langchain/chat_models/mlflow.py +0 -23
  410. langchain/chat_models/mlflow_ai_gateway.py +0 -30
  411. langchain/chat_models/ollama.py +0 -23
  412. langchain/chat_models/openai.py +0 -23
  413. langchain/chat_models/pai_eas_endpoint.py +0 -25
  414. langchain/chat_models/promptlayer_openai.py +0 -25
  415. langchain/chat_models/tongyi.py +0 -23
  416. langchain/chat_models/vertexai.py +0 -23
  417. langchain/chat_models/volcengine_maas.py +0 -30
  418. langchain/chat_models/yandex.py +0 -23
  419. langchain/docstore/__init__.py +0 -48
  420. langchain/docstore/arbitrary_fn.py +0 -23
  421. langchain/docstore/base.py +0 -27
  422. langchain/docstore/document.py +0 -3
  423. langchain/docstore/in_memory.py +0 -23
  424. langchain/docstore/wikipedia.py +0 -23
  425. langchain/document_loaders/__init__.py +0 -553
  426. langchain/document_loaders/acreom.py +0 -23
  427. langchain/document_loaders/airbyte.py +0 -48
  428. langchain/document_loaders/airbyte_json.py +0 -23
  429. langchain/document_loaders/airtable.py +0 -23
  430. langchain/document_loaders/apify_dataset.py +0 -23
  431. langchain/document_loaders/arcgis_loader.py +0 -23
  432. langchain/document_loaders/arxiv.py +0 -23
  433. langchain/document_loaders/assemblyai.py +0 -28
  434. langchain/document_loaders/async_html.py +0 -23
  435. langchain/document_loaders/azlyrics.py +0 -23
  436. langchain/document_loaders/azure_ai_data.py +0 -23
  437. langchain/document_loaders/azure_blob_storage_container.py +0 -25
  438. langchain/document_loaders/azure_blob_storage_file.py +0 -25
  439. langchain/document_loaders/baiducloud_bos_directory.py +0 -29
  440. langchain/document_loaders/baiducloud_bos_file.py +0 -27
  441. langchain/document_loaders/base.py +0 -3
  442. langchain/document_loaders/base_o365.py +0 -23
  443. langchain/document_loaders/bibtex.py +0 -23
  444. langchain/document_loaders/bigquery.py +0 -23
  445. langchain/document_loaders/bilibili.py +0 -23
  446. langchain/document_loaders/blackboard.py +0 -23
  447. langchain/document_loaders/blob_loaders/__init__.py +0 -36
  448. langchain/document_loaders/blob_loaders/file_system.py +0 -23
  449. langchain/document_loaders/blob_loaders/schema.py +0 -26
  450. langchain/document_loaders/blob_loaders/youtube_audio.py +0 -23
  451. langchain/document_loaders/blockchain.py +0 -28
  452. langchain/document_loaders/brave_search.py +0 -23
  453. langchain/document_loaders/browserless.py +0 -23
  454. langchain/document_loaders/chatgpt.py +0 -28
  455. langchain/document_loaders/chromium.py +0 -23
  456. langchain/document_loaders/college_confidential.py +0 -25
  457. langchain/document_loaders/concurrent.py +0 -23
  458. langchain/document_loaders/confluence.py +0 -28
  459. langchain/document_loaders/conllu.py +0 -23
  460. langchain/document_loaders/couchbase.py +0 -23
  461. langchain/document_loaders/csv_loader.py +0 -27
  462. langchain/document_loaders/cube_semantic.py +0 -23
  463. langchain/document_loaders/datadog_logs.py +0 -23
  464. langchain/document_loaders/dataframe.py +0 -28
  465. langchain/document_loaders/diffbot.py +0 -23
  466. langchain/document_loaders/directory.py +0 -23
  467. langchain/document_loaders/discord.py +0 -23
  468. langchain/document_loaders/docugami.py +0 -23
  469. langchain/document_loaders/docusaurus.py +0 -23
  470. langchain/document_loaders/dropbox.py +0 -23
  471. langchain/document_loaders/duckdb_loader.py +0 -23
  472. langchain/document_loaders/email.py +0 -30
  473. langchain/document_loaders/epub.py +0 -23
  474. langchain/document_loaders/etherscan.py +0 -23
  475. langchain/document_loaders/evernote.py +0 -23
  476. langchain/document_loaders/excel.py +0 -23
  477. langchain/document_loaders/facebook_chat.py +0 -28
  478. langchain/document_loaders/fauna.py +0 -23
  479. langchain/document_loaders/figma.py +0 -23
  480. langchain/document_loaders/gcs_directory.py +0 -23
  481. langchain/document_loaders/gcs_file.py +0 -23
  482. langchain/document_loaders/generic.py +0 -23
  483. langchain/document_loaders/geodataframe.py +0 -23
  484. langchain/document_loaders/git.py +0 -23
  485. langchain/document_loaders/gitbook.py +0 -23
  486. langchain/document_loaders/github.py +0 -28
  487. langchain/document_loaders/google_speech_to_text.py +0 -23
  488. langchain/document_loaders/googledrive.py +0 -23
  489. langchain/document_loaders/gutenberg.py +0 -23
  490. langchain/document_loaders/helpers.py +0 -30
  491. langchain/document_loaders/hn.py +0 -23
  492. langchain/document_loaders/html.py +0 -23
  493. langchain/document_loaders/html_bs.py +0 -23
  494. langchain/document_loaders/hugging_face_dataset.py +0 -23
  495. langchain/document_loaders/ifixit.py +0 -23
  496. langchain/document_loaders/image.py +0 -23
  497. langchain/document_loaders/image_captions.py +0 -23
  498. langchain/document_loaders/imsdb.py +0 -23
  499. langchain/document_loaders/iugu.py +0 -23
  500. langchain/document_loaders/joplin.py +0 -23
  501. langchain/document_loaders/json_loader.py +0 -23
  502. langchain/document_loaders/lakefs.py +0 -33
  503. langchain/document_loaders/larksuite.py +0 -23
  504. langchain/document_loaders/markdown.py +0 -25
  505. langchain/document_loaders/mastodon.py +0 -23
  506. langchain/document_loaders/max_compute.py +0 -23
  507. langchain/document_loaders/mediawikidump.py +0 -23
  508. langchain/document_loaders/merge.py +0 -23
  509. langchain/document_loaders/mhtml.py +0 -23
  510. langchain/document_loaders/modern_treasury.py +0 -23
  511. langchain/document_loaders/mongodb.py +0 -23
  512. langchain/document_loaders/news.py +0 -23
  513. langchain/document_loaders/notebook.py +0 -33
  514. langchain/document_loaders/notion.py +0 -23
  515. langchain/document_loaders/notiondb.py +0 -23
  516. langchain/document_loaders/nuclia.py +0 -23
  517. langchain/document_loaders/obs_directory.py +0 -23
  518. langchain/document_loaders/obs_file.py +0 -23
  519. langchain/document_loaders/obsidian.py +0 -23
  520. langchain/document_loaders/odt.py +0 -23
  521. langchain/document_loaders/onedrive.py +0 -23
  522. langchain/document_loaders/onedrive_file.py +0 -23
  523. langchain/document_loaders/onenote.py +0 -23
  524. langchain/document_loaders/open_city_data.py +0 -23
  525. langchain/document_loaders/org_mode.py +0 -25
  526. langchain/document_loaders/parsers/__init__.py +0 -58
  527. langchain/document_loaders/parsers/audio.py +0 -33
  528. langchain/document_loaders/parsers/docai.py +0 -30
  529. langchain/document_loaders/parsers/generic.py +0 -25
  530. langchain/document_loaders/parsers/grobid.py +0 -30
  531. langchain/document_loaders/parsers/html/__init__.py +0 -25
  532. langchain/document_loaders/parsers/html/bs4.py +0 -25
  533. langchain/document_loaders/parsers/language/__init__.py +0 -29
  534. langchain/document_loaders/parsers/language/cobol.py +0 -27
  535. langchain/document_loaders/parsers/language/code_segmenter.py +0 -29
  536. langchain/document_loaders/parsers/language/javascript.py +0 -29
  537. langchain/document_loaders/parsers/language/language_parser.py +0 -29
  538. langchain/document_loaders/parsers/language/python.py +0 -27
  539. langchain/document_loaders/parsers/msword.py +0 -25
  540. langchain/document_loaders/parsers/pdf.py +0 -50
  541. langchain/document_loaders/parsers/registry.py +0 -25
  542. langchain/document_loaders/parsers/txt.py +0 -23
  543. langchain/document_loaders/pdf.py +0 -65
  544. langchain/document_loaders/polars_dataframe.py +0 -23
  545. langchain/document_loaders/powerpoint.py +0 -25
  546. langchain/document_loaders/psychic.py +0 -23
  547. langchain/document_loaders/pubmed.py +0 -23
  548. langchain/document_loaders/pyspark_dataframe.py +0 -26
  549. langchain/document_loaders/python.py +0 -22
  550. langchain/document_loaders/quip.py +0 -23
  551. langchain/document_loaders/readthedocs.py +0 -23
  552. langchain/document_loaders/recursive_url_loader.py +0 -23
  553. langchain/document_loaders/reddit.py +0 -23
  554. langchain/document_loaders/roam.py +0 -23
  555. langchain/document_loaders/rocksetdb.py +0 -23
  556. langchain/document_loaders/rspace.py +0 -23
  557. langchain/document_loaders/rss.py +0 -23
  558. langchain/document_loaders/rst.py +0 -23
  559. langchain/document_loaders/rtf.py +0 -23
  560. langchain/document_loaders/s3_directory.py +0 -23
  561. langchain/document_loaders/s3_file.py +0 -23
  562. langchain/document_loaders/sharepoint.py +0 -23
  563. langchain/document_loaders/sitemap.py +0 -23
  564. langchain/document_loaders/slack_directory.py +0 -23
  565. langchain/document_loaders/snowflake_loader.py +0 -23
  566. langchain/document_loaders/spreedly.py +0 -23
  567. langchain/document_loaders/srt.py +0 -23
  568. langchain/document_loaders/stripe.py +0 -23
  569. langchain/document_loaders/telegram.py +0 -38
  570. langchain/document_loaders/tencent_cos_directory.py +0 -25
  571. langchain/document_loaders/tencent_cos_file.py +0 -23
  572. langchain/document_loaders/tensorflow_datasets.py +0 -23
  573. langchain/document_loaders/text.py +0 -23
  574. langchain/document_loaders/tomarkdown.py +0 -23
  575. langchain/document_loaders/toml.py +0 -23
  576. langchain/document_loaders/trello.py +0 -23
  577. langchain/document_loaders/tsv.py +0 -23
  578. langchain/document_loaders/twitter.py +0 -23
  579. langchain/document_loaders/unstructured.py +0 -54
  580. langchain/document_loaders/url.py +0 -23
  581. langchain/document_loaders/url_playwright.py +0 -33
  582. langchain/document_loaders/url_selenium.py +0 -23
  583. langchain/document_loaders/weather.py +0 -23
  584. langchain/document_loaders/web_base.py +0 -23
  585. langchain/document_loaders/whatsapp_chat.py +0 -28
  586. langchain/document_loaders/wikipedia.py +0 -23
  587. langchain/document_loaders/word_document.py +0 -30
  588. langchain/document_loaders/xml.py +0 -23
  589. langchain/document_loaders/xorbits.py +0 -23
  590. langchain/document_loaders/youtube.py +0 -33
  591. langchain/document_transformers/__init__.py +0 -77
  592. langchain/document_transformers/beautiful_soup_transformer.py +0 -25
  593. langchain/document_transformers/doctran_text_extract.py +0 -25
  594. langchain/document_transformers/doctran_text_qa.py +0 -25
  595. langchain/document_transformers/doctran_text_translate.py +0 -25
  596. langchain/document_transformers/embeddings_redundant_filter.py +0 -50
  597. langchain/document_transformers/google_translate.py +0 -25
  598. langchain/document_transformers/html2text.py +0 -25
  599. langchain/document_transformers/long_context_reorder.py +0 -23
  600. langchain/document_transformers/nuclia_text_transform.py +0 -25
  601. langchain/document_transformers/openai_functions.py +0 -32
  602. langchain/document_transformers/xsl/html_chunks_with_headers.xslt +0 -199
  603. langchain/embeddings/aleph_alpha.py +0 -30
  604. langchain/embeddings/awa.py +0 -23
  605. langchain/embeddings/azure_openai.py +0 -23
  606. langchain/embeddings/baidu_qianfan_endpoint.py +0 -23
  607. langchain/embeddings/bedrock.py +0 -23
  608. langchain/embeddings/bookend.py +0 -23
  609. langchain/embeddings/cache.py +0 -368
  610. langchain/embeddings/clarifai.py +0 -23
  611. langchain/embeddings/cloudflare_workersai.py +0 -29
  612. langchain/embeddings/cohere.py +0 -23
  613. langchain/embeddings/dashscope.py +0 -23
  614. langchain/embeddings/databricks.py +0 -23
  615. langchain/embeddings/deepinfra.py +0 -23
  616. langchain/embeddings/edenai.py +0 -23
  617. langchain/embeddings/elasticsearch.py +0 -23
  618. langchain/embeddings/embaas.py +0 -23
  619. langchain/embeddings/ernie.py +0 -23
  620. langchain/embeddings/fake.py +0 -30
  621. langchain/embeddings/fastembed.py +0 -23
  622. langchain/embeddings/google_palm.py +0 -23
  623. langchain/embeddings/gpt4all.py +0 -23
  624. langchain/embeddings/gradient_ai.py +0 -23
  625. langchain/embeddings/huggingface.py +0 -36
  626. langchain/embeddings/huggingface_hub.py +0 -23
  627. langchain/embeddings/infinity.py +0 -30
  628. langchain/embeddings/javelin_ai_gateway.py +0 -23
  629. langchain/embeddings/jina.py +0 -23
  630. langchain/embeddings/johnsnowlabs.py +0 -23
  631. langchain/embeddings/llamacpp.py +0 -23
  632. langchain/embeddings/llm_rails.py +0 -23
  633. langchain/embeddings/localai.py +0 -23
  634. langchain/embeddings/minimax.py +0 -23
  635. langchain/embeddings/mlflow.py +0 -23
  636. langchain/embeddings/mlflow_gateway.py +0 -23
  637. langchain/embeddings/modelscope_hub.py +0 -23
  638. langchain/embeddings/mosaicml.py +0 -23
  639. langchain/embeddings/nlpcloud.py +0 -23
  640. langchain/embeddings/octoai_embeddings.py +0 -23
  641. langchain/embeddings/ollama.py +0 -23
  642. langchain/embeddings/openai.py +0 -23
  643. langchain/embeddings/sagemaker_endpoint.py +0 -30
  644. langchain/embeddings/self_hosted.py +0 -23
  645. langchain/embeddings/self_hosted_hugging_face.py +0 -30
  646. langchain/embeddings/sentence_transformer.py +0 -21
  647. langchain/embeddings/spacy_embeddings.py +0 -23
  648. langchain/embeddings/tensorflow_hub.py +0 -23
  649. langchain/embeddings/vertexai.py +0 -23
  650. langchain/embeddings/voyageai.py +0 -23
  651. langchain/embeddings/xinference.py +0 -23
  652. langchain/env.py +0 -17
  653. langchain/evaluation/__init__.py +0 -128
  654. langchain/evaluation/agents/__init__.py +0 -5
  655. langchain/evaluation/agents/trajectory_eval_chain.py +0 -416
  656. langchain/evaluation/agents/trajectory_eval_prompt.py +0 -146
  657. langchain/evaluation/comparison/__init__.py +0 -36
  658. langchain/evaluation/comparison/eval_chain.py +0 -462
  659. langchain/evaluation/comparison/prompt.py +0 -59
  660. langchain/evaluation/criteria/__init__.py +0 -56
  661. langchain/evaluation/criteria/eval_chain.py +0 -606
  662. langchain/evaluation/criteria/prompt.py +0 -37
  663. langchain/evaluation/embedding_distance/__init__.py +0 -13
  664. langchain/evaluation/embedding_distance/base.py +0 -613
  665. langchain/evaluation/exact_match/__init__.py +0 -0
  666. langchain/evaluation/exact_match/base.py +0 -110
  667. langchain/evaluation/loading.py +0 -207
  668. langchain/evaluation/parsing/__init__.py +0 -0
  669. langchain/evaluation/parsing/base.py +0 -175
  670. langchain/evaluation/parsing/json_distance.py +0 -108
  671. langchain/evaluation/parsing/json_schema.py +0 -97
  672. langchain/evaluation/qa/__init__.py +0 -10
  673. langchain/evaluation/qa/eval_chain.py +0 -372
  674. langchain/evaluation/qa/eval_prompt.py +0 -78
  675. langchain/evaluation/qa/generate_chain.py +0 -36
  676. langchain/evaluation/qa/generate_prompt.py +0 -21
  677. langchain/evaluation/regex_match/__init__.py +0 -0
  678. langchain/evaluation/regex_match/base.py +0 -94
  679. langchain/evaluation/schema.py +0 -491
  680. langchain/evaluation/scoring/__init__.py +0 -31
  681. langchain/evaluation/scoring/eval_chain.py +0 -476
  682. langchain/evaluation/scoring/prompt.py +0 -53
  683. langchain/evaluation/string_distance/__init__.py +0 -13
  684. langchain/evaluation/string_distance/base.py +0 -472
  685. langchain/example_generator.py +0 -5
  686. langchain/formatting.py +0 -5
  687. langchain/globals.py +0 -180
  688. langchain/graphs/__init__.py +0 -57
  689. langchain/graphs/arangodb_graph.py +0 -28
  690. langchain/graphs/falkordb_graph.py +0 -23
  691. langchain/graphs/graph_document.py +0 -33
  692. langchain/graphs/graph_store.py +0 -23
  693. langchain/graphs/hugegraph.py +0 -23
  694. langchain/graphs/kuzu_graph.py +0 -23
  695. langchain/graphs/memgraph_graph.py +0 -23
  696. langchain/graphs/nebula_graph.py +0 -23
  697. langchain/graphs/neo4j_graph.py +0 -23
  698. langchain/graphs/neptune_graph.py +0 -23
  699. langchain/graphs/networkx_graph.py +0 -36
  700. langchain/graphs/rdf_graph.py +0 -23
  701. langchain/hub.py +0 -131
  702. langchain/indexes/__init__.py +0 -50
  703. langchain/indexes/_api.py +0 -5
  704. langchain/indexes/_sql_record_manager.py +0 -539
  705. langchain/indexes/graph.py +0 -28
  706. langchain/indexes/prompts/__init__.py +0 -13
  707. langchain/indexes/prompts/entity_extraction.py +0 -39
  708. langchain/indexes/prompts/entity_summarization.py +0 -24
  709. langchain/indexes/prompts/knowledge_triplet_extraction.py +0 -36
  710. langchain/indexes/vectorstore.py +0 -269
  711. langchain/input.py +0 -15
  712. langchain/llms/__init__.py +0 -734
  713. langchain/llms/ai21.py +0 -28
  714. langchain/llms/aleph_alpha.py +0 -23
  715. langchain/llms/amazon_api_gateway.py +0 -23
  716. langchain/llms/anthropic.py +0 -23
  717. langchain/llms/anyscale.py +0 -23
  718. langchain/llms/arcee.py +0 -23
  719. langchain/llms/aviary.py +0 -23
  720. langchain/llms/azureml_endpoint.py +0 -48
  721. langchain/llms/baidu_qianfan_endpoint.py +0 -23
  722. langchain/llms/bananadev.py +0 -23
  723. langchain/llms/base.py +0 -20
  724. langchain/llms/baseten.py +0 -23
  725. langchain/llms/beam.py +0 -23
  726. langchain/llms/bedrock.py +0 -28
  727. langchain/llms/bittensor.py +0 -23
  728. langchain/llms/cerebriumai.py +0 -23
  729. langchain/llms/chatglm.py +0 -23
  730. langchain/llms/clarifai.py +0 -23
  731. langchain/llms/cloudflare_workersai.py +0 -25
  732. langchain/llms/cohere.py +0 -23
  733. langchain/llms/ctransformers.py +0 -23
  734. langchain/llms/ctranslate2.py +0 -23
  735. langchain/llms/databricks.py +0 -23
  736. langchain/llms/deepinfra.py +0 -23
  737. langchain/llms/deepsparse.py +0 -23
  738. langchain/llms/edenai.py +0 -23
  739. langchain/llms/fake.py +0 -28
  740. langchain/llms/fireworks.py +0 -23
  741. langchain/llms/forefrontai.py +0 -23
  742. langchain/llms/gigachat.py +0 -23
  743. langchain/llms/google_palm.py +0 -23
  744. langchain/llms/gooseai.py +0 -23
  745. langchain/llms/gpt4all.py +0 -23
  746. langchain/llms/gradient_ai.py +0 -28
  747. langchain/llms/grammars/json.gbnf +0 -29
  748. langchain/llms/grammars/list.gbnf +0 -14
  749. langchain/llms/huggingface_endpoint.py +0 -23
  750. langchain/llms/huggingface_hub.py +0 -23
  751. langchain/llms/huggingface_pipeline.py +0 -23
  752. langchain/llms/huggingface_text_gen_inference.py +0 -23
  753. langchain/llms/human.py +0 -23
  754. langchain/llms/javelin_ai_gateway.py +0 -28
  755. langchain/llms/koboldai.py +0 -23
  756. langchain/llms/llamacpp.py +0 -23
  757. langchain/llms/loading.py +0 -27
  758. langchain/llms/manifest.py +0 -23
  759. langchain/llms/minimax.py +0 -23
  760. langchain/llms/mlflow.py +0 -23
  761. langchain/llms/mlflow_ai_gateway.py +0 -23
  762. langchain/llms/modal.py +0 -23
  763. langchain/llms/mosaicml.py +0 -23
  764. langchain/llms/nlpcloud.py +0 -23
  765. langchain/llms/octoai_endpoint.py +0 -23
  766. langchain/llms/ollama.py +0 -23
  767. langchain/llms/opaqueprompts.py +0 -23
  768. langchain/llms/openai.py +0 -32
  769. langchain/llms/openllm.py +0 -23
  770. langchain/llms/openlm.py +0 -23
  771. langchain/llms/pai_eas_endpoint.py +0 -23
  772. langchain/llms/petals.py +0 -23
  773. langchain/llms/pipelineai.py +0 -23
  774. langchain/llms/predibase.py +0 -23
  775. langchain/llms/predictionguard.py +0 -23
  776. langchain/llms/promptlayer_openai.py +0 -27
  777. langchain/llms/replicate.py +0 -23
  778. langchain/llms/rwkv.py +0 -23
  779. langchain/llms/sagemaker_endpoint.py +0 -28
  780. langchain/llms/self_hosted.py +0 -23
  781. langchain/llms/self_hosted_hugging_face.py +0 -23
  782. langchain/llms/stochasticai.py +0 -23
  783. langchain/llms/symblai_nebula.py +0 -23
  784. langchain/llms/textgen.py +0 -23
  785. langchain/llms/titan_takeoff.py +0 -23
  786. langchain/llms/titan_takeoff_pro.py +0 -23
  787. langchain/llms/together.py +0 -23
  788. langchain/llms/tongyi.py +0 -23
  789. langchain/llms/utils.py +0 -23
  790. langchain/llms/vertexai.py +0 -27
  791. langchain/llms/vllm.py +0 -27
  792. langchain/llms/volcengine_maas.py +0 -28
  793. langchain/llms/watsonxllm.py +0 -23
  794. langchain/llms/writer.py +0 -23
  795. langchain/llms/xinference.py +0 -23
  796. langchain/llms/yandex.py +0 -23
  797. langchain/load/__init__.py +0 -11
  798. langchain/load/dump.py +0 -3
  799. langchain/load/load.py +0 -3
  800. langchain/load/serializable.py +0 -19
  801. langchain/memory/__init__.py +0 -153
  802. langchain/memory/buffer.py +0 -178
  803. langchain/memory/buffer_window.py +0 -62
  804. langchain/memory/chat_memory.py +0 -104
  805. langchain/memory/chat_message_histories/__init__.py +0 -84
  806. langchain/memory/chat_message_histories/astradb.py +0 -25
  807. langchain/memory/chat_message_histories/cassandra.py +0 -25
  808. langchain/memory/chat_message_histories/cosmos_db.py +0 -25
  809. langchain/memory/chat_message_histories/dynamodb.py +0 -25
  810. langchain/memory/chat_message_histories/elasticsearch.py +0 -27
  811. langchain/memory/chat_message_histories/file.py +0 -25
  812. langchain/memory/chat_message_histories/firestore.py +0 -25
  813. langchain/memory/chat_message_histories/in_memory.py +0 -5
  814. langchain/memory/chat_message_histories/momento.py +0 -25
  815. langchain/memory/chat_message_histories/mongodb.py +0 -25
  816. langchain/memory/chat_message_histories/neo4j.py +0 -25
  817. langchain/memory/chat_message_histories/postgres.py +0 -25
  818. langchain/memory/chat_message_histories/redis.py +0 -25
  819. langchain/memory/chat_message_histories/rocksetdb.py +0 -25
  820. langchain/memory/chat_message_histories/singlestoredb.py +0 -27
  821. langchain/memory/chat_message_histories/sql.py +0 -33
  822. langchain/memory/chat_message_histories/streamlit.py +0 -25
  823. langchain/memory/chat_message_histories/upstash_redis.py +0 -27
  824. langchain/memory/chat_message_histories/xata.py +0 -25
  825. langchain/memory/chat_message_histories/zep.py +0 -25
  826. langchain/memory/combined.py +0 -85
  827. langchain/memory/entity.py +0 -611
  828. langchain/memory/kg.py +0 -23
  829. langchain/memory/motorhead_memory.py +0 -23
  830. langchain/memory/prompt.py +0 -164
  831. langchain/memory/readonly.py +0 -24
  832. langchain/memory/simple.py +0 -27
  833. langchain/memory/summary.py +0 -170
  834. langchain/memory/summary_buffer.py +0 -151
  835. langchain/memory/token_buffer.py +0 -74
  836. langchain/memory/utils.py +0 -21
  837. langchain/memory/vectorstore.py +0 -120
  838. langchain/memory/vectorstore_token_buffer_memory.py +0 -184
  839. langchain/memory/zep_memory.py +0 -23
  840. langchain/model_laboratory.py +0 -99
  841. langchain/output_parsers/__init__.py +0 -87
  842. langchain/output_parsers/boolean.py +0 -54
  843. langchain/output_parsers/combining.py +0 -59
  844. langchain/output_parsers/datetime.py +0 -58
  845. langchain/output_parsers/enum.py +0 -45
  846. langchain/output_parsers/ernie_functions.py +0 -45
  847. langchain/output_parsers/fix.py +0 -155
  848. langchain/output_parsers/format_instructions.py +0 -79
  849. langchain/output_parsers/json.py +0 -15
  850. langchain/output_parsers/list.py +0 -13
  851. langchain/output_parsers/loading.py +0 -22
  852. langchain/output_parsers/openai_functions.py +0 -13
  853. langchain/output_parsers/openai_tools.py +0 -7
  854. langchain/output_parsers/pandas_dataframe.py +0 -171
  855. langchain/output_parsers/prompts.py +0 -21
  856. langchain/output_parsers/pydantic.py +0 -3
  857. langchain/output_parsers/rail_parser.py +0 -25
  858. langchain/output_parsers/regex.py +0 -41
  859. langchain/output_parsers/regex_dict.py +0 -43
  860. langchain/output_parsers/retry.py +0 -316
  861. langchain/output_parsers/structured.py +0 -116
  862. langchain/output_parsers/xml.py +0 -3
  863. langchain/output_parsers/yaml.py +0 -77
  864. langchain/prompts/__init__.py +0 -102
  865. langchain/prompts/base.py +0 -21
  866. langchain/prompts/chat.py +0 -37
  867. langchain/prompts/example_selector/__init__.py +0 -42
  868. langchain/prompts/example_selector/base.py +0 -3
  869. langchain/prompts/example_selector/length_based.py +0 -5
  870. langchain/prompts/example_selector/ngram_overlap.py +0 -32
  871. langchain/prompts/example_selector/semantic_similarity.py +0 -11
  872. langchain/prompts/few_shot.py +0 -11
  873. langchain/prompts/few_shot_with_templates.py +0 -3
  874. langchain/prompts/loading.py +0 -23
  875. langchain/prompts/pipeline.py +0 -3
  876. langchain/prompts/prompt.py +0 -6
  877. langchain/pydantic_v1/__init__.py +0 -38
  878. langchain/pydantic_v1/dataclasses.py +0 -20
  879. langchain/pydantic_v1/main.py +0 -20
  880. langchain/python.py +0 -19
  881. langchain/requests.py +0 -35
  882. langchain/retrievers/__init__.py +0 -178
  883. langchain/retrievers/arcee.py +0 -23
  884. langchain/retrievers/arxiv.py +0 -23
  885. langchain/retrievers/azure_ai_search.py +0 -30
  886. langchain/retrievers/bedrock.py +0 -33
  887. langchain/retrievers/bm25.py +0 -28
  888. langchain/retrievers/chaindesk.py +0 -23
  889. langchain/retrievers/chatgpt_plugin_retriever.py +0 -23
  890. langchain/retrievers/cohere_rag_retriever.py +0 -23
  891. langchain/retrievers/contextual_compression.py +0 -81
  892. langchain/retrievers/databerry.py +0 -23
  893. langchain/retrievers/docarray.py +0 -28
  894. langchain/retrievers/document_compressors/__init__.py +0 -44
  895. langchain/retrievers/document_compressors/base.py +0 -82
  896. langchain/retrievers/document_compressors/chain_extract.py +0 -123
  897. langchain/retrievers/document_compressors/chain_extract_prompt.py +0 -10
  898. langchain/retrievers/document_compressors/chain_filter.py +0 -133
  899. langchain/retrievers/document_compressors/chain_filter_prompt.py +0 -8
  900. langchain/retrievers/document_compressors/cohere_rerank.py +0 -126
  901. langchain/retrievers/document_compressors/cross_encoder.py +0 -16
  902. langchain/retrievers/document_compressors/cross_encoder_rerank.py +0 -50
  903. langchain/retrievers/document_compressors/embeddings_filter.py +0 -140
  904. langchain/retrievers/document_compressors/flashrank_rerank.py +0 -27
  905. langchain/retrievers/document_compressors/listwise_rerank.py +0 -145
  906. langchain/retrievers/elastic_search_bm25.py +0 -23
  907. langchain/retrievers/embedchain.py +0 -23
  908. langchain/retrievers/ensemble.py +0 -336
  909. langchain/retrievers/google_cloud_documentai_warehouse.py +0 -25
  910. langchain/retrievers/google_vertex_ai_search.py +0 -33
  911. langchain/retrievers/kay.py +0 -23
  912. langchain/retrievers/kendra.py +0 -66
  913. langchain/retrievers/knn.py +0 -23
  914. langchain/retrievers/llama_index.py +0 -30
  915. langchain/retrievers/merger_retriever.py +0 -123
  916. langchain/retrievers/metal.py +0 -23
  917. langchain/retrievers/milvus.py +0 -28
  918. langchain/retrievers/multi_query.py +0 -233
  919. langchain/retrievers/multi_vector.py +0 -135
  920. langchain/retrievers/outline.py +0 -23
  921. langchain/retrievers/parent_document_retriever.py +0 -172
  922. langchain/retrievers/pinecone_hybrid_search.py +0 -23
  923. langchain/retrievers/pubmed.py +0 -23
  924. langchain/retrievers/pupmed.py +0 -23
  925. langchain/retrievers/re_phraser.py +0 -89
  926. langchain/retrievers/remote_retriever.py +0 -23
  927. langchain/retrievers/self_query/__init__.py +0 -0
  928. langchain/retrievers/self_query/astradb.py +0 -23
  929. langchain/retrievers/self_query/base.py +0 -416
  930. langchain/retrievers/self_query/chroma.py +0 -23
  931. langchain/retrievers/self_query/dashvector.py +0 -23
  932. langchain/retrievers/self_query/databricks_vector_search.py +0 -27
  933. langchain/retrievers/self_query/deeplake.py +0 -27
  934. langchain/retrievers/self_query/dingo.py +0 -23
  935. langchain/retrievers/self_query/elasticsearch.py +0 -25
  936. langchain/retrievers/self_query/milvus.py +0 -27
  937. langchain/retrievers/self_query/mongodb_atlas.py +0 -25
  938. langchain/retrievers/self_query/myscale.py +0 -23
  939. langchain/retrievers/self_query/opensearch.py +0 -23
  940. langchain/retrievers/self_query/pgvector.py +0 -23
  941. langchain/retrievers/self_query/pinecone.py +0 -23
  942. langchain/retrievers/self_query/qdrant.py +0 -23
  943. langchain/retrievers/self_query/redis.py +0 -23
  944. langchain/retrievers/self_query/supabase.py +0 -23
  945. langchain/retrievers/self_query/tencentvectordb.py +0 -27
  946. langchain/retrievers/self_query/timescalevector.py +0 -27
  947. langchain/retrievers/self_query/vectara.py +0 -27
  948. langchain/retrievers/self_query/weaviate.py +0 -23
  949. langchain/retrievers/svm.py +0 -23
  950. langchain/retrievers/tavily_search_api.py +0 -28
  951. langchain/retrievers/tfidf.py +0 -23
  952. langchain/retrievers/time_weighted_retriever.py +0 -196
  953. langchain/retrievers/vespa_retriever.py +0 -23
  954. langchain/retrievers/weaviate_hybrid_search.py +0 -23
  955. langchain/retrievers/web_research.py +0 -29
  956. langchain/retrievers/wikipedia.py +0 -23
  957. langchain/retrievers/you.py +0 -23
  958. langchain/retrievers/zep.py +0 -30
  959. langchain/retrievers/zilliz.py +0 -28
  960. langchain/runnables/__init__.py +0 -18
  961. langchain/runnables/hub.py +0 -44
  962. langchain/runnables/openai_functions.py +0 -57
  963. langchain/schema/__init__.py +0 -82
  964. langchain/schema/agent.py +0 -3
  965. langchain/schema/cache.py +0 -3
  966. langchain/schema/callbacks/__init__.py +0 -0
  967. langchain/schema/callbacks/base.py +0 -23
  968. langchain/schema/callbacks/manager.py +0 -55
  969. langchain/schema/callbacks/stdout.py +0 -3
  970. langchain/schema/callbacks/streaming_stdout.py +0 -3
  971. langchain/schema/callbacks/tracers/__init__.py +0 -0
  972. langchain/schema/callbacks/tracers/base.py +0 -4
  973. langchain/schema/callbacks/tracers/evaluation.py +0 -6
  974. langchain/schema/callbacks/tracers/langchain.py +0 -8
  975. langchain/schema/callbacks/tracers/langchain_v1.py +0 -3
  976. langchain/schema/callbacks/tracers/log_stream.py +0 -9
  977. langchain/schema/callbacks/tracers/root_listeners.py +0 -3
  978. langchain/schema/callbacks/tracers/run_collector.py +0 -3
  979. langchain/schema/callbacks/tracers/schemas.py +0 -27
  980. langchain/schema/callbacks/tracers/stdout.py +0 -13
  981. langchain/schema/chat.py +0 -3
  982. langchain/schema/chat_history.py +0 -3
  983. langchain/schema/document.py +0 -3
  984. langchain/schema/embeddings.py +0 -3
  985. langchain/schema/exceptions.py +0 -3
  986. langchain/schema/language_model.py +0 -15
  987. langchain/schema/memory.py +0 -3
  988. langchain/schema/messages.py +0 -51
  989. langchain/schema/output.py +0 -19
  990. langchain/schema/output_parser.py +0 -25
  991. langchain/schema/prompt.py +0 -3
  992. langchain/schema/prompt_template.py +0 -3
  993. langchain/schema/retriever.py +0 -3
  994. langchain/schema/runnable/__init__.py +0 -58
  995. langchain/schema/runnable/base.py +0 -38
  996. langchain/schema/runnable/branch.py +0 -3
  997. langchain/schema/runnable/config.py +0 -27
  998. langchain/schema/runnable/configurable.py +0 -15
  999. langchain/schema/runnable/fallbacks.py +0 -3
  1000. langchain/schema/runnable/history.py +0 -11
  1001. langchain/schema/runnable/passthrough.py +0 -8
  1002. langchain/schema/runnable/retry.py +0 -3
  1003. langchain/schema/runnable/router.py +0 -3
  1004. langchain/schema/runnable/utils.py +0 -51
  1005. langchain/schema/storage.py +0 -3
  1006. langchain/schema/vectorstore.py +0 -3
  1007. langchain/serpapi.py +0 -25
  1008. langchain/smith/__init__.py +0 -103
  1009. langchain/smith/evaluation/__init__.py +0 -68
  1010. langchain/smith/evaluation/config.py +0 -365
  1011. langchain/smith/evaluation/name_generation.py +0 -727
  1012. langchain/smith/evaluation/progress.py +0 -146
  1013. langchain/smith/evaluation/runner_utils.py +0 -1689
  1014. langchain/smith/evaluation/string_run_evaluator.py +0 -467
  1015. langchain/sql_database.py +0 -25
  1016. langchain/storage/__init__.py +0 -57
  1017. langchain/storage/_lc_store.py +0 -91
  1018. langchain/storage/encoder_backed.py +0 -128
  1019. langchain/storage/exceptions.py +0 -3
  1020. langchain/storage/file_system.py +0 -176
  1021. langchain/storage/in_memory.py +0 -13
  1022. langchain/storage/redis.py +0 -23
  1023. langchain/storage/upstash_redis.py +0 -27
  1024. langchain/text_splitter.py +0 -50
  1025. langchain/tools/ainetwork/__init__.py +0 -0
  1026. langchain/tools/ainetwork/app.py +0 -30
  1027. langchain/tools/ainetwork/base.py +0 -27
  1028. langchain/tools/ainetwork/owner.py +0 -28
  1029. langchain/tools/ainetwork/rule.py +0 -28
  1030. langchain/tools/ainetwork/transfer.py +0 -28
  1031. langchain/tools/ainetwork/value.py +0 -28
  1032. langchain/tools/amadeus/__init__.py +0 -30
  1033. langchain/tools/amadeus/base.py +0 -23
  1034. langchain/tools/amadeus/closest_airport.py +0 -30
  1035. langchain/tools/amadeus/flight_search.py +0 -30
  1036. langchain/tools/arxiv/__init__.py +0 -1
  1037. langchain/tools/arxiv/tool.py +0 -28
  1038. langchain/tools/azure_cognitive_services/__init__.py +0 -41
  1039. langchain/tools/azure_cognitive_services/form_recognizer.py +0 -23
  1040. langchain/tools/azure_cognitive_services/image_analysis.py +0 -23
  1041. langchain/tools/azure_cognitive_services/speech2text.py +0 -23
  1042. langchain/tools/azure_cognitive_services/text2speech.py +0 -23
  1043. langchain/tools/azure_cognitive_services/text_analytics_health.py +0 -23
  1044. langchain/tools/base.py +0 -19
  1045. langchain/tools/bearly/__init__.py +0 -0
  1046. langchain/tools/bearly/tool.py +0 -33
  1047. langchain/tools/bing_search/__init__.py +0 -29
  1048. langchain/tools/bing_search/tool.py +0 -27
  1049. langchain/tools/brave_search/__init__.py +0 -0
  1050. langchain/tools/brave_search/tool.py +0 -23
  1051. langchain/tools/clickup/__init__.py +0 -0
  1052. langchain/tools/clickup/tool.py +0 -23
  1053. langchain/tools/convert_to_openai.py +0 -4
  1054. langchain/tools/dataforseo_api_search/__init__.py +0 -34
  1055. langchain/tools/dataforseo_api_search/tool.py +0 -32
  1056. langchain/tools/ddg_search/__init__.py +0 -25
  1057. langchain/tools/ddg_search/tool.py +0 -32
  1058. langchain/tools/e2b_data_analysis/__init__.py +0 -0
  1059. langchain/tools/e2b_data_analysis/tool.py +0 -33
  1060. langchain/tools/edenai/__init__.py +0 -50
  1061. langchain/tools/edenai/audio_speech_to_text.py +0 -23
  1062. langchain/tools/edenai/audio_text_to_speech.py +0 -23
  1063. langchain/tools/edenai/edenai_base_tool.py +0 -23
  1064. langchain/tools/edenai/image_explicitcontent.py +0 -23
  1065. langchain/tools/edenai/image_objectdetection.py +0 -23
  1066. langchain/tools/edenai/ocr_identityparser.py +0 -23
  1067. langchain/tools/edenai/ocr_invoiceparser.py +0 -23
  1068. langchain/tools/edenai/text_moderation.py +0 -23
  1069. langchain/tools/eleven_labs/__init__.py +0 -25
  1070. langchain/tools/eleven_labs/models.py +0 -23
  1071. langchain/tools/eleven_labs/text2speech.py +0 -23
  1072. langchain/tools/file_management/__init__.py +0 -47
  1073. langchain/tools/file_management/copy.py +0 -28
  1074. langchain/tools/file_management/delete.py +0 -28
  1075. langchain/tools/file_management/file_search.py +0 -28
  1076. langchain/tools/file_management/list_dir.py +0 -28
  1077. langchain/tools/file_management/move.py +0 -28
  1078. langchain/tools/file_management/read.py +0 -28
  1079. langchain/tools/file_management/write.py +0 -28
  1080. langchain/tools/github/__init__.py +0 -1
  1081. langchain/tools/github/tool.py +0 -23
  1082. langchain/tools/gitlab/__init__.py +0 -1
  1083. langchain/tools/gitlab/tool.py +0 -23
  1084. langchain/tools/gmail/__init__.py +0 -41
  1085. langchain/tools/gmail/base.py +0 -23
  1086. langchain/tools/gmail/create_draft.py +0 -28
  1087. langchain/tools/gmail/get_message.py +0 -28
  1088. langchain/tools/gmail/get_thread.py +0 -28
  1089. langchain/tools/gmail/search.py +0 -30
  1090. langchain/tools/gmail/send_message.py +0 -28
  1091. langchain/tools/golden_query/__init__.py +0 -25
  1092. langchain/tools/golden_query/tool.py +0 -23
  1093. langchain/tools/google_cloud/__init__.py +0 -25
  1094. langchain/tools/google_cloud/texttospeech.py +0 -23
  1095. langchain/tools/google_finance/__init__.py +0 -27
  1096. langchain/tools/google_finance/tool.py +0 -25
  1097. langchain/tools/google_jobs/__init__.py +0 -25
  1098. langchain/tools/google_jobs/tool.py +0 -23
  1099. langchain/tools/google_lens/__init__.py +0 -25
  1100. langchain/tools/google_lens/tool.py +0 -23
  1101. langchain/tools/google_places/__init__.py +0 -25
  1102. langchain/tools/google_places/tool.py +0 -28
  1103. langchain/tools/google_scholar/__init__.py +0 -27
  1104. langchain/tools/google_scholar/tool.py +0 -25
  1105. langchain/tools/google_search/__init__.py +0 -29
  1106. langchain/tools/google_search/tool.py +0 -27
  1107. langchain/tools/google_serper/__init__.py +0 -30
  1108. langchain/tools/google_serper/tool.py +0 -27
  1109. langchain/tools/google_trends/__init__.py +0 -27
  1110. langchain/tools/google_trends/tool.py +0 -25
  1111. langchain/tools/graphql/__init__.py +0 -1
  1112. langchain/tools/graphql/tool.py +0 -23
  1113. langchain/tools/human/__init__.py +0 -25
  1114. langchain/tools/human/tool.py +0 -23
  1115. langchain/tools/ifttt.py +0 -23
  1116. langchain/tools/interaction/__init__.py +0 -1
  1117. langchain/tools/interaction/tool.py +0 -23
  1118. langchain/tools/jira/__init__.py +0 -1
  1119. langchain/tools/jira/tool.py +0 -42
  1120. langchain/tools/json/__init__.py +0 -1
  1121. langchain/tools/json/tool.py +0 -52
  1122. langchain/tools/memorize/__init__.py +0 -25
  1123. langchain/tools/memorize/tool.py +0 -27
  1124. langchain/tools/merriam_webster/__init__.py +0 -1
  1125. langchain/tools/merriam_webster/tool.py +0 -23
  1126. langchain/tools/metaphor_search/__init__.py +0 -25
  1127. langchain/tools/metaphor_search/tool.py +0 -23
  1128. langchain/tools/multion/__init__.py +0 -33
  1129. langchain/tools/multion/close_session.py +0 -30
  1130. langchain/tools/multion/create_session.py +0 -30
  1131. langchain/tools/multion/update_session.py +0 -30
  1132. langchain/tools/nasa/__init__.py +0 -0
  1133. langchain/tools/nasa/tool.py +0 -23
  1134. langchain/tools/nuclia/__init__.py +0 -23
  1135. langchain/tools/nuclia/tool.py +0 -27
  1136. langchain/tools/office365/__init__.py +0 -41
  1137. langchain/tools/office365/base.py +0 -23
  1138. langchain/tools/office365/create_draft_message.py +0 -32
  1139. langchain/tools/office365/events_search.py +0 -28
  1140. langchain/tools/office365/messages_search.py +0 -28
  1141. langchain/tools/office365/send_event.py +0 -28
  1142. langchain/tools/office365/send_message.py +0 -28
  1143. langchain/tools/openapi/__init__.py +0 -0
  1144. langchain/tools/openapi/utils/__init__.py +0 -0
  1145. langchain/tools/openapi/utils/api_models.py +0 -54
  1146. langchain/tools/openapi/utils/openapi_utils.py +0 -30
  1147. langchain/tools/openweathermap/__init__.py +0 -25
  1148. langchain/tools/openweathermap/tool.py +0 -23
  1149. langchain/tools/playwright/__init__.py +0 -47
  1150. langchain/tools/playwright/base.py +0 -23
  1151. langchain/tools/playwright/click.py +0 -28
  1152. langchain/tools/playwright/current_page.py +0 -23
  1153. langchain/tools/playwright/extract_hyperlinks.py +0 -32
  1154. langchain/tools/playwright/extract_text.py +0 -23
  1155. langchain/tools/playwright/get_elements.py +0 -28
  1156. langchain/tools/playwright/navigate.py +0 -28
  1157. langchain/tools/playwright/navigate_back.py +0 -23
  1158. langchain/tools/plugin.py +0 -32
  1159. langchain/tools/powerbi/__init__.py +0 -1
  1160. langchain/tools/powerbi/tool.py +0 -33
  1161. langchain/tools/pubmed/__init__.py +0 -1
  1162. langchain/tools/pubmed/tool.py +0 -23
  1163. langchain/tools/python/__init__.py +0 -13
  1164. langchain/tools/reddit_search/__init__.py +0 -0
  1165. langchain/tools/reddit_search/tool.py +0 -27
  1166. langchain/tools/render.py +0 -23
  1167. langchain/tools/requests/__init__.py +0 -1
  1168. langchain/tools/requests/tool.py +0 -42
  1169. langchain/tools/retriever.py +0 -11
  1170. langchain/tools/scenexplain/__init__.py +0 -1
  1171. langchain/tools/scenexplain/tool.py +0 -28
  1172. langchain/tools/searchapi/__init__.py +0 -30
  1173. langchain/tools/searchapi/tool.py +0 -27
  1174. langchain/tools/searx_search/__init__.py +0 -0
  1175. langchain/tools/searx_search/tool.py +0 -27
  1176. langchain/tools/shell/__init__.py +0 -25
  1177. langchain/tools/shell/tool.py +0 -28
  1178. langchain/tools/slack/__init__.py +0 -38
  1179. langchain/tools/slack/base.py +0 -23
  1180. langchain/tools/slack/get_channel.py +0 -23
  1181. langchain/tools/slack/get_message.py +0 -28
  1182. langchain/tools/slack/schedule_message.py +0 -28
  1183. langchain/tools/slack/send_message.py +0 -28
  1184. langchain/tools/sleep/__init__.py +0 -1
  1185. langchain/tools/sleep/tool.py +0 -28
  1186. langchain/tools/spark_sql/__init__.py +0 -1
  1187. langchain/tools/spark_sql/tool.py +0 -39
  1188. langchain/tools/sql_database/__init__.py +0 -1
  1189. langchain/tools/sql_database/prompt.py +0 -24
  1190. langchain/tools/sql_database/tool.py +0 -39
  1191. langchain/tools/stackexchange/__init__.py +0 -1
  1192. langchain/tools/stackexchange/tool.py +0 -23
  1193. langchain/tools/steam/__init__.py +0 -1
  1194. langchain/tools/steam/tool.py +0 -23
  1195. langchain/tools/steamship_image_generation/__init__.py +0 -25
  1196. langchain/tools/steamship_image_generation/tool.py +0 -28
  1197. langchain/tools/tavily_search/__init__.py +0 -32
  1198. langchain/tools/tavily_search/tool.py +0 -33
  1199. langchain/tools/vectorstore/__init__.py +0 -1
  1200. langchain/tools/vectorstore/tool.py +0 -30
  1201. langchain/tools/wikipedia/__init__.py +0 -1
  1202. langchain/tools/wikipedia/tool.py +0 -23
  1203. langchain/tools/wolfram_alpha/__init__.py +0 -25
  1204. langchain/tools/wolfram_alpha/tool.py +0 -23
  1205. langchain/tools/yahoo_finance_news.py +0 -23
  1206. langchain/tools/youtube/__init__.py +0 -0
  1207. langchain/tools/youtube/search.py +0 -23
  1208. langchain/tools/zapier/__init__.py +0 -29
  1209. langchain/tools/zapier/tool.py +0 -49
  1210. langchain/utilities/__init__.py +0 -168
  1211. langchain/utilities/alpha_vantage.py +0 -23
  1212. langchain/utilities/anthropic.py +0 -30
  1213. langchain/utilities/apify.py +0 -23
  1214. langchain/utilities/arcee.py +0 -45
  1215. langchain/utilities/arxiv.py +0 -23
  1216. langchain/utilities/asyncio.py +0 -11
  1217. langchain/utilities/awslambda.py +0 -23
  1218. langchain/utilities/bibtex.py +0 -23
  1219. langchain/utilities/bing_search.py +0 -23
  1220. langchain/utilities/brave_search.py +0 -23
  1221. langchain/utilities/clickup.py +0 -45
  1222. langchain/utilities/dalle_image_generator.py +0 -25
  1223. langchain/utilities/dataforseo_api_search.py +0 -25
  1224. langchain/utilities/duckduckgo_search.py +0 -23
  1225. langchain/utilities/github.py +0 -23
  1226. langchain/utilities/gitlab.py +0 -23
  1227. langchain/utilities/golden_query.py +0 -23
  1228. langchain/utilities/google_finance.py +0 -23
  1229. langchain/utilities/google_jobs.py +0 -23
  1230. langchain/utilities/google_lens.py +0 -23
  1231. langchain/utilities/google_places_api.py +0 -23
  1232. langchain/utilities/google_scholar.py +0 -23
  1233. langchain/utilities/google_search.py +0 -23
  1234. langchain/utilities/google_serper.py +0 -23
  1235. langchain/utilities/google_trends.py +0 -23
  1236. langchain/utilities/graphql.py +0 -23
  1237. langchain/utilities/jira.py +0 -23
  1238. langchain/utilities/loading.py +0 -4
  1239. langchain/utilities/max_compute.py +0 -23
  1240. langchain/utilities/merriam_webster.py +0 -23
  1241. langchain/utilities/metaphor_search.py +0 -23
  1242. langchain/utilities/nasa.py +0 -23
  1243. langchain/utilities/opaqueprompts.py +0 -27
  1244. langchain/utilities/openapi.py +0 -28
  1245. langchain/utilities/openweathermap.py +0 -23
  1246. langchain/utilities/outline.py +0 -23
  1247. langchain/utilities/portkey.py +0 -23
  1248. langchain/utilities/powerbi.py +0 -23
  1249. langchain/utilities/pubmed.py +0 -23
  1250. langchain/utilities/python.py +0 -19
  1251. langchain/utilities/reddit_search.py +0 -25
  1252. langchain/utilities/redis.py +0 -33
  1253. langchain/utilities/requests.py +0 -27
  1254. langchain/utilities/scenexplain.py +0 -23
  1255. langchain/utilities/searchapi.py +0 -23
  1256. langchain/utilities/searx_search.py +0 -28
  1257. langchain/utilities/serpapi.py +0 -28
  1258. langchain/utilities/spark_sql.py +0 -23
  1259. langchain/utilities/sql_database.py +0 -28
  1260. langchain/utilities/stackexchange.py +0 -23
  1261. langchain/utilities/steam.py +0 -23
  1262. langchain/utilities/tavily_search.py +0 -25
  1263. langchain/utilities/tensorflow_datasets.py +0 -23
  1264. langchain/utilities/twilio.py +0 -23
  1265. langchain/utilities/vertexai.py +0 -36
  1266. langchain/utilities/wikipedia.py +0 -23
  1267. langchain/utilities/wolfram_alpha.py +0 -23
  1268. langchain/utilities/zapier.py +0 -23
  1269. langchain/utils/__init__.py +0 -77
  1270. langchain/utils/aiter.py +0 -3
  1271. langchain/utils/env.py +0 -3
  1272. langchain/utils/ernie_functions.py +0 -36
  1273. langchain/utils/formatting.py +0 -3
  1274. langchain/utils/html.py +0 -19
  1275. langchain/utils/input.py +0 -8
  1276. langchain/utils/iter.py +0 -3
  1277. langchain/utils/json_schema.py +0 -11
  1278. langchain/utils/loading.py +0 -3
  1279. langchain/utils/math.py +0 -32
  1280. langchain/utils/openai.py +0 -23
  1281. langchain/utils/openai_functions.py +0 -13
  1282. langchain/utils/pydantic.py +0 -3
  1283. langchain/utils/strings.py +0 -3
  1284. langchain/utils/utils.py +0 -21
  1285. langchain/vectorstores/__init__.py +0 -262
  1286. langchain/vectorstores/alibabacloud_opensearch.py +0 -30
  1287. langchain/vectorstores/analyticdb.py +0 -23
  1288. langchain/vectorstores/annoy.py +0 -23
  1289. langchain/vectorstores/astradb.py +0 -23
  1290. langchain/vectorstores/atlas.py +0 -23
  1291. langchain/vectorstores/awadb.py +0 -23
  1292. langchain/vectorstores/azure_cosmos_db.py +0 -28
  1293. langchain/vectorstores/azuresearch.py +0 -30
  1294. langchain/vectorstores/bageldb.py +0 -23
  1295. langchain/vectorstores/baiducloud_vector_search.py +0 -23
  1296. langchain/vectorstores/base.py +0 -3
  1297. langchain/vectorstores/cassandra.py +0 -23
  1298. langchain/vectorstores/chroma.py +0 -23
  1299. langchain/vectorstores/clarifai.py +0 -23
  1300. langchain/vectorstores/clickhouse.py +0 -27
  1301. langchain/vectorstores/dashvector.py +0 -23
  1302. langchain/vectorstores/databricks_vector_search.py +0 -23
  1303. langchain/vectorstores/deeplake.py +0 -23
  1304. langchain/vectorstores/dingo.py +0 -23
  1305. langchain/vectorstores/docarray/__init__.py +0 -30
  1306. langchain/vectorstores/docarray/base.py +0 -23
  1307. langchain/vectorstores/docarray/hnsw.py +0 -23
  1308. langchain/vectorstores/docarray/in_memory.py +0 -23
  1309. langchain/vectorstores/elastic_vector_search.py +0 -27
  1310. langchain/vectorstores/elasticsearch.py +0 -39
  1311. langchain/vectorstores/epsilla.py +0 -23
  1312. langchain/vectorstores/faiss.py +0 -23
  1313. langchain/vectorstores/hippo.py +0 -23
  1314. langchain/vectorstores/hologres.py +0 -23
  1315. langchain/vectorstores/lancedb.py +0 -23
  1316. langchain/vectorstores/llm_rails.py +0 -28
  1317. langchain/vectorstores/marqo.py +0 -23
  1318. langchain/vectorstores/matching_engine.py +0 -23
  1319. langchain/vectorstores/meilisearch.py +0 -23
  1320. langchain/vectorstores/milvus.py +0 -23
  1321. langchain/vectorstores/momento_vector_index.py +0 -23
  1322. langchain/vectorstores/mongodb_atlas.py +0 -23
  1323. langchain/vectorstores/myscale.py +0 -30
  1324. langchain/vectorstores/neo4j_vector.py +0 -28
  1325. langchain/vectorstores/nucliadb.py +0 -23
  1326. langchain/vectorstores/opensearch_vector_search.py +0 -23
  1327. langchain/vectorstores/pgembedding.py +0 -36
  1328. langchain/vectorstores/pgvecto_rs.py +0 -23
  1329. langchain/vectorstores/pgvector.py +0 -28
  1330. langchain/vectorstores/pinecone.py +0 -23
  1331. langchain/vectorstores/qdrant.py +0 -28
  1332. langchain/vectorstores/redis/__init__.py +0 -42
  1333. langchain/vectorstores/redis/base.py +0 -33
  1334. langchain/vectorstores/redis/filters.py +0 -48
  1335. langchain/vectorstores/redis/schema.py +0 -54
  1336. langchain/vectorstores/rocksetdb.py +0 -23
  1337. langchain/vectorstores/scann.py +0 -23
  1338. langchain/vectorstores/semadb.py +0 -23
  1339. langchain/vectorstores/singlestoredb.py +0 -23
  1340. langchain/vectorstores/sklearn.py +0 -42
  1341. langchain/vectorstores/sqlitevss.py +0 -23
  1342. langchain/vectorstores/starrocks.py +0 -28
  1343. langchain/vectorstores/supabase.py +0 -23
  1344. langchain/vectorstores/tair.py +0 -23
  1345. langchain/vectorstores/tencentvectordb.py +0 -33
  1346. langchain/vectorstores/tigris.py +0 -23
  1347. langchain/vectorstores/tiledb.py +0 -23
  1348. langchain/vectorstores/timescalevector.py +0 -23
  1349. langchain/vectorstores/typesense.py +0 -23
  1350. langchain/vectorstores/usearch.py +0 -23
  1351. langchain/vectorstores/utils.py +0 -33
  1352. langchain/vectorstores/vald.py +0 -23
  1353. langchain/vectorstores/vearch.py +0 -23
  1354. langchain/vectorstores/vectara.py +0 -28
  1355. langchain/vectorstores/vespa.py +0 -23
  1356. langchain/vectorstores/weaviate.py +0 -23
  1357. langchain/vectorstores/xata.py +0 -23
  1358. langchain/vectorstores/yellowbrick.py +0 -23
  1359. langchain/vectorstores/zep.py +0 -28
  1360. langchain/vectorstores/zilliz.py +0 -23
  1361. langchain-0.4.0.dev0.dist-info/METADATA +0 -134
  1362. langchain-0.4.0.dev0.dist-info/RECORD +0 -1341
  1363. langchain-0.4.0.dev0.dist-info/entry_points.txt +0 -4
  1364. {langchain-0.4.0.dev0.dist-info → langchain-1.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,1700 @@
1
+ """Tool execution node for LangGraph workflows.
2
+
3
+ This module provides prebuilt functionality for executing tools in LangGraph.
4
+
5
+ Tools are functions that models can call to interact with external systems,
6
+ APIs, databases, or perform computations.
7
+
8
+ The module implements design patterns for:
9
+ - Parallel execution of multiple tool calls for efficiency
10
+ - Robust error handling with customizable error messages
11
+ - State injection for tools that need access to graph state
12
+ - Store injection for tools that need persistent storage
13
+ - Command-based state updates for advanced control flow
14
+
15
+ Key Components:
16
+ ToolNode: Main class for executing tools in LangGraph workflows
17
+ InjectedState: Annotation for injecting graph state into tools
18
+ InjectedStore: Annotation for injecting persistent store into tools
19
+ tools_condition: Utility function for conditional routing based on tool calls
20
+
21
+ Typical Usage:
22
+ ```python
23
+ from langchain_core.tools import tool
24
+ from langchain.tools import ToolNode
25
+
26
+
27
+ @tool
28
+ def my_tool(x: int) -> str:
29
+ return f"Result: {x}"
30
+
31
+
32
+ tool_node = ToolNode([my_tool])
33
+ ```
34
+ """
35
+
36
+ from __future__ import annotations
37
+
38
+ import asyncio
39
+ import inspect
40
+ import json
41
+ from collections.abc import Awaitable, Callable
42
+ from copy import copy, deepcopy
43
+ from dataclasses import dataclass, replace
44
+ from types import UnionType
45
+ from typing import (
46
+ TYPE_CHECKING,
47
+ Annotated,
48
+ Any,
49
+ Generic,
50
+ Literal,
51
+ TypedDict,
52
+ TypeVar,
53
+ Union,
54
+ cast,
55
+ get_args,
56
+ get_origin,
57
+ get_type_hints,
58
+ )
59
+
60
+ from langchain_core.messages import (
61
+ AIMessage,
62
+ AnyMessage,
63
+ RemoveMessage,
64
+ ToolCall,
65
+ ToolMessage,
66
+ convert_to_messages,
67
+ )
68
+ from langchain_core.runnables.config import (
69
+ RunnableConfig,
70
+ get_config_list,
71
+ get_executor_for_config,
72
+ )
73
+ from langchain_core.tools import BaseTool, InjectedToolArg
74
+ from langchain_core.tools import tool as create_tool
75
+ from langchain_core.tools.base import (
76
+ TOOL_MESSAGE_BLOCK_TYPES,
77
+ ToolException,
78
+ _DirectlyInjectedToolArg,
79
+ get_all_basemodel_annotations,
80
+ )
81
+ from langgraph._internal._runnable import RunnableCallable
82
+ from langgraph.errors import GraphBubbleUp
83
+ from langgraph.graph.message import REMOVE_ALL_MESSAGES
84
+ from langgraph.store.base import BaseStore # noqa: TC002
85
+ from langgraph.types import Command, Send, StreamWriter
86
+ from pydantic import BaseModel, ValidationError
87
+ from typing_extensions import Unpack
88
+
89
+ if TYPE_CHECKING:
90
+ from collections.abc import Sequence
91
+
92
+ from langgraph.runtime import Runtime
93
+
94
+ StateT = TypeVar("StateT")
95
+ ContextT = TypeVar("ContextT")
96
+
97
+ INVALID_TOOL_NAME_ERROR_TEMPLATE = (
98
+ "Error: {requested_tool} is not a valid tool, try one of [{available_tools}]."
99
+ )
100
+ TOOL_CALL_ERROR_TEMPLATE = "Error: {error}\n Please fix your mistakes."
101
+ TOOL_EXECUTION_ERROR_TEMPLATE = (
102
+ "Error executing tool '{tool_name}' with kwargs {tool_kwargs} with error:\n"
103
+ " {error}\n"
104
+ " Please fix the error and try again."
105
+ )
106
+ TOOL_INVOCATION_ERROR_TEMPLATE = (
107
+ "Error invoking tool '{tool_name}' with kwargs {tool_kwargs} with error:\n"
108
+ " {error}\n"
109
+ " Please fix the error and try again."
110
+ )
111
+
112
+
113
+ class _ToolCallRequestOverrides(TypedDict, total=False):
114
+ """Possible overrides for ToolCallRequest.override() method."""
115
+
116
+ tool_call: ToolCall
117
+
118
+
119
+ @dataclass()
120
+ class ToolCallRequest:
121
+ """Tool execution request passed to tool call interceptors.
122
+
123
+ Attributes:
124
+ tool_call: Tool call dict with name, args, and id from model output.
125
+ tool: BaseTool instance to be invoked, or None if tool is not
126
+ registered with the ToolNode. When tool is None, interceptors can
127
+ handle the request without validation. If the interceptor calls execute(),
128
+ validation will occur and raise an error for unregistered tools.
129
+ state: Agent state (dict, list, or BaseModel).
130
+ runtime: LangGraph runtime context (optional, None if outside graph).
131
+ """
132
+
133
+ tool_call: ToolCall
134
+ tool: BaseTool | None
135
+ state: Any
136
+ runtime: ToolRuntime
137
+
138
+ def override(self, **overrides: Unpack[_ToolCallRequestOverrides]) -> ToolCallRequest:
139
+ """Replace the request with a new request with the given overrides.
140
+
141
+ Returns a new `ToolCallRequest` instance with the specified attributes replaced.
142
+ This follows an immutable pattern, leaving the original request unchanged.
143
+
144
+ Args:
145
+ **overrides: Keyword arguments for attributes to override. Supported keys:
146
+ - tool_call: Tool call dict with name, args, and id
147
+
148
+ Returns:
149
+ New ToolCallRequest instance with specified overrides applied.
150
+
151
+ Examples:
152
+ ```python
153
+ # Modify tool call arguments without mutating original
154
+ modified_call = {**request.tool_call, "args": {"value": 10}}
155
+ new_request = request.override(tool_call=modified_call)
156
+
157
+ # Override multiple attributes
158
+ new_request = request.override(tool_call=modified_call, state=new_state)
159
+ ```
160
+ """
161
+ return replace(self, **overrides)
162
+
163
+
164
+ ToolCallWrapper = Callable[
165
+ [ToolCallRequest, Callable[[ToolCallRequest], ToolMessage | Command]],
166
+ ToolMessage | Command,
167
+ ]
168
+ """Wrapper for tool call execution with multi-call support.
169
+
170
+ Wrapper receives:
171
+ request: ToolCallRequest with tool_call, tool, state, and runtime.
172
+ execute: Callable to execute the tool (CAN BE CALLED MULTIPLE TIMES).
173
+
174
+ Returns:
175
+ ToolMessage or Command (the final result).
176
+
177
+ The execute callable can be invoked multiple times for retry logic,
178
+ with potentially modified requests each time. Each call to execute
179
+ is independent and stateless.
180
+
181
+ Note:
182
+ When implementing middleware for `create_agent`, use
183
+ `AgentMiddleware.wrap_tool_call` which provides properly typed
184
+ state parameter for better type safety.
185
+
186
+ Examples:
187
+ Passthrough (execute once):
188
+
189
+ def handler(request, execute):
190
+ return execute(request)
191
+
192
+ Modify request before execution:
193
+
194
+ ```python
195
+ def handler(request, execute):
196
+ request.tool_call["args"]["value"] *= 2
197
+ return execute(request)
198
+ ```
199
+
200
+ Retry on error (execute multiple times):
201
+
202
+ ```python
203
+ def handler(request, execute):
204
+ for attempt in range(3):
205
+ try:
206
+ result = execute(request)
207
+ if is_valid(result):
208
+ return result
209
+ except Exception:
210
+ if attempt == 2:
211
+ raise
212
+ return result
213
+ ```
214
+
215
+ Conditional retry based on response:
216
+
217
+ ```python
218
+ def handler(request, execute):
219
+ for attempt in range(3):
220
+ result = execute(request)
221
+ if isinstance(result, ToolMessage) and result.status != "error":
222
+ return result
223
+ if attempt < 2:
224
+ continue
225
+ return result
226
+ ```
227
+
228
+ Cache/short-circuit without calling execute:
229
+
230
+ ```python
231
+ def handler(request, execute):
232
+ if cached := get_cache(request):
233
+ return ToolMessage(content=cached, tool_call_id=request.tool_call["id"])
234
+ result = execute(request)
235
+ save_cache(request, result)
236
+ return result
237
+ ```
238
+ """
239
+
240
+ AsyncToolCallWrapper = Callable[
241
+ [ToolCallRequest, Callable[[ToolCallRequest], Awaitable[ToolMessage | Command]]],
242
+ Awaitable[ToolMessage | Command],
243
+ ]
244
+ """Async wrapper for tool call execution with multi-call support."""
245
+
246
+
247
+ class ToolCallWithContext(TypedDict):
248
+ """ToolCall with additional context for graph state.
249
+
250
+ This is an internal data structure meant to help the ToolNode accept
251
+ tool calls with additional context (e.g. state) when dispatched using the
252
+ Send API.
253
+
254
+ The Send API is used in create_agent to distribute tool calls in parallel
255
+ and support human-in-the-loop workflows where graph execution may be paused
256
+ for an indefinite time.
257
+ """
258
+
259
+ tool_call: ToolCall
260
+ __type: Literal["tool_call_with_context"]
261
+ """Type to parameterize the payload.
262
+
263
+ Using "__" as a prefix to be defensive against potential name collisions with
264
+ regular user state.
265
+ """
266
+ state: Any
267
+ """The state is provided as additional context."""
268
+
269
+
270
+ def msg_content_output(output: Any) -> str | list[dict]:
271
+ """Convert tool output to ToolMessage content format.
272
+
273
+ Handles str, list[dict] (content blocks), and arbitrary objects by attempting
274
+ JSON serialization with fallback to str().
275
+
276
+ Args:
277
+ output: Tool execution output of any type.
278
+
279
+ Returns:
280
+ String or list of content blocks suitable for ToolMessage.content.
281
+ """
282
+ if isinstance(output, str) or (
283
+ isinstance(output, list)
284
+ and all(isinstance(x, dict) and x.get("type") in TOOL_MESSAGE_BLOCK_TYPES for x in output)
285
+ ):
286
+ return output
287
+ # Technically a list of strings is also valid message content, but it's
288
+ # not currently well tested that all chat models support this.
289
+ # And for backwards compatibility we want to make sure we don't break
290
+ # any existing ToolNode usage.
291
+ try:
292
+ return json.dumps(output, ensure_ascii=False)
293
+ except Exception: # noqa: BLE001
294
+ return str(output)
295
+
296
+
297
+ class ToolInvocationError(ToolException):
298
+ """An error occurred while invoking a tool due to invalid arguments.
299
+
300
+ This exception is only raised when invoking a tool using the ToolNode!
301
+ """
302
+
303
+ def __init__(
304
+ self, tool_name: str, source: ValidationError, tool_kwargs: dict[str, Any]
305
+ ) -> None:
306
+ """Initialize the ToolInvocationError.
307
+
308
+ Args:
309
+ tool_name: The name of the tool that failed.
310
+ source: The exception that occurred.
311
+ tool_kwargs: The keyword arguments that were passed to the tool.
312
+ """
313
+ self.message = TOOL_INVOCATION_ERROR_TEMPLATE.format(
314
+ tool_name=tool_name, tool_kwargs=tool_kwargs, error=source
315
+ )
316
+ self.tool_name = tool_name
317
+ self.tool_kwargs = tool_kwargs
318
+ self.source = source
319
+ super().__init__(self.message)
320
+
321
+
322
+ def _default_handle_tool_errors(e: Exception) -> str:
323
+ """Default error handler for tool errors.
324
+
325
+ If the tool is a tool invocation error, return its message.
326
+ Otherwise, raise the error.
327
+ """
328
+ if isinstance(e, ToolInvocationError):
329
+ return e.message
330
+ raise e
331
+
332
+
333
+ def _handle_tool_error(
334
+ e: Exception,
335
+ *,
336
+ flag: bool | str | Callable[..., str] | type[Exception] | tuple[type[Exception], ...],
337
+ ) -> str:
338
+ """Generate error message content based on exception handling configuration.
339
+
340
+ This function centralizes error message generation logic, supporting different
341
+ error handling strategies configured via the ToolNode's handle_tool_errors
342
+ parameter.
343
+
344
+ Args:
345
+ e: The exception that occurred during tool execution.
346
+ flag: Configuration for how to handle the error. Can be:
347
+ - bool: If `True`, use default error template
348
+ - str: Use this string as the error message
349
+ - Callable: Call this function with the exception to get error message
350
+ - tuple: Not used in this context (handled by caller)
351
+
352
+ Returns:
353
+ A string containing the error message to include in the ToolMessage.
354
+
355
+ Raises:
356
+ ValueError: If flag is not one of the supported types.
357
+
358
+ Note:
359
+ The tuple case is handled by the caller through exception type checking,
360
+ not by this function directly.
361
+ """
362
+ if isinstance(flag, (bool, tuple)) or (isinstance(flag, type) and issubclass(flag, Exception)):
363
+ content = TOOL_CALL_ERROR_TEMPLATE.format(error=repr(e))
364
+ elif isinstance(flag, str):
365
+ content = flag
366
+ elif callable(flag):
367
+ content = flag(e) # type: ignore [assignment, call-arg]
368
+ else:
369
+ msg = (
370
+ f"Got unexpected type of `handle_tool_error`. Expected bool, str "
371
+ f"or callable. Received: {flag}"
372
+ )
373
+ raise ValueError(msg)
374
+ return content
375
+
376
+
377
+ def _infer_handled_types(handler: Callable[..., str]) -> tuple[type[Exception], ...]:
378
+ """Infer exception types handled by a custom error handler function.
379
+
380
+ This function analyzes the type annotations of a custom error handler to determine
381
+ which exception types it's designed to handle. This enables type-safe error handling
382
+ where only specific exceptions are caught and processed by the handler.
383
+
384
+ Args:
385
+ handler: A callable that takes an exception and returns an error message string.
386
+ The first parameter (after self/cls if present) should be type-annotated
387
+ with the exception type(s) to handle.
388
+
389
+ Returns:
390
+ A tuple of exception types that the handler can process. Returns (Exception,)
391
+ if no specific type information is available for backward compatibility.
392
+
393
+ Raises:
394
+ ValueError: If the handler's annotation contains non-Exception types or
395
+ if Union types contain non-Exception types.
396
+
397
+ Note:
398
+ This function supports both single exception types and Union types for
399
+ handlers that need to handle multiple exception types differently.
400
+ """
401
+ sig = inspect.signature(handler)
402
+ params = list(sig.parameters.values())
403
+ if params:
404
+ # If it's a method, the first argument is typically 'self' or 'cls'
405
+ if params[0].name in ["self", "cls"] and len(params) == 2:
406
+ first_param = params[1]
407
+ else:
408
+ first_param = params[0]
409
+
410
+ type_hints = get_type_hints(handler)
411
+ if first_param.name in type_hints:
412
+ origin = get_origin(first_param.annotation)
413
+ if origin in [Union, UnionType]:
414
+ args = get_args(first_param.annotation)
415
+ if all(issubclass(arg, Exception) for arg in args):
416
+ return tuple(args)
417
+ msg = (
418
+ "All types in the error handler error annotation must be "
419
+ "Exception types. For example, "
420
+ "`def custom_handler(e: Union[ValueError, TypeError])`. "
421
+ f"Got '{first_param.annotation}' instead."
422
+ )
423
+ raise ValueError(msg)
424
+
425
+ exception_type = type_hints[first_param.name]
426
+ if Exception in exception_type.__mro__:
427
+ return (exception_type,)
428
+ msg = (
429
+ f"Arbitrary types are not supported in the error handler "
430
+ f"signature. Please annotate the error with either a "
431
+ f"specific Exception type or a union of Exception types. "
432
+ "For example, `def custom_handler(e: ValueError)` or "
433
+ "`def custom_handler(e: Union[ValueError, TypeError])`. "
434
+ f"Got '{exception_type}' instead."
435
+ )
436
+ raise ValueError(msg)
437
+
438
+ # If no type information is available, return (Exception,)
439
+ # for backwards compatibility.
440
+ return (Exception,)
441
+
442
+
443
+ class _ToolNode(RunnableCallable):
444
+ """A node for executing tools in LangGraph workflows.
445
+
446
+ Handles tool execution patterns including function calls, state injection,
447
+ persistent storage, and control flow. Manages parallel execution,
448
+ error handling.
449
+
450
+ Input Formats:
451
+ 1. Graph state with `messages` key that has a list of messages:
452
+ - Common representation for agentic workflows
453
+ - Supports custom messages key via `messages_key` parameter
454
+
455
+ 2. **Message List**: `[AIMessage(..., tool_calls=[...])]`
456
+ - List of messages with tool calls in the last AIMessage
457
+
458
+ 3. **Direct Tool Calls**: `[{"name": "tool", "args": {...}, "id": "1", "type": "tool_call"}]`
459
+ - Bypasses message parsing for direct tool execution
460
+ - For programmatic tool invocation and testing
461
+
462
+ Output Formats:
463
+ Output format depends on input type and tool behavior:
464
+
465
+ **For Regular tools**:
466
+ - Dict input → `{"messages": [ToolMessage(...)]}`
467
+ - List input → `[ToolMessage(...)]`
468
+
469
+ **For Command tools**:
470
+ - Returns `[Command(...)]` or mixed list with regular tool outputs
471
+ - Commands can update state, trigger navigation, or send messages
472
+
473
+ Args:
474
+ tools: A sequence of tools that can be invoked by this node. Supports:
475
+ - **BaseTool instances**: Tools with schemas and metadata
476
+ - **Plain functions**: Automatically converted to tools with inferred schemas
477
+ name: The name identifier for this node in the graph. Used for debugging
478
+ and visualization. Defaults to "tools".
479
+ tags: Optional metadata tags to associate with the node for filtering
480
+ and organization. Defaults to `None`.
481
+ handle_tool_errors: Configuration for error handling during tool execution.
482
+ Supports multiple strategies:
483
+
484
+ - **True**: Catch all errors and return a ToolMessage with the default
485
+ error template containing the exception details.
486
+ - **str**: Catch all errors and return a ToolMessage with this custom
487
+ error message string.
488
+ - **type[Exception]**: Only catch exceptions with the specified type and
489
+ return the default error message for it.
490
+ - **tuple[type[Exception], ...]**: Only catch exceptions with the specified
491
+ types and return default error messages for them.
492
+ - **Callable[..., str]**: Catch exceptions matching the callable's signature
493
+ and return the string result of calling it with the exception.
494
+ - **False**: Disable error handling entirely, allowing exceptions to
495
+ propagate.
496
+
497
+ Defaults to a callable that:
498
+ - catches tool invocation errors (due to invalid arguments provided by the model) and returns a descriptive error message
499
+ - ignores tool execution errors (they will be re-raised)
500
+
501
+ messages_key: The key in the state dictionary that contains the message list.
502
+ This same key will be used for the output `ToolMessage` objects.
503
+ Defaults to "messages".
504
+ Allows custom state schemas with different message field names.
505
+
506
+ Examples:
507
+ Basic usage:
508
+
509
+ ```python
510
+ from langchain.tools import ToolNode
511
+ from langchain_core.tools import tool
512
+
513
+ @tool
514
+ def calculator(a: int, b: int) -> int:
515
+ \"\"\"Add two numbers.\"\"\"
516
+ return a + b
517
+
518
+ tool_node = ToolNode([calculator])
519
+ ```
520
+
521
+ State injection:
522
+
523
+ ```python
524
+ from typing_extensions import Annotated
525
+ from langchain.tools import InjectedState
526
+
527
+ @tool
528
+ def context_tool(query: str, state: Annotated[dict, InjectedState]) -> str:
529
+ \"\"\"Some tool that uses state.\"\"\"
530
+ return f"Query: {query}, Messages: {len(state['messages'])}"
531
+
532
+ tool_node = ToolNode([context_tool])
533
+ ```
534
+
535
+ Error handling:
536
+
537
+ ```python
538
+ def handle_errors(e: ValueError) -> str:
539
+ return "Invalid input provided"
540
+
541
+
542
+ tool_node = ToolNode([my_tool], handle_tool_errors=handle_errors)
543
+ ```
544
+ """ # noqa: E501
545
+
546
+ name: str = "tools"
547
+
548
+ def __init__(
549
+ self,
550
+ tools: Sequence[BaseTool | Callable],
551
+ *,
552
+ name: str = "tools",
553
+ tags: list[str] | None = None,
554
+ handle_tool_errors: bool
555
+ | str
556
+ | Callable[..., str]
557
+ | type[Exception]
558
+ | tuple[type[Exception], ...] = _default_handle_tool_errors,
559
+ messages_key: str = "messages",
560
+ wrap_tool_call: ToolCallWrapper | None = None,
561
+ awrap_tool_call: AsyncToolCallWrapper | None = None,
562
+ ) -> None:
563
+ """Initialize ToolNode with tools and configuration.
564
+
565
+ Args:
566
+ tools: Sequence of tools to make available for execution.
567
+ name: Node name for graph identification.
568
+ tags: Optional metadata tags.
569
+ handle_tool_errors: Error handling configuration.
570
+ messages_key: State key containing messages.
571
+ wrap_tool_call: Sync wrapper function to intercept tool execution. Receives
572
+ ToolCallRequest and execute callable, returns ToolMessage or Command.
573
+ Enables retries, caching, request modification, and control flow.
574
+ awrap_tool_call: Async wrapper function to intercept tool execution.
575
+ If not provided, falls back to wrap_tool_call for async execution.
576
+ """
577
+ super().__init__(self._func, self._afunc, name=name, tags=tags, trace=False)
578
+ self._tools_by_name: dict[str, BaseTool] = {}
579
+ self._tool_to_state_args: dict[str, dict[str, str | None]] = {}
580
+ self._tool_to_store_arg: dict[str, str | None] = {}
581
+ self._tool_to_runtime_arg: dict[str, str | None] = {}
582
+ self._handle_tool_errors = handle_tool_errors
583
+ self._messages_key = messages_key
584
+ self._wrap_tool_call = wrap_tool_call
585
+ self._awrap_tool_call = awrap_tool_call
586
+ for tool in tools:
587
+ if not isinstance(tool, BaseTool):
588
+ tool_ = create_tool(cast("type[BaseTool]", tool))
589
+ else:
590
+ tool_ = tool
591
+ self._tools_by_name[tool_.name] = tool_
592
+ self._tool_to_state_args[tool_.name] = _get_state_args(tool_)
593
+ self._tool_to_store_arg[tool_.name] = _get_store_arg(tool_)
594
+ self._tool_to_runtime_arg[tool_.name] = _get_runtime_arg(tool_)
595
+
596
+ @property
597
+ def tools_by_name(self) -> dict[str, BaseTool]:
598
+ """Mapping from tool name to BaseTool instance."""
599
+ return self._tools_by_name
600
+
601
+ def _func(
602
+ self,
603
+ input: list[AnyMessage] | dict[str, Any] | BaseModel,
604
+ config: RunnableConfig,
605
+ runtime: Runtime,
606
+ ) -> Any:
607
+ tool_calls, input_type = self._parse_input(input)
608
+ config_list = get_config_list(config, len(tool_calls))
609
+
610
+ # Construct ToolRuntime instances at the top level for each tool call
611
+ tool_runtimes = []
612
+ for call, cfg in zip(tool_calls, config_list, strict=False):
613
+ state = self._extract_state(input)
614
+ tool_runtime = ToolRuntime(
615
+ state=state,
616
+ tool_call_id=call["id"],
617
+ config=cfg,
618
+ context=runtime.context,
619
+ store=runtime.store,
620
+ stream_writer=runtime.stream_writer,
621
+ )
622
+ tool_runtimes.append(tool_runtime)
623
+
624
+ # Inject tool arguments (including runtime)
625
+
626
+ injected_tool_calls = []
627
+ input_types = [input_type] * len(tool_calls)
628
+ for call, tool_runtime in zip(tool_calls, tool_runtimes, strict=False):
629
+ injected_call = self._inject_tool_args(call, tool_runtime)
630
+ injected_tool_calls.append(injected_call)
631
+ with get_executor_for_config(config) as executor:
632
+ outputs = list(
633
+ executor.map(self._run_one, injected_tool_calls, input_types, tool_runtimes)
634
+ )
635
+
636
+ return self._combine_tool_outputs(outputs, input_type)
637
+
638
+ async def _afunc(
639
+ self,
640
+ input: list[AnyMessage] | dict[str, Any] | BaseModel,
641
+ config: RunnableConfig,
642
+ runtime: Runtime,
643
+ ) -> Any:
644
+ tool_calls, input_type = self._parse_input(input)
645
+ config_list = get_config_list(config, len(tool_calls))
646
+
647
+ # Construct ToolRuntime instances at the top level for each tool call
648
+ tool_runtimes = []
649
+ for call, cfg in zip(tool_calls, config_list, strict=False):
650
+ state = self._extract_state(input)
651
+ tool_runtime = ToolRuntime(
652
+ state=state,
653
+ tool_call_id=call["id"],
654
+ config=cfg,
655
+ context=runtime.context,
656
+ store=runtime.store,
657
+ stream_writer=runtime.stream_writer,
658
+ )
659
+ tool_runtimes.append(tool_runtime)
660
+
661
+ injected_tool_calls = []
662
+ coros = []
663
+ for call, tool_runtime in zip(tool_calls, tool_runtimes, strict=False):
664
+ injected_call = self._inject_tool_args(call, tool_runtime)
665
+ injected_tool_calls.append(injected_call)
666
+ coros.append(self._arun_one(injected_call, input_type, tool_runtime))
667
+ outputs = await asyncio.gather(*coros)
668
+
669
+ return self._combine_tool_outputs(outputs, input_type)
670
+
671
+ def _combine_tool_outputs(
672
+ self,
673
+ outputs: list[ToolMessage | Command],
674
+ input_type: Literal["list", "dict", "tool_calls"],
675
+ ) -> list[Command | list[ToolMessage] | dict[str, list[ToolMessage]]]:
676
+ # preserve existing behavior for non-command tool outputs for backwards
677
+ # compatibility
678
+ if not any(isinstance(output, Command) for output in outputs):
679
+ # TypedDict, pydantic, dataclass, etc. should all be able to load from dict
680
+ return outputs if input_type == "list" else {self._messages_key: outputs} # type: ignore[return-value, return-value]
681
+
682
+ # LangGraph will automatically handle list of Command and non-command node
683
+ # updates
684
+ combined_outputs: list[Command | list[ToolMessage] | dict[str, list[ToolMessage]]] = []
685
+
686
+ # combine all parent commands with goto into a single parent command
687
+ parent_command: Command | None = None
688
+ for output in outputs:
689
+ if isinstance(output, Command):
690
+ if (
691
+ output.graph is Command.PARENT
692
+ and isinstance(output.goto, list)
693
+ and all(isinstance(send, Send) for send in output.goto)
694
+ ):
695
+ if parent_command:
696
+ parent_command = replace(
697
+ parent_command,
698
+ goto=cast("list[Send]", parent_command.goto) + output.goto,
699
+ )
700
+ else:
701
+ parent_command = Command(graph=Command.PARENT, goto=output.goto)
702
+ else:
703
+ combined_outputs.append(output)
704
+ else:
705
+ combined_outputs.append(
706
+ [output] if input_type == "list" else {self._messages_key: [output]}
707
+ )
708
+
709
+ if parent_command:
710
+ combined_outputs.append(parent_command)
711
+ return combined_outputs
712
+
713
+ def _execute_tool_sync(
714
+ self,
715
+ request: ToolCallRequest,
716
+ input_type: Literal["list", "dict", "tool_calls"],
717
+ config: RunnableConfig,
718
+ ) -> ToolMessage | Command:
719
+ """Execute tool call with configured error handling.
720
+
721
+ Args:
722
+ request: Tool execution request.
723
+ input_type: Input format.
724
+ config: Runnable configuration.
725
+
726
+ Returns:
727
+ ToolMessage or Command.
728
+
729
+ Raises:
730
+ Exception: If tool fails and handle_tool_errors is False.
731
+ """
732
+ call = request.tool_call
733
+ tool = request.tool
734
+
735
+ # Validate tool exists when we actually need to execute it
736
+ if tool is None:
737
+ if invalid_tool_message := self._validate_tool_call(call):
738
+ return invalid_tool_message
739
+ # This should never happen if validation works correctly
740
+ msg = f"Tool {call['name']} is not registered with ToolNode"
741
+ raise TypeError(msg)
742
+
743
+ call_args = {**call, "type": "tool_call"}
744
+
745
+ try:
746
+ try:
747
+ response = tool.invoke(call_args, config)
748
+ except ValidationError as exc:
749
+ raise ToolInvocationError(call["name"], exc, call["args"]) from exc
750
+
751
+ # GraphInterrupt is a special exception that will always be raised.
752
+ # It can be triggered in the following scenarios,
753
+ # Where GraphInterrupt(GraphBubbleUp) is raised from an `interrupt` invocation
754
+ # most commonly:
755
+ # (1) a GraphInterrupt is raised inside a tool
756
+ # (2) a GraphInterrupt is raised inside a graph node for a graph called as a tool
757
+ # (3) a GraphInterrupt is raised when a subgraph is interrupted inside a graph
758
+ # called as a tool
759
+ # (2 and 3 can happen in a "supervisor w/ tools" multi-agent architecture)
760
+ except GraphBubbleUp:
761
+ raise
762
+ except Exception as e:
763
+ # Determine which exception types are handled
764
+ handled_types: tuple[type[Exception], ...]
765
+ if isinstance(self._handle_tool_errors, type) and issubclass(
766
+ self._handle_tool_errors, Exception
767
+ ):
768
+ handled_types = (self._handle_tool_errors,)
769
+ elif isinstance(self._handle_tool_errors, tuple):
770
+ handled_types = self._handle_tool_errors
771
+ elif callable(self._handle_tool_errors) and not isinstance(
772
+ self._handle_tool_errors, type
773
+ ):
774
+ handled_types = _infer_handled_types(self._handle_tool_errors)
775
+ else:
776
+ # default behavior is catching all exceptions
777
+ handled_types = (Exception,)
778
+
779
+ # Check if this error should be handled
780
+ if not self._handle_tool_errors or not isinstance(e, handled_types):
781
+ raise
782
+
783
+ # Error is handled - create error ToolMessage
784
+ content = _handle_tool_error(e, flag=self._handle_tool_errors)
785
+ return ToolMessage(
786
+ content=content,
787
+ name=call["name"],
788
+ tool_call_id=call["id"],
789
+ status="error",
790
+ )
791
+
792
+ # Process successful response
793
+ if isinstance(response, Command):
794
+ # Validate Command before returning to handler
795
+ return self._validate_tool_command(response, request.tool_call, input_type)
796
+ if isinstance(response, ToolMessage):
797
+ response.content = cast("str | list", msg_content_output(response.content))
798
+ return response
799
+
800
+ msg = f"Tool {call['name']} returned unexpected type: {type(response)}"
801
+ raise TypeError(msg)
802
+
803
+ def _run_one(
804
+ self,
805
+ call: ToolCall,
806
+ input_type: Literal["list", "dict", "tool_calls"],
807
+ tool_runtime: ToolRuntime,
808
+ ) -> ToolMessage | Command:
809
+ """Execute single tool call with wrap_tool_call wrapper if configured.
810
+
811
+ Args:
812
+ call: Tool call dict.
813
+ input_type: Input format.
814
+ tool_runtime: Tool runtime.
815
+
816
+ Returns:
817
+ ToolMessage or Command.
818
+ """
819
+ # Validation is deferred to _execute_tool_sync to allow interceptors
820
+ # to short-circuit requests for unregistered tools
821
+ tool = self.tools_by_name.get(call["name"])
822
+
823
+ # Create the tool request with state and runtime
824
+ tool_request = ToolCallRequest(
825
+ tool_call=call,
826
+ tool=tool,
827
+ state=tool_runtime.state,
828
+ runtime=tool_runtime,
829
+ )
830
+
831
+ config = tool_runtime.config
832
+
833
+ if self._wrap_tool_call is None:
834
+ # No wrapper - execute directly
835
+ return self._execute_tool_sync(tool_request, input_type, config)
836
+
837
+ # Define execute callable that can be called multiple times
838
+ def execute(req: ToolCallRequest) -> ToolMessage | Command:
839
+ """Execute tool with given request. Can be called multiple times."""
840
+ return self._execute_tool_sync(req, input_type, config)
841
+
842
+ # Call wrapper with request and execute callable
843
+ try:
844
+ return self._wrap_tool_call(tool_request, execute)
845
+ except Exception as e:
846
+ # Wrapper threw an exception
847
+ if not self._handle_tool_errors:
848
+ raise
849
+ # Convert to error message
850
+ content = _handle_tool_error(e, flag=self._handle_tool_errors)
851
+ return ToolMessage(
852
+ content=content,
853
+ name=tool_request.tool_call["name"],
854
+ tool_call_id=tool_request.tool_call["id"],
855
+ status="error",
856
+ )
857
+
858
+ async def _execute_tool_async(
859
+ self,
860
+ request: ToolCallRequest,
861
+ input_type: Literal["list", "dict", "tool_calls"],
862
+ config: RunnableConfig,
863
+ ) -> ToolMessage | Command:
864
+ """Execute tool call asynchronously with configured error handling.
865
+
866
+ Args:
867
+ request: Tool execution request.
868
+ input_type: Input format.
869
+ config: Runnable configuration.
870
+
871
+ Returns:
872
+ ToolMessage or Command.
873
+
874
+ Raises:
875
+ Exception: If tool fails and handle_tool_errors is False.
876
+ """
877
+ call = request.tool_call
878
+ tool = request.tool
879
+
880
+ # Validate tool exists when we actually need to execute it
881
+ if tool is None:
882
+ if invalid_tool_message := self._validate_tool_call(call):
883
+ return invalid_tool_message
884
+ # This should never happen if validation works correctly
885
+ msg = f"Tool {call['name']} is not registered with ToolNode"
886
+ raise TypeError(msg)
887
+
888
+ call_args = {**call, "type": "tool_call"}
889
+
890
+ try:
891
+ try:
892
+ response = await tool.ainvoke(call_args, config)
893
+ except ValidationError as exc:
894
+ raise ToolInvocationError(call["name"], exc, call["args"]) from exc
895
+
896
+ # GraphInterrupt is a special exception that will always be raised.
897
+ # It can be triggered in the following scenarios,
898
+ # Where GraphInterrupt(GraphBubbleUp) is raised from an `interrupt` invocation
899
+ # most commonly:
900
+ # (1) a GraphInterrupt is raised inside a tool
901
+ # (2) a GraphInterrupt is raised inside a graph node for a graph called as a tool
902
+ # (3) a GraphInterrupt is raised when a subgraph is interrupted inside a graph
903
+ # called as a tool
904
+ # (2 and 3 can happen in a "supervisor w/ tools" multi-agent architecture)
905
+ except GraphBubbleUp:
906
+ raise
907
+ except Exception as e:
908
+ # Determine which exception types are handled
909
+ handled_types: tuple[type[Exception], ...]
910
+ if isinstance(self._handle_tool_errors, type) and issubclass(
911
+ self._handle_tool_errors, Exception
912
+ ):
913
+ handled_types = (self._handle_tool_errors,)
914
+ elif isinstance(self._handle_tool_errors, tuple):
915
+ handled_types = self._handle_tool_errors
916
+ elif callable(self._handle_tool_errors) and not isinstance(
917
+ self._handle_tool_errors, type
918
+ ):
919
+ handled_types = _infer_handled_types(self._handle_tool_errors)
920
+ else:
921
+ # default behavior is catching all exceptions
922
+ handled_types = (Exception,)
923
+
924
+ # Check if this error should be handled
925
+ if not self._handle_tool_errors or not isinstance(e, handled_types):
926
+ raise
927
+
928
+ # Error is handled - create error ToolMessage
929
+ content = _handle_tool_error(e, flag=self._handle_tool_errors)
930
+ return ToolMessage(
931
+ content=content,
932
+ name=call["name"],
933
+ tool_call_id=call["id"],
934
+ status="error",
935
+ )
936
+
937
+ # Process successful response
938
+ if isinstance(response, Command):
939
+ # Validate Command before returning to handler
940
+ return self._validate_tool_command(response, request.tool_call, input_type)
941
+ if isinstance(response, ToolMessage):
942
+ response.content = cast("str | list", msg_content_output(response.content))
943
+ return response
944
+
945
+ msg = f"Tool {call['name']} returned unexpected type: {type(response)}"
946
+ raise TypeError(msg)
947
+
948
+ async def _arun_one(
949
+ self,
950
+ call: ToolCall,
951
+ input_type: Literal["list", "dict", "tool_calls"],
952
+ tool_runtime: ToolRuntime,
953
+ ) -> ToolMessage | Command:
954
+ """Execute single tool call asynchronously with awrap_tool_call wrapper if configured.
955
+
956
+ Args:
957
+ call: Tool call dict.
958
+ input_type: Input format.
959
+ tool_runtime: Tool runtime.
960
+
961
+ Returns:
962
+ ToolMessage or Command.
963
+ """
964
+ # Validation is deferred to _execute_tool_async to allow interceptors
965
+ # to short-circuit requests for unregistered tools
966
+ tool = self.tools_by_name.get(call["name"])
967
+
968
+ # Create the tool request with state and runtime
969
+ tool_request = ToolCallRequest(
970
+ tool_call=call,
971
+ tool=tool,
972
+ state=tool_runtime.state,
973
+ runtime=tool_runtime,
974
+ )
975
+
976
+ config = tool_runtime.config
977
+
978
+ if self._awrap_tool_call is None and self._wrap_tool_call is None:
979
+ # No wrapper - execute directly
980
+ return await self._execute_tool_async(tool_request, input_type, config)
981
+
982
+ # Define async execute callable that can be called multiple times
983
+ async def execute(req: ToolCallRequest) -> ToolMessage | Command:
984
+ """Execute tool with given request. Can be called multiple times."""
985
+ return await self._execute_tool_async(req, input_type, config)
986
+
987
+ def _sync_execute(req: ToolCallRequest) -> ToolMessage | Command:
988
+ """Sync execute fallback for sync wrapper."""
989
+ return self._execute_tool_sync(req, input_type, config)
990
+
991
+ # Call wrapper with request and execute callable
992
+ try:
993
+ if self._awrap_tool_call is not None:
994
+ return await self._awrap_tool_call(tool_request, execute)
995
+ # None check was performed above already
996
+ self._wrap_tool_call = cast("ToolCallWrapper", self._wrap_tool_call)
997
+ return self._wrap_tool_call(tool_request, _sync_execute)
998
+ except Exception as e:
999
+ # Wrapper threw an exception
1000
+ if not self._handle_tool_errors:
1001
+ raise
1002
+ # Convert to error message
1003
+ content = _handle_tool_error(e, flag=self._handle_tool_errors)
1004
+ return ToolMessage(
1005
+ content=content,
1006
+ name=tool_request.tool_call["name"],
1007
+ tool_call_id=tool_request.tool_call["id"],
1008
+ status="error",
1009
+ )
1010
+
1011
+ def _parse_input(
1012
+ self,
1013
+ input: list[AnyMessage] | dict[str, Any] | BaseModel,
1014
+ ) -> tuple[list[ToolCall], Literal["list", "dict", "tool_calls"]]:
1015
+ input_type: Literal["list", "dict", "tool_calls"]
1016
+ if isinstance(input, list):
1017
+ if isinstance(input[-1], dict) and input[-1].get("type") == "tool_call":
1018
+ input_type = "tool_calls"
1019
+ tool_calls = cast("list[ToolCall]", input)
1020
+ return tool_calls, input_type
1021
+ input_type = "list"
1022
+ messages = input
1023
+ elif isinstance(input, dict) and input.get("__type") == "tool_call_with_context":
1024
+ # Handle ToolCallWithContext from Send API
1025
+ # mypy will not be able to type narrow correctly since the signature
1026
+ # for input contains dict[str, Any]. We'd need to narrow dict[str, Any]
1027
+ # before we can apply correct typing.
1028
+ input_with_ctx = cast("ToolCallWithContext", input)
1029
+ input_type = "tool_calls"
1030
+ return [input_with_ctx["tool_call"]], input_type
1031
+ elif isinstance(input, dict) and (messages := input.get(self._messages_key, [])):
1032
+ input_type = "dict"
1033
+ elif messages := getattr(input, self._messages_key, []):
1034
+ # Assume dataclass-like state that can coerce from dict
1035
+ input_type = "dict"
1036
+ else:
1037
+ msg = "No message found in input"
1038
+ raise ValueError(msg)
1039
+
1040
+ try:
1041
+ latest_ai_message = next(m for m in reversed(messages) if isinstance(m, AIMessage))
1042
+ except StopIteration:
1043
+ msg = "No AIMessage found in input"
1044
+ raise ValueError(msg)
1045
+
1046
+ tool_calls = list(latest_ai_message.tool_calls)
1047
+ return tool_calls, input_type
1048
+
1049
+ def _validate_tool_call(self, call: ToolCall) -> ToolMessage | None:
1050
+ requested_tool = call["name"]
1051
+ if requested_tool not in self.tools_by_name:
1052
+ all_tool_names = list(self.tools_by_name.keys())
1053
+ content = INVALID_TOOL_NAME_ERROR_TEMPLATE.format(
1054
+ requested_tool=requested_tool,
1055
+ available_tools=", ".join(all_tool_names),
1056
+ )
1057
+ return ToolMessage(
1058
+ content, name=requested_tool, tool_call_id=call["id"], status="error"
1059
+ )
1060
+ return None
1061
+
1062
+ def _extract_state(
1063
+ self, input: list[AnyMessage] | dict[str, Any] | BaseModel
1064
+ ) -> list[AnyMessage] | dict[str, Any] | BaseModel:
1065
+ """Extract state from input, handling ToolCallWithContext if present.
1066
+
1067
+ Args:
1068
+ input: The input which may be raw state or ToolCallWithContext.
1069
+
1070
+ Returns:
1071
+ The actual state to pass to wrap_tool_call wrappers.
1072
+ """
1073
+ if isinstance(input, dict) and input.get("__type") == "tool_call_with_context":
1074
+ return input["state"]
1075
+ return input
1076
+
1077
+ def _inject_state(
1078
+ self,
1079
+ tool_call: ToolCall,
1080
+ state: list[AnyMessage] | dict[str, Any] | BaseModel,
1081
+ ) -> ToolCall:
1082
+ state_args = self._tool_to_state_args[tool_call["name"]]
1083
+
1084
+ if state_args and isinstance(state, list):
1085
+ required_fields = list(state_args.values())
1086
+ if (
1087
+ len(required_fields) == 1 and required_fields[0] == self._messages_key
1088
+ ) or required_fields[0] is None:
1089
+ state = {self._messages_key: state}
1090
+ else:
1091
+ err_msg = (
1092
+ f"Invalid input to ToolNode. Tool {tool_call['name']} requires "
1093
+ f"graph state dict as input."
1094
+ )
1095
+ if any(state_field for state_field in state_args.values()):
1096
+ required_fields_str = ", ".join(f for f in required_fields if f)
1097
+ err_msg += f" State should contain fields {required_fields_str}."
1098
+ raise ValueError(err_msg)
1099
+
1100
+ if isinstance(state, dict):
1101
+ tool_state_args = {
1102
+ tool_arg: state[state_field] if state_field else state
1103
+ for tool_arg, state_field in state_args.items()
1104
+ }
1105
+ else:
1106
+ tool_state_args = {
1107
+ tool_arg: getattr(state, state_field) if state_field else state
1108
+ for tool_arg, state_field in state_args.items()
1109
+ }
1110
+
1111
+ tool_call["args"] = {
1112
+ **tool_call["args"],
1113
+ **tool_state_args,
1114
+ }
1115
+ return tool_call
1116
+
1117
+ def _inject_store(self, tool_call: ToolCall, store: BaseStore | None) -> ToolCall:
1118
+ store_arg = self._tool_to_store_arg[tool_call["name"]]
1119
+ if not store_arg:
1120
+ return tool_call
1121
+
1122
+ if store is None:
1123
+ msg = (
1124
+ "Cannot inject store into tools with InjectedStore annotations - "
1125
+ "please compile your graph with a store."
1126
+ )
1127
+ raise ValueError(msg)
1128
+
1129
+ tool_call["args"] = {
1130
+ **tool_call["args"],
1131
+ store_arg: store,
1132
+ }
1133
+ return tool_call
1134
+
1135
+ def _inject_runtime(self, tool_call: ToolCall, tool_runtime: ToolRuntime) -> ToolCall:
1136
+ """Inject ToolRuntime into tool call arguments.
1137
+
1138
+ Args:
1139
+ tool_call: The tool call to inject runtime into.
1140
+ tool_runtime: The ToolRuntime instance to inject.
1141
+
1142
+ Returns:
1143
+ The tool call with runtime injected if needed.
1144
+ """
1145
+ runtime_arg = self._tool_to_runtime_arg.get(tool_call["name"])
1146
+ if not runtime_arg:
1147
+ return tool_call
1148
+
1149
+ tool_call["args"] = {
1150
+ **tool_call["args"],
1151
+ runtime_arg: tool_runtime,
1152
+ }
1153
+ return tool_call
1154
+
1155
+ def _inject_tool_args(
1156
+ self,
1157
+ tool_call: ToolCall,
1158
+ tool_runtime: ToolRuntime,
1159
+ ) -> ToolCall:
1160
+ """Inject graph state, store, and runtime into tool call arguments.
1161
+
1162
+ This is an internal method that enables tools to access graph context that
1163
+ should not be controlled by the model. Tools can declare dependencies on graph
1164
+ state, persistent storage, or runtime context using InjectedState, InjectedStore,
1165
+ and ToolRuntime annotations. This method automatically identifies these
1166
+ dependencies and injects the appropriate values.
1167
+
1168
+ The injection process preserves the original tool call structure while adding
1169
+ the necessary context arguments. This allows tools to be both model-callable
1170
+ and context-aware without exposing internal state management to the model.
1171
+
1172
+ Args:
1173
+ tool_call: The tool call dictionary to augment with injected arguments.
1174
+ Must contain 'name', 'args', 'id', and 'type' fields.
1175
+ tool_runtime: The ToolRuntime instance containing all runtime context
1176
+ (state, config, store, context, stream_writer) to inject into tools.
1177
+
1178
+ Returns:
1179
+ A new ToolCall dictionary with the same structure as the input but with
1180
+ additional arguments injected based on the tool's annotation requirements.
1181
+
1182
+ Raises:
1183
+ ValueError: If a tool requires store injection but no store is provided,
1184
+ or if state injection requirements cannot be satisfied.
1185
+
1186
+ Note:
1187
+ This method is called automatically during tool execution. It should not
1188
+ be called from outside the ToolNode.
1189
+ """
1190
+ if tool_call["name"] not in self.tools_by_name:
1191
+ return tool_call
1192
+
1193
+ tool_call_copy: ToolCall = copy(tool_call)
1194
+ tool_call_with_state = self._inject_state(tool_call_copy, tool_runtime.state)
1195
+ tool_call_with_store = self._inject_store(tool_call_with_state, tool_runtime.store)
1196
+ return self._inject_runtime(tool_call_with_store, tool_runtime)
1197
+
1198
+ def _validate_tool_command(
1199
+ self,
1200
+ command: Command,
1201
+ call: ToolCall,
1202
+ input_type: Literal["list", "dict", "tool_calls"],
1203
+ ) -> Command:
1204
+ if isinstance(command.update, dict):
1205
+ # input type is dict when ToolNode is invoked with a dict input
1206
+ # (e.g. {"messages": [AIMessage(..., tool_calls=[...])]})
1207
+ if input_type not in ("dict", "tool_calls"):
1208
+ msg = (
1209
+ "Tools can provide a dict in Command.update only when using dict "
1210
+ f"with '{self._messages_key}' key as ToolNode input, "
1211
+ f"got: {command.update} for tool '{call['name']}'"
1212
+ )
1213
+ raise ValueError(msg)
1214
+
1215
+ updated_command = deepcopy(command)
1216
+ state_update = cast("dict[str, Any]", updated_command.update) or {}
1217
+ messages_update = state_update.get(self._messages_key, [])
1218
+ elif isinstance(command.update, list):
1219
+ # Input type is list when ToolNode is invoked with a list input
1220
+ # (e.g. [AIMessage(..., tool_calls=[...])])
1221
+ if input_type != "list":
1222
+ msg = (
1223
+ "Tools can provide a list of messages in Command.update "
1224
+ "only when using list of messages as ToolNode input, "
1225
+ f"got: {command.update} for tool '{call['name']}'"
1226
+ )
1227
+ raise ValueError(msg)
1228
+
1229
+ updated_command = deepcopy(command)
1230
+ messages_update = updated_command.update
1231
+ else:
1232
+ return command
1233
+
1234
+ # convert to message objects if updates are in a dict format
1235
+ messages_update = convert_to_messages(messages_update)
1236
+
1237
+ # no validation needed if all messages are being removed
1238
+ if messages_update == [RemoveMessage(id=REMOVE_ALL_MESSAGES)]:
1239
+ return updated_command
1240
+
1241
+ has_matching_tool_message = False
1242
+ for message in messages_update:
1243
+ if not isinstance(message, ToolMessage):
1244
+ continue
1245
+
1246
+ if message.tool_call_id == call["id"]:
1247
+ message.name = call["name"]
1248
+ has_matching_tool_message = True
1249
+
1250
+ # validate that we always have a ToolMessage matching the tool call in
1251
+ # Command.update if command is sent to the CURRENT graph
1252
+ if updated_command.graph is None and not has_matching_tool_message:
1253
+ example_update = (
1254
+ '`Command(update={"messages": '
1255
+ '[ToolMessage("Success", tool_call_id=tool_call_id), ...]}, ...)`'
1256
+ if input_type == "dict"
1257
+ else "`Command(update="
1258
+ '[ToolMessage("Success", tool_call_id=tool_call_id), ...], ...)`'
1259
+ )
1260
+ msg = (
1261
+ "Expected to have a matching ToolMessage in Command.update "
1262
+ f"for tool '{call['name']}', got: {messages_update}. "
1263
+ "Every tool call (LLM requesting to call a tool) "
1264
+ "in the message history MUST have a corresponding ToolMessage. "
1265
+ f"You can fix it by modifying the tool to return {example_update}."
1266
+ )
1267
+ raise ValueError(msg)
1268
+ return updated_command
1269
+
1270
+
1271
+ def tools_condition(
1272
+ state: list[AnyMessage] | dict[str, Any] | BaseModel,
1273
+ messages_key: str = "messages",
1274
+ ) -> Literal["tools", "__end__"]:
1275
+ """Conditional routing function for tool-calling workflows.
1276
+
1277
+ This utility function implements the standard conditional logic for ReAct-style
1278
+ agents: if the last AI message contains tool calls, route to the tool execution
1279
+ node; otherwise, end the workflow. This pattern is fundamental to most tool-calling
1280
+ agent architectures.
1281
+
1282
+ The function handles multiple state formats commonly used in LangGraph applications,
1283
+ making it flexible for different graph designs while maintaining consistent behavior.
1284
+
1285
+ Args:
1286
+ state: The current graph state to examine for tool calls. Supported formats:
1287
+ - Dictionary containing a messages key (for StateGraph)
1288
+ - BaseModel instance with a messages attribute
1289
+ messages_key: The key or attribute name containing the message list in the state.
1290
+ This allows customization for graphs using different state schemas.
1291
+ Defaults to "messages".
1292
+
1293
+ Returns:
1294
+ Either "tools" if tool calls are present in the last AI message, or "__end__"
1295
+ to terminate the workflow. These are the standard routing destinations for
1296
+ tool-calling conditional edges.
1297
+
1298
+ Raises:
1299
+ ValueError: If no messages can be found in the provided state format.
1300
+
1301
+ Example:
1302
+ Basic usage in a ReAct agent:
1303
+
1304
+ ```python
1305
+ from langgraph.graph import StateGraph
1306
+ from langchain.tools import ToolNode
1307
+ from langchain.tools.tool_node import tools_condition
1308
+ from typing_extensions import TypedDict
1309
+
1310
+
1311
+ class State(TypedDict):
1312
+ messages: list
1313
+
1314
+
1315
+ graph = StateGraph(State)
1316
+ graph.add_node("llm", call_model)
1317
+ graph.add_node("tools", ToolNode([my_tool]))
1318
+ graph.add_conditional_edges(
1319
+ "llm",
1320
+ tools_condition, # Routes to "tools" or "__end__"
1321
+ {"tools": "tools", "__end__": "__end__"},
1322
+ )
1323
+ ```
1324
+
1325
+ Custom messages key:
1326
+
1327
+ ```python
1328
+ def custom_condition(state):
1329
+ return tools_condition(state, messages_key="chat_history")
1330
+ ```
1331
+
1332
+ Note:
1333
+ This function is designed to work seamlessly with ToolNode and standard
1334
+ LangGraph patterns. It expects the last message to be an AIMessage when
1335
+ tool calls are present, which is the standard output format for tool-calling
1336
+ language models.
1337
+ """
1338
+ if isinstance(state, list):
1339
+ ai_message = state[-1]
1340
+ elif (isinstance(state, dict) and (messages := state.get(messages_key, []))) or (
1341
+ messages := getattr(state, messages_key, [])
1342
+ ):
1343
+ ai_message = messages[-1]
1344
+ else:
1345
+ msg = f"No messages found in input state to tool_edge: {state}"
1346
+ raise ValueError(msg)
1347
+ if hasattr(ai_message, "tool_calls") and len(ai_message.tool_calls) > 0:
1348
+ return "tools"
1349
+ return "__end__"
1350
+
1351
+
1352
+ @dataclass
1353
+ class ToolRuntime(_DirectlyInjectedToolArg, Generic[ContextT, StateT]):
1354
+ """Runtime context automatically injected into tools.
1355
+
1356
+ When a tool function has a parameter named 'tool_runtime' with type hint
1357
+ 'ToolRuntime', the tool execution system will automatically inject
1358
+ an instance containing:
1359
+
1360
+ - state: The current graph state
1361
+ - tool_call_id: The ID of the current tool call
1362
+ - config: RunnableConfig for the current execution
1363
+ - context: Runtime context (from langgraph Runtime)
1364
+ - store: BaseStore instance for persistent storage (from langgraph Runtime)
1365
+ - stream_writer: StreamWriter for streaming output (from langgraph Runtime)
1366
+
1367
+ No `Annotated` wrapper is needed - just use `runtime: ToolRuntime`
1368
+ as a parameter.
1369
+
1370
+ Example:
1371
+ ```python
1372
+ from langchain_core.tools import tool
1373
+ from langchain.tools import ToolRuntime
1374
+
1375
+ @tool
1376
+ def my_tool(x: int, runtime: ToolRuntime) -> str:
1377
+ \"\"\"Tool that accesses runtime context.\"\"\"
1378
+ # Access state
1379
+ messages = tool_runtime.state["messages"]
1380
+
1381
+ # Access tool_call_id
1382
+ print(f"Tool call ID: {tool_runtime.tool_call_id}")
1383
+
1384
+ # Access config
1385
+ print(f"Run ID: {tool_runtime.config.get('run_id')}")
1386
+
1387
+ # Access runtime context
1388
+ user_id = tool_runtime.context.get("user_id")
1389
+
1390
+ # Access store
1391
+ tool_runtime.store.put(("metrics",), "count", 1)
1392
+
1393
+ # Stream output
1394
+ tool_runtime.stream_writer.write("Processing...")
1395
+
1396
+ return f"Processed {x}"
1397
+ ```
1398
+
1399
+ Note:
1400
+ This is a marker class used for type checking and detection.
1401
+ The actual runtime object will be constructed during tool execution.
1402
+ """
1403
+
1404
+ state: StateT
1405
+ context: ContextT
1406
+ config: RunnableConfig
1407
+ stream_writer: StreamWriter
1408
+ tool_call_id: str | None
1409
+ store: BaseStore | None
1410
+
1411
+
1412
+ class InjectedState(InjectedToolArg):
1413
+ """Annotation for injecting graph state into tool arguments.
1414
+
1415
+ This annotation enables tools to access graph state without exposing state
1416
+ management details to the language model. Tools annotated with `InjectedState`
1417
+ receive state data automatically during execution while remaining invisible
1418
+ to the model's tool-calling interface.
1419
+
1420
+ Args:
1421
+ field: Optional key to extract from the state dictionary. If `None`, the entire
1422
+ state is injected. If specified, only that field's value is injected.
1423
+ This allows tools to request specific state components rather than
1424
+ processing the full state structure.
1425
+
1426
+ Example:
1427
+ ```python
1428
+ from typing import List
1429
+ from typing_extensions import Annotated, TypedDict
1430
+
1431
+ from langchain_core.messages import BaseMessage, AIMessage
1432
+ from langchain.tools import InjectedState, ToolNode, tool
1433
+
1434
+
1435
+ class AgentState(TypedDict):
1436
+ messages: List[BaseMessage]
1437
+ foo: str
1438
+
1439
+
1440
+ @tool
1441
+ def state_tool(x: int, state: Annotated[dict, InjectedState]) -> str:
1442
+ '''Do something with state.'''
1443
+ if len(state["messages"]) > 2:
1444
+ return state["foo"] + str(x)
1445
+ else:
1446
+ return "not enough messages"
1447
+
1448
+
1449
+ @tool
1450
+ def foo_tool(x: int, foo: Annotated[str, InjectedState("foo")]) -> str:
1451
+ '''Do something else with state.'''
1452
+ return foo + str(x + 1)
1453
+
1454
+
1455
+ node = ToolNode([state_tool, foo_tool])
1456
+
1457
+ tool_call1 = {"name": "state_tool", "args": {"x": 1}, "id": "1", "type": "tool_call"}
1458
+ tool_call2 = {"name": "foo_tool", "args": {"x": 1}, "id": "2", "type": "tool_call"}
1459
+ state = {
1460
+ "messages": [AIMessage("", tool_calls=[tool_call1, tool_call2])],
1461
+ "foo": "bar",
1462
+ }
1463
+ node.invoke(state)
1464
+ ```
1465
+
1466
+ ```python
1467
+ [
1468
+ ToolMessage(content="not enough messages", name="state_tool", tool_call_id="1"),
1469
+ ToolMessage(content="bar2", name="foo_tool", tool_call_id="2"),
1470
+ ]
1471
+ ```
1472
+
1473
+ Note:
1474
+ - `InjectedState` arguments are automatically excluded from tool schemas
1475
+ presented to language models
1476
+ - `ToolNode` handles the injection process during execution
1477
+ - Tools can mix regular arguments (controlled by the model) with injected
1478
+ arguments (controlled by the system)
1479
+ - State injection occurs after the model generates tool calls but before
1480
+ tool execution
1481
+ """
1482
+
1483
+ def __init__(self, field: str | None = None) -> None:
1484
+ """Initialize the `InjectedState` annotation."""
1485
+ self.field = field
1486
+
1487
+
1488
+ class InjectedStore(InjectedToolArg):
1489
+ """Annotation for injecting persistent store into tool arguments.
1490
+
1491
+ This annotation enables tools to access LangGraph's persistent storage system
1492
+ without exposing storage details to the language model. Tools annotated with
1493
+ InjectedStore receive the store instance automatically during execution while
1494
+ remaining invisible to the model's tool-calling interface.
1495
+
1496
+ The store provides persistent, cross-session data storage that tools can use
1497
+ for maintaining context, user preferences, or any other data that needs to
1498
+ persist beyond individual workflow executions.
1499
+
1500
+ !!! warning
1501
+ `InjectedStore` annotation requires `langchain-core >= 0.3.8`
1502
+
1503
+ Example:
1504
+ ```python
1505
+ from typing_extensions import Annotated
1506
+ from langgraph.store.memory import InMemoryStore
1507
+ from langchain.tools import InjectedStore, ToolNode, tool
1508
+
1509
+ @tool
1510
+ def save_preference(
1511
+ key: str,
1512
+ value: str,
1513
+ store: Annotated[Any, InjectedStore()]
1514
+ ) -> str:
1515
+ \"\"\"Save user preference to persistent storage.\"\"\"
1516
+ store.put(("preferences",), key, value)
1517
+ return f"Saved {key} = {value}"
1518
+
1519
+ @tool
1520
+ def get_preference(
1521
+ key: str,
1522
+ store: Annotated[Any, InjectedStore()]
1523
+ ) -> str:
1524
+ \"\"\"Retrieve user preference from persistent storage.\"\"\"
1525
+ result = store.get(("preferences",), key)
1526
+ return result.value if result else "Not found"
1527
+ ```
1528
+
1529
+ Usage with `ToolNode` and graph compilation:
1530
+
1531
+ ```python
1532
+ from langgraph.graph import StateGraph
1533
+ from langgraph.store.memory import InMemoryStore
1534
+
1535
+ store = InMemoryStore()
1536
+ tool_node = ToolNode([save_preference, get_preference])
1537
+
1538
+ graph = StateGraph(State)
1539
+ graph.add_node("tools", tool_node)
1540
+ compiled_graph = graph.compile(store=store) # Store is injected automatically
1541
+ ```
1542
+
1543
+ Cross-session persistence:
1544
+
1545
+ ```python
1546
+ # First session
1547
+ result1 = graph.invoke({"messages": [HumanMessage("Save my favorite color as blue")]})
1548
+
1549
+ # Later session - data persists
1550
+ result2 = graph.invoke({"messages": [HumanMessage("What's my favorite color?")]})
1551
+ ```
1552
+
1553
+ Note:
1554
+ - `InjectedStore` arguments are automatically excluded from tool schemas
1555
+ presented to language models
1556
+ - The store instance is automatically injected by `ToolNode` during execution
1557
+ - Tools can access namespaced storage using the store's get/put methods
1558
+ - Store injection requires the graph to be compiled with a store instance
1559
+ - Multiple tools can share the same store instance for data consistency
1560
+ """
1561
+
1562
+
1563
+ def _is_injection(
1564
+ type_arg: Any,
1565
+ injection_type: type[InjectedState | InjectedStore | ToolRuntime],
1566
+ ) -> bool:
1567
+ """Check if a type argument represents an injection annotation.
1568
+
1569
+ This utility function determines whether a type annotation indicates that
1570
+ an argument should be injected with state or store data. It handles both
1571
+ direct annotations and nested annotations within Union or Annotated types.
1572
+
1573
+ Args:
1574
+ type_arg: The type argument to check for injection annotations.
1575
+ injection_type: The injection type to look for (InjectedState or InjectedStore).
1576
+
1577
+ Returns:
1578
+ True if the type argument contains the specified injection annotation.
1579
+ """
1580
+ if isinstance(type_arg, injection_type) or (
1581
+ isinstance(type_arg, type) and issubclass(type_arg, injection_type)
1582
+ ):
1583
+ return True
1584
+ origin_ = get_origin(type_arg)
1585
+ if origin_ is Union or origin_ is Annotated:
1586
+ return any(_is_injection(ta, injection_type) for ta in get_args(type_arg))
1587
+ return False
1588
+
1589
+
1590
+ def _get_state_args(tool: BaseTool) -> dict[str, str | None]:
1591
+ """Extract state injection mappings from tool annotations.
1592
+
1593
+ This function analyzes a tool's input schema to identify arguments that should
1594
+ be injected with graph state. It processes InjectedState annotations to build
1595
+ a mapping of tool argument names to state field names.
1596
+
1597
+ Args:
1598
+ tool: The tool to analyze for state injection requirements.
1599
+
1600
+ Returns:
1601
+ A dictionary mapping tool argument names to state field names. If a field
1602
+ name is None, the entire state should be injected for that argument.
1603
+ """
1604
+ full_schema = tool.get_input_schema()
1605
+ tool_args_to_state_fields: dict = {}
1606
+
1607
+ for name, type_ in get_all_basemodel_annotations(full_schema).items():
1608
+ injections = [
1609
+ type_arg for type_arg in get_args(type_) if _is_injection(type_arg, InjectedState)
1610
+ ]
1611
+ if len(injections) > 1:
1612
+ msg = (
1613
+ "A tool argument should not be annotated with InjectedState more than "
1614
+ f"once. Received arg {name} with annotations {injections}."
1615
+ )
1616
+ raise ValueError(msg)
1617
+ if len(injections) == 1:
1618
+ injection = injections[0]
1619
+ if isinstance(injection, InjectedState) and injection.field:
1620
+ tool_args_to_state_fields[name] = injection.field
1621
+ else:
1622
+ tool_args_to_state_fields[name] = None
1623
+ else:
1624
+ pass
1625
+ return tool_args_to_state_fields
1626
+
1627
+
1628
+ def _get_store_arg(tool: BaseTool) -> str | None:
1629
+ """Extract store injection argument from tool annotations.
1630
+
1631
+ This function analyzes a tool's input schema to identify the argument that
1632
+ should be injected with the graph store. Only one store argument is supported
1633
+ per tool.
1634
+
1635
+ Args:
1636
+ tool: The tool to analyze for store injection requirements.
1637
+
1638
+ Returns:
1639
+ The name of the argument that should receive the store injection, or None
1640
+ if no store injection is required.
1641
+
1642
+ Raises:
1643
+ ValueError: If a tool argument has multiple InjectedStore annotations.
1644
+ """
1645
+ full_schema = tool.get_input_schema()
1646
+ for name, type_ in get_all_basemodel_annotations(full_schema).items():
1647
+ injections = [
1648
+ type_arg for type_arg in get_args(type_) if _is_injection(type_arg, InjectedStore)
1649
+ ]
1650
+ if len(injections) > 1:
1651
+ msg = (
1652
+ "A tool argument should not be annotated with InjectedStore more than "
1653
+ f"once. Received arg {name} with annotations {injections}."
1654
+ )
1655
+ raise ValueError(msg)
1656
+ if len(injections) == 1:
1657
+ return name
1658
+
1659
+ return None
1660
+
1661
+
1662
+ def _get_runtime_arg(tool: BaseTool) -> str | None:
1663
+ """Extract runtime injection argument from tool annotations.
1664
+
1665
+ This function analyzes a tool's input schema to identify the argument that
1666
+ should be injected with the ToolRuntime instance. Only one runtime argument
1667
+ is supported per tool.
1668
+
1669
+ Args:
1670
+ tool: The tool to analyze for runtime injection requirements.
1671
+
1672
+ Returns:
1673
+ The name of the argument that should receive the runtime injection, or None
1674
+ if no runtime injection is required.
1675
+
1676
+ Raises:
1677
+ ValueError: If a tool argument has multiple ToolRuntime annotations.
1678
+ """
1679
+ full_schema = tool.get_input_schema()
1680
+ for name, type_ in get_all_basemodel_annotations(full_schema).items():
1681
+ # Check if the parameter name is "runtime" (regardless of type)
1682
+ if name == "runtime":
1683
+ return name
1684
+ # Check if the type itself is ToolRuntime (direct usage)
1685
+ if _is_injection(type_, ToolRuntime):
1686
+ return name
1687
+ # Check if ToolRuntime is in Annotated args
1688
+ injections = [
1689
+ type_arg for type_arg in get_args(type_) if _is_injection(type_arg, ToolRuntime)
1690
+ ]
1691
+ if len(injections) > 1:
1692
+ msg = (
1693
+ "A tool argument should not be annotated with ToolRuntime more than "
1694
+ f"once. Received arg {name} with annotations {injections}."
1695
+ )
1696
+ raise ValueError(msg)
1697
+ if len(injections) == 1:
1698
+ return name
1699
+
1700
+ return None