langchain 0.3.26__py3-none-any.whl → 0.4.0.dev0__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.
Files changed (591) hide show
  1. langchain/__init__.py +110 -96
  2. langchain/_api/__init__.py +2 -2
  3. langchain/_api/deprecation.py +3 -3
  4. langchain/_api/module_import.py +51 -46
  5. langchain/_api/path.py +1 -1
  6. langchain/adapters/openai.py +8 -8
  7. langchain/agents/__init__.py +15 -12
  8. langchain/agents/agent.py +174 -151
  9. langchain/agents/agent_iterator.py +50 -26
  10. langchain/agents/agent_toolkits/__init__.py +7 -6
  11. langchain/agents/agent_toolkits/ainetwork/toolkit.py +1 -1
  12. langchain/agents/agent_toolkits/amadeus/toolkit.py +1 -1
  13. langchain/agents/agent_toolkits/azure_cognitive_services.py +1 -1
  14. langchain/agents/agent_toolkits/clickup/toolkit.py +1 -1
  15. langchain/agents/agent_toolkits/conversational_retrieval/openai_functions.py +6 -4
  16. langchain/agents/agent_toolkits/csv/__init__.py +4 -2
  17. langchain/agents/agent_toolkits/file_management/__init__.py +1 -1
  18. langchain/agents/agent_toolkits/file_management/toolkit.py +1 -1
  19. langchain/agents/agent_toolkits/github/toolkit.py +9 -9
  20. langchain/agents/agent_toolkits/gitlab/toolkit.py +1 -1
  21. langchain/agents/agent_toolkits/json/base.py +1 -1
  22. langchain/agents/agent_toolkits/multion/toolkit.py +1 -1
  23. langchain/agents/agent_toolkits/office365/toolkit.py +1 -1
  24. langchain/agents/agent_toolkits/openapi/base.py +1 -1
  25. langchain/agents/agent_toolkits/openapi/planner.py +2 -2
  26. langchain/agents/agent_toolkits/openapi/planner_prompt.py +10 -10
  27. langchain/agents/agent_toolkits/openapi/prompt.py +1 -1
  28. langchain/agents/agent_toolkits/openapi/toolkit.py +1 -1
  29. langchain/agents/agent_toolkits/pandas/__init__.py +4 -2
  30. langchain/agents/agent_toolkits/playwright/__init__.py +1 -1
  31. langchain/agents/agent_toolkits/playwright/toolkit.py +1 -1
  32. langchain/agents/agent_toolkits/powerbi/base.py +1 -1
  33. langchain/agents/agent_toolkits/powerbi/chat_base.py +1 -1
  34. langchain/agents/agent_toolkits/powerbi/prompt.py +2 -2
  35. langchain/agents/agent_toolkits/powerbi/toolkit.py +1 -1
  36. langchain/agents/agent_toolkits/python/__init__.py +4 -2
  37. langchain/agents/agent_toolkits/spark/__init__.py +4 -2
  38. langchain/agents/agent_toolkits/spark_sql/base.py +1 -1
  39. langchain/agents/agent_toolkits/spark_sql/toolkit.py +1 -1
  40. langchain/agents/agent_toolkits/sql/prompt.py +1 -1
  41. langchain/agents/agent_toolkits/sql/toolkit.py +1 -1
  42. langchain/agents/agent_toolkits/vectorstore/base.py +4 -2
  43. langchain/agents/agent_toolkits/vectorstore/prompt.py +2 -4
  44. langchain/agents/agent_toolkits/vectorstore/toolkit.py +12 -11
  45. langchain/agents/agent_toolkits/xorbits/__init__.py +4 -2
  46. langchain/agents/agent_toolkits/zapier/toolkit.py +1 -1
  47. langchain/agents/agent_types.py +6 -6
  48. langchain/agents/chat/base.py +8 -12
  49. langchain/agents/chat/output_parser.py +9 -6
  50. langchain/agents/chat/prompt.py +3 -4
  51. langchain/agents/conversational/base.py +11 -5
  52. langchain/agents/conversational/output_parser.py +4 -2
  53. langchain/agents/conversational/prompt.py +2 -3
  54. langchain/agents/conversational_chat/base.py +9 -5
  55. langchain/agents/conversational_chat/output_parser.py +9 -11
  56. langchain/agents/conversational_chat/prompt.py +5 -6
  57. langchain/agents/format_scratchpad/__init__.py +3 -3
  58. langchain/agents/format_scratchpad/log_to_messages.py +1 -1
  59. langchain/agents/format_scratchpad/openai_functions.py +8 -6
  60. langchain/agents/format_scratchpad/tools.py +5 -3
  61. langchain/agents/format_scratchpad/xml.py +33 -2
  62. langchain/agents/initialize.py +17 -9
  63. langchain/agents/json_chat/base.py +19 -18
  64. langchain/agents/json_chat/prompt.py +2 -3
  65. langchain/agents/load_tools.py +2 -1
  66. langchain/agents/loading.py +28 -18
  67. langchain/agents/mrkl/base.py +11 -4
  68. langchain/agents/mrkl/output_parser.py +17 -13
  69. langchain/agents/mrkl/prompt.py +1 -2
  70. langchain/agents/openai_assistant/base.py +81 -71
  71. langchain/agents/openai_functions_agent/agent_token_buffer_memory.py +2 -0
  72. langchain/agents/openai_functions_agent/base.py +47 -37
  73. langchain/agents/openai_functions_multi_agent/base.py +40 -27
  74. langchain/agents/openai_tools/base.py +9 -8
  75. langchain/agents/output_parsers/__init__.py +3 -3
  76. langchain/agents/output_parsers/json.py +8 -6
  77. langchain/agents/output_parsers/openai_functions.py +24 -9
  78. langchain/agents/output_parsers/openai_tools.py +16 -4
  79. langchain/agents/output_parsers/react_json_single_input.py +13 -5
  80. langchain/agents/output_parsers/react_single_input.py +18 -11
  81. langchain/agents/output_parsers/self_ask.py +5 -2
  82. langchain/agents/output_parsers/tools.py +32 -13
  83. langchain/agents/output_parsers/xml.py +102 -28
  84. langchain/agents/react/agent.py +5 -4
  85. langchain/agents/react/base.py +26 -17
  86. langchain/agents/react/output_parser.py +7 -6
  87. langchain/agents/react/textworld_prompt.py +0 -1
  88. langchain/agents/react/wiki_prompt.py +14 -15
  89. langchain/agents/schema.py +5 -2
  90. langchain/agents/self_ask_with_search/base.py +23 -15
  91. langchain/agents/self_ask_with_search/prompt.py +0 -1
  92. langchain/agents/structured_chat/base.py +19 -11
  93. langchain/agents/structured_chat/output_parser.py +29 -18
  94. langchain/agents/structured_chat/prompt.py +3 -4
  95. langchain/agents/tool_calling_agent/base.py +8 -6
  96. langchain/agents/tools.py +5 -2
  97. langchain/agents/utils.py +2 -3
  98. langchain/agents/xml/base.py +12 -6
  99. langchain/agents/xml/prompt.py +1 -2
  100. langchain/cache.py +12 -12
  101. langchain/callbacks/__init__.py +11 -11
  102. langchain/callbacks/aim_callback.py +2 -2
  103. langchain/callbacks/argilla_callback.py +1 -1
  104. langchain/callbacks/arize_callback.py +1 -1
  105. langchain/callbacks/arthur_callback.py +1 -1
  106. langchain/callbacks/base.py +7 -7
  107. langchain/callbacks/clearml_callback.py +1 -1
  108. langchain/callbacks/comet_ml_callback.py +1 -1
  109. langchain/callbacks/confident_callback.py +1 -1
  110. langchain/callbacks/context_callback.py +1 -1
  111. langchain/callbacks/flyte_callback.py +1 -1
  112. langchain/callbacks/human.py +2 -2
  113. langchain/callbacks/infino_callback.py +1 -1
  114. langchain/callbacks/labelstudio_callback.py +1 -1
  115. langchain/callbacks/llmonitor_callback.py +1 -1
  116. langchain/callbacks/manager.py +5 -5
  117. langchain/callbacks/mlflow_callback.py +2 -2
  118. langchain/callbacks/openai_info.py +1 -1
  119. langchain/callbacks/promptlayer_callback.py +1 -1
  120. langchain/callbacks/sagemaker_callback.py +1 -1
  121. langchain/callbacks/streaming_aiter.py +17 -3
  122. langchain/callbacks/streaming_aiter_final_only.py +16 -5
  123. langchain/callbacks/streaming_stdout_final_only.py +10 -3
  124. langchain/callbacks/streamlit/__init__.py +3 -2
  125. langchain/callbacks/streamlit/mutable_expander.py +1 -1
  126. langchain/callbacks/streamlit/streamlit_callback_handler.py +3 -3
  127. langchain/callbacks/tracers/__init__.py +1 -1
  128. langchain/callbacks/tracers/comet.py +1 -1
  129. langchain/callbacks/tracers/evaluation.py +1 -1
  130. langchain/callbacks/tracers/log_stream.py +1 -1
  131. langchain/callbacks/tracers/logging.py +12 -1
  132. langchain/callbacks/tracers/stdout.py +1 -1
  133. langchain/callbacks/trubrics_callback.py +1 -1
  134. langchain/callbacks/utils.py +4 -4
  135. langchain/callbacks/wandb_callback.py +1 -1
  136. langchain/callbacks/whylabs_callback.py +1 -1
  137. langchain/chains/api/base.py +41 -23
  138. langchain/chains/api/news_docs.py +1 -2
  139. langchain/chains/api/open_meteo_docs.py +1 -2
  140. langchain/chains/api/openapi/requests_chain.py +1 -1
  141. langchain/chains/api/openapi/response_chain.py +1 -1
  142. langchain/chains/api/podcast_docs.py +1 -2
  143. langchain/chains/api/prompt.py +1 -2
  144. langchain/chains/api/tmdb_docs.py +1 -2
  145. langchain/chains/base.py +96 -56
  146. langchain/chains/chat_vector_db/prompts.py +2 -3
  147. langchain/chains/combine_documents/__init__.py +1 -1
  148. langchain/chains/combine_documents/base.py +30 -11
  149. langchain/chains/combine_documents/map_reduce.py +41 -30
  150. langchain/chains/combine_documents/map_rerank.py +39 -24
  151. langchain/chains/combine_documents/reduce.py +48 -26
  152. langchain/chains/combine_documents/refine.py +27 -17
  153. langchain/chains/combine_documents/stuff.py +24 -13
  154. langchain/chains/constitutional_ai/base.py +11 -4
  155. langchain/chains/constitutional_ai/principles.py +22 -25
  156. langchain/chains/constitutional_ai/prompts.py +25 -28
  157. langchain/chains/conversation/base.py +9 -4
  158. langchain/chains/conversation/memory.py +5 -5
  159. langchain/chains/conversation/prompt.py +5 -5
  160. langchain/chains/conversational_retrieval/base.py +108 -79
  161. langchain/chains/conversational_retrieval/prompts.py +2 -3
  162. langchain/chains/elasticsearch_database/base.py +10 -10
  163. langchain/chains/elasticsearch_database/prompts.py +2 -3
  164. langchain/chains/ernie_functions/__init__.py +2 -2
  165. langchain/chains/example_generator.py +3 -1
  166. langchain/chains/flare/base.py +28 -12
  167. langchain/chains/flare/prompts.py +2 -0
  168. langchain/chains/graph_qa/cypher.py +2 -2
  169. langchain/chains/graph_qa/falkordb.py +1 -1
  170. langchain/chains/graph_qa/gremlin.py +1 -1
  171. langchain/chains/graph_qa/neptune_sparql.py +1 -1
  172. langchain/chains/graph_qa/prompts.py +2 -2
  173. langchain/chains/history_aware_retriever.py +2 -1
  174. langchain/chains/hyde/base.py +6 -5
  175. langchain/chains/hyde/prompts.py +5 -6
  176. langchain/chains/llm.py +82 -61
  177. langchain/chains/llm_bash/__init__.py +3 -2
  178. langchain/chains/llm_checker/base.py +19 -6
  179. langchain/chains/llm_checker/prompt.py +3 -4
  180. langchain/chains/llm_math/base.py +25 -10
  181. langchain/chains/llm_math/prompt.py +1 -2
  182. langchain/chains/llm_summarization_checker/base.py +22 -7
  183. langchain/chains/llm_symbolic_math/__init__.py +3 -2
  184. langchain/chains/loading.py +155 -97
  185. langchain/chains/mapreduce.py +4 -3
  186. langchain/chains/moderation.py +11 -9
  187. langchain/chains/natbot/base.py +11 -9
  188. langchain/chains/natbot/crawler.py +102 -76
  189. langchain/chains/natbot/prompt.py +2 -3
  190. langchain/chains/openai_functions/__init__.py +7 -7
  191. langchain/chains/openai_functions/base.py +15 -10
  192. langchain/chains/openai_functions/citation_fuzzy_match.py +21 -11
  193. langchain/chains/openai_functions/extraction.py +19 -19
  194. langchain/chains/openai_functions/openapi.py +39 -35
  195. langchain/chains/openai_functions/qa_with_structure.py +22 -15
  196. langchain/chains/openai_functions/tagging.py +4 -4
  197. langchain/chains/openai_tools/extraction.py +7 -8
  198. langchain/chains/qa_generation/base.py +8 -3
  199. langchain/chains/qa_generation/prompt.py +5 -5
  200. langchain/chains/qa_with_sources/base.py +17 -6
  201. langchain/chains/qa_with_sources/loading.py +16 -8
  202. langchain/chains/qa_with_sources/map_reduce_prompt.py +8 -9
  203. langchain/chains/qa_with_sources/refine_prompts.py +0 -1
  204. langchain/chains/qa_with_sources/retrieval.py +15 -6
  205. langchain/chains/qa_with_sources/stuff_prompt.py +6 -7
  206. langchain/chains/qa_with_sources/vector_db.py +21 -8
  207. langchain/chains/query_constructor/base.py +37 -34
  208. langchain/chains/query_constructor/ir.py +4 -4
  209. langchain/chains/query_constructor/parser.py +101 -34
  210. langchain/chains/query_constructor/prompt.py +5 -6
  211. langchain/chains/question_answering/chain.py +21 -10
  212. langchain/chains/question_answering/map_reduce_prompt.py +14 -14
  213. langchain/chains/question_answering/map_rerank_prompt.py +3 -3
  214. langchain/chains/question_answering/refine_prompts.py +2 -5
  215. langchain/chains/question_answering/stuff_prompt.py +5 -5
  216. langchain/chains/retrieval.py +1 -3
  217. langchain/chains/retrieval_qa/base.py +38 -27
  218. langchain/chains/retrieval_qa/prompt.py +1 -2
  219. langchain/chains/router/__init__.py +3 -3
  220. langchain/chains/router/base.py +38 -22
  221. langchain/chains/router/embedding_router.py +15 -8
  222. langchain/chains/router/llm_router.py +23 -20
  223. langchain/chains/router/multi_prompt.py +5 -2
  224. langchain/chains/router/multi_retrieval_qa.py +28 -5
  225. langchain/chains/sequential.py +30 -18
  226. langchain/chains/sql_database/prompt.py +14 -16
  227. langchain/chains/sql_database/query.py +7 -5
  228. langchain/chains/structured_output/__init__.py +1 -1
  229. langchain/chains/structured_output/base.py +77 -67
  230. langchain/chains/summarize/chain.py +11 -5
  231. langchain/chains/summarize/map_reduce_prompt.py +0 -1
  232. langchain/chains/summarize/stuff_prompt.py +0 -1
  233. langchain/chains/transform.py +9 -6
  234. langchain/chat_loaders/facebook_messenger.py +1 -1
  235. langchain/chat_loaders/langsmith.py +1 -1
  236. langchain/chat_loaders/utils.py +3 -3
  237. langchain/chat_models/__init__.py +20 -19
  238. langchain/chat_models/anthropic.py +1 -1
  239. langchain/chat_models/azureml_endpoint.py +1 -1
  240. langchain/chat_models/baidu_qianfan_endpoint.py +1 -1
  241. langchain/chat_models/base.py +213 -139
  242. langchain/chat_models/bedrock.py +1 -1
  243. langchain/chat_models/fake.py +1 -1
  244. langchain/chat_models/meta.py +1 -1
  245. langchain/chat_models/pai_eas_endpoint.py +1 -1
  246. langchain/chat_models/promptlayer_openai.py +1 -1
  247. langchain/chat_models/volcengine_maas.py +1 -1
  248. langchain/docstore/base.py +1 -1
  249. langchain/document_loaders/__init__.py +9 -9
  250. langchain/document_loaders/airbyte.py +3 -3
  251. langchain/document_loaders/assemblyai.py +1 -1
  252. langchain/document_loaders/azure_blob_storage_container.py +1 -1
  253. langchain/document_loaders/azure_blob_storage_file.py +1 -1
  254. langchain/document_loaders/baiducloud_bos_file.py +1 -1
  255. langchain/document_loaders/base.py +1 -1
  256. langchain/document_loaders/blob_loaders/__init__.py +1 -1
  257. langchain/document_loaders/blob_loaders/schema.py +1 -4
  258. langchain/document_loaders/blockchain.py +1 -1
  259. langchain/document_loaders/chatgpt.py +1 -1
  260. langchain/document_loaders/college_confidential.py +1 -1
  261. langchain/document_loaders/confluence.py +1 -1
  262. langchain/document_loaders/email.py +1 -1
  263. langchain/document_loaders/facebook_chat.py +1 -1
  264. langchain/document_loaders/markdown.py +1 -1
  265. langchain/document_loaders/notebook.py +1 -1
  266. langchain/document_loaders/org_mode.py +1 -1
  267. langchain/document_loaders/parsers/__init__.py +1 -1
  268. langchain/document_loaders/parsers/docai.py +1 -1
  269. langchain/document_loaders/parsers/generic.py +1 -1
  270. langchain/document_loaders/parsers/html/__init__.py +1 -1
  271. langchain/document_loaders/parsers/html/bs4.py +1 -1
  272. langchain/document_loaders/parsers/language/cobol.py +1 -1
  273. langchain/document_loaders/parsers/language/python.py +1 -1
  274. langchain/document_loaders/parsers/msword.py +1 -1
  275. langchain/document_loaders/parsers/pdf.py +5 -5
  276. langchain/document_loaders/parsers/registry.py +1 -1
  277. langchain/document_loaders/pdf.py +8 -8
  278. langchain/document_loaders/powerpoint.py +1 -1
  279. langchain/document_loaders/pyspark_dataframe.py +1 -1
  280. langchain/document_loaders/telegram.py +2 -2
  281. langchain/document_loaders/tencent_cos_directory.py +1 -1
  282. langchain/document_loaders/unstructured.py +5 -5
  283. langchain/document_loaders/url_playwright.py +1 -1
  284. langchain/document_loaders/whatsapp_chat.py +1 -1
  285. langchain/document_loaders/youtube.py +2 -2
  286. langchain/document_transformers/__init__.py +3 -3
  287. langchain/document_transformers/beautiful_soup_transformer.py +1 -1
  288. langchain/document_transformers/doctran_text_extract.py +1 -1
  289. langchain/document_transformers/doctran_text_qa.py +1 -1
  290. langchain/document_transformers/doctran_text_translate.py +1 -1
  291. langchain/document_transformers/embeddings_redundant_filter.py +3 -3
  292. langchain/document_transformers/google_translate.py +1 -1
  293. langchain/document_transformers/html2text.py +1 -1
  294. langchain/document_transformers/nuclia_text_transform.py +1 -1
  295. langchain/embeddings/__init__.py +5 -5
  296. langchain/embeddings/base.py +35 -24
  297. langchain/embeddings/cache.py +37 -32
  298. langchain/embeddings/fake.py +1 -1
  299. langchain/embeddings/huggingface.py +2 -2
  300. langchain/evaluation/__init__.py +22 -22
  301. langchain/evaluation/agents/trajectory_eval_chain.py +26 -25
  302. langchain/evaluation/agents/trajectory_eval_prompt.py +6 -9
  303. langchain/evaluation/comparison/__init__.py +1 -1
  304. langchain/evaluation/comparison/eval_chain.py +21 -13
  305. langchain/evaluation/comparison/prompt.py +1 -2
  306. langchain/evaluation/criteria/__init__.py +1 -1
  307. langchain/evaluation/criteria/eval_chain.py +23 -11
  308. langchain/evaluation/criteria/prompt.py +2 -3
  309. langchain/evaluation/embedding_distance/base.py +34 -20
  310. langchain/evaluation/exact_match/base.py +14 -1
  311. langchain/evaluation/loading.py +16 -11
  312. langchain/evaluation/parsing/base.py +20 -4
  313. langchain/evaluation/parsing/json_distance.py +24 -10
  314. langchain/evaluation/parsing/json_schema.py +13 -12
  315. langchain/evaluation/qa/__init__.py +1 -1
  316. langchain/evaluation/qa/eval_chain.py +20 -5
  317. langchain/evaluation/qa/eval_prompt.py +7 -8
  318. langchain/evaluation/qa/generate_chain.py +4 -1
  319. langchain/evaluation/qa/generate_prompt.py +2 -4
  320. langchain/evaluation/regex_match/base.py +9 -1
  321. langchain/evaluation/schema.py +38 -30
  322. langchain/evaluation/scoring/__init__.py +1 -1
  323. langchain/evaluation/scoring/eval_chain.py +23 -15
  324. langchain/evaluation/scoring/prompt.py +0 -1
  325. langchain/evaluation/string_distance/base.py +20 -9
  326. langchain/globals.py +12 -11
  327. langchain/graphs/__init__.py +6 -6
  328. langchain/graphs/graph_document.py +1 -1
  329. langchain/graphs/networkx_graph.py +2 -2
  330. langchain/hub.py +9 -11
  331. langchain/indexes/__init__.py +3 -3
  332. langchain/indexes/_sql_record_manager.py +63 -46
  333. langchain/indexes/prompts/entity_extraction.py +1 -2
  334. langchain/indexes/prompts/entity_summarization.py +1 -2
  335. langchain/indexes/prompts/knowledge_triplet_extraction.py +1 -3
  336. langchain/indexes/vectorstore.py +35 -19
  337. langchain/llms/__init__.py +13 -13
  338. langchain/llms/ai21.py +1 -1
  339. langchain/llms/azureml_endpoint.py +4 -4
  340. langchain/llms/base.py +15 -7
  341. langchain/llms/bedrock.py +1 -1
  342. langchain/llms/cloudflare_workersai.py +1 -1
  343. langchain/llms/gradient_ai.py +1 -1
  344. langchain/llms/loading.py +1 -1
  345. langchain/llms/openai.py +1 -1
  346. langchain/llms/sagemaker_endpoint.py +1 -1
  347. langchain/load/dump.py +1 -1
  348. langchain/load/load.py +1 -1
  349. langchain/load/serializable.py +3 -3
  350. langchain/memory/__init__.py +3 -3
  351. langchain/memory/buffer.py +14 -7
  352. langchain/memory/buffer_window.py +2 -0
  353. langchain/memory/chat_memory.py +14 -8
  354. langchain/memory/chat_message_histories/__init__.py +1 -1
  355. langchain/memory/chat_message_histories/astradb.py +1 -1
  356. langchain/memory/chat_message_histories/cassandra.py +1 -1
  357. langchain/memory/chat_message_histories/cosmos_db.py +1 -1
  358. langchain/memory/chat_message_histories/dynamodb.py +1 -1
  359. langchain/memory/chat_message_histories/elasticsearch.py +1 -1
  360. langchain/memory/chat_message_histories/file.py +1 -1
  361. langchain/memory/chat_message_histories/firestore.py +1 -1
  362. langchain/memory/chat_message_histories/momento.py +1 -1
  363. langchain/memory/chat_message_histories/mongodb.py +1 -1
  364. langchain/memory/chat_message_histories/neo4j.py +1 -1
  365. langchain/memory/chat_message_histories/postgres.py +1 -1
  366. langchain/memory/chat_message_histories/redis.py +1 -1
  367. langchain/memory/chat_message_histories/rocksetdb.py +1 -1
  368. langchain/memory/chat_message_histories/singlestoredb.py +1 -1
  369. langchain/memory/chat_message_histories/streamlit.py +1 -1
  370. langchain/memory/chat_message_histories/upstash_redis.py +1 -1
  371. langchain/memory/chat_message_histories/xata.py +1 -1
  372. langchain/memory/chat_message_histories/zep.py +1 -1
  373. langchain/memory/combined.py +14 -13
  374. langchain/memory/entity.py +131 -61
  375. langchain/memory/prompt.py +10 -11
  376. langchain/memory/readonly.py +0 -2
  377. langchain/memory/simple.py +4 -3
  378. langchain/memory/summary.py +43 -11
  379. langchain/memory/summary_buffer.py +20 -8
  380. langchain/memory/token_buffer.py +2 -0
  381. langchain/memory/utils.py +3 -2
  382. langchain/memory/vectorstore.py +12 -5
  383. langchain/memory/vectorstore_token_buffer_memory.py +5 -5
  384. langchain/model_laboratory.py +12 -11
  385. langchain/output_parsers/__init__.py +4 -4
  386. langchain/output_parsers/boolean.py +7 -4
  387. langchain/output_parsers/combining.py +14 -7
  388. langchain/output_parsers/datetime.py +32 -31
  389. langchain/output_parsers/enum.py +10 -4
  390. langchain/output_parsers/fix.py +60 -53
  391. langchain/output_parsers/format_instructions.py +6 -8
  392. langchain/output_parsers/json.py +2 -2
  393. langchain/output_parsers/list.py +2 -2
  394. langchain/output_parsers/loading.py +9 -9
  395. langchain/output_parsers/openai_functions.py +3 -3
  396. langchain/output_parsers/openai_tools.py +1 -1
  397. langchain/output_parsers/pandas_dataframe.py +59 -48
  398. langchain/output_parsers/prompts.py +1 -2
  399. langchain/output_parsers/rail_parser.py +1 -1
  400. langchain/output_parsers/regex.py +9 -8
  401. langchain/output_parsers/regex_dict.py +7 -10
  402. langchain/output_parsers/retry.py +99 -80
  403. langchain/output_parsers/structured.py +21 -6
  404. langchain/output_parsers/yaml.py +19 -11
  405. langchain/prompts/__init__.py +5 -3
  406. langchain/prompts/base.py +5 -5
  407. langchain/prompts/chat.py +8 -8
  408. langchain/prompts/example_selector/__init__.py +3 -1
  409. langchain/prompts/example_selector/semantic_similarity.py +2 -2
  410. langchain/prompts/few_shot.py +1 -1
  411. langchain/prompts/loading.py +3 -3
  412. langchain/prompts/prompt.py +1 -1
  413. langchain/pydantic_v1/__init__.py +1 -1
  414. langchain/retrievers/__init__.py +5 -5
  415. langchain/retrievers/bedrock.py +2 -2
  416. langchain/retrievers/bm25.py +1 -1
  417. langchain/retrievers/contextual_compression.py +14 -8
  418. langchain/retrievers/docarray.py +1 -1
  419. langchain/retrievers/document_compressors/__init__.py +5 -4
  420. langchain/retrievers/document_compressors/base.py +12 -6
  421. langchain/retrievers/document_compressors/chain_extract.py +5 -3
  422. langchain/retrievers/document_compressors/chain_extract_prompt.py +2 -3
  423. langchain/retrievers/document_compressors/chain_filter.py +9 -9
  424. langchain/retrievers/document_compressors/chain_filter_prompt.py +1 -2
  425. langchain/retrievers/document_compressors/cohere_rerank.py +17 -15
  426. langchain/retrievers/document_compressors/cross_encoder_rerank.py +2 -0
  427. langchain/retrievers/document_compressors/embeddings_filter.py +24 -17
  428. langchain/retrievers/document_compressors/flashrank_rerank.py +1 -1
  429. langchain/retrievers/document_compressors/listwise_rerank.py +8 -5
  430. langchain/retrievers/ensemble.py +30 -27
  431. langchain/retrievers/google_cloud_documentai_warehouse.py +1 -1
  432. langchain/retrievers/google_vertex_ai_search.py +2 -2
  433. langchain/retrievers/kendra.py +10 -10
  434. langchain/retrievers/llama_index.py +1 -1
  435. langchain/retrievers/merger_retriever.py +11 -11
  436. langchain/retrievers/milvus.py +1 -1
  437. langchain/retrievers/multi_query.py +35 -27
  438. langchain/retrievers/multi_vector.py +24 -9
  439. langchain/retrievers/parent_document_retriever.py +33 -9
  440. langchain/retrievers/re_phraser.py +6 -5
  441. langchain/retrievers/self_query/base.py +157 -127
  442. langchain/retrievers/time_weighted_retriever.py +21 -7
  443. langchain/retrievers/zilliz.py +1 -1
  444. langchain/runnables/hub.py +12 -0
  445. langchain/runnables/openai_functions.py +12 -2
  446. langchain/schema/__init__.py +23 -23
  447. langchain/schema/cache.py +1 -1
  448. langchain/schema/callbacks/base.py +7 -7
  449. langchain/schema/callbacks/manager.py +19 -19
  450. langchain/schema/callbacks/tracers/base.py +1 -1
  451. langchain/schema/callbacks/tracers/evaluation.py +1 -1
  452. langchain/schema/callbacks/tracers/langchain.py +1 -1
  453. langchain/schema/callbacks/tracers/langchain_v1.py +1 -1
  454. langchain/schema/callbacks/tracers/log_stream.py +1 -1
  455. langchain/schema/callbacks/tracers/schemas.py +8 -8
  456. langchain/schema/callbacks/tracers/stdout.py +3 -3
  457. langchain/schema/document.py +1 -1
  458. langchain/schema/language_model.py +2 -2
  459. langchain/schema/messages.py +12 -12
  460. langchain/schema/output.py +3 -3
  461. langchain/schema/output_parser.py +3 -3
  462. langchain/schema/runnable/__init__.py +3 -3
  463. langchain/schema/runnable/base.py +9 -9
  464. langchain/schema/runnable/config.py +5 -5
  465. langchain/schema/runnable/configurable.py +1 -1
  466. langchain/schema/runnable/history.py +1 -1
  467. langchain/schema/runnable/passthrough.py +1 -1
  468. langchain/schema/runnable/utils.py +16 -16
  469. langchain/schema/vectorstore.py +1 -1
  470. langchain/smith/__init__.py +2 -1
  471. langchain/smith/evaluation/__init__.py +2 -2
  472. langchain/smith/evaluation/config.py +9 -23
  473. langchain/smith/evaluation/name_generation.py +3 -3
  474. langchain/smith/evaluation/progress.py +22 -4
  475. langchain/smith/evaluation/runner_utils.py +416 -247
  476. langchain/smith/evaluation/string_run_evaluator.py +102 -68
  477. langchain/storage/__init__.py +2 -2
  478. langchain/storage/_lc_store.py +4 -2
  479. langchain/storage/encoder_backed.py +7 -2
  480. langchain/storage/file_system.py +19 -16
  481. langchain/storage/in_memory.py +1 -1
  482. langchain/storage/upstash_redis.py +1 -1
  483. langchain/text_splitter.py +15 -15
  484. langchain/tools/__init__.py +28 -26
  485. langchain/tools/ainetwork/app.py +1 -1
  486. langchain/tools/ainetwork/base.py +1 -1
  487. langchain/tools/ainetwork/owner.py +1 -1
  488. langchain/tools/ainetwork/rule.py +1 -1
  489. langchain/tools/ainetwork/transfer.py +1 -1
  490. langchain/tools/ainetwork/value.py +1 -1
  491. langchain/tools/amadeus/closest_airport.py +1 -1
  492. langchain/tools/amadeus/flight_search.py +1 -1
  493. langchain/tools/azure_cognitive_services/__init__.py +1 -1
  494. langchain/tools/base.py +4 -4
  495. langchain/tools/bearly/tool.py +1 -1
  496. langchain/tools/bing_search/__init__.py +1 -1
  497. langchain/tools/bing_search/tool.py +1 -1
  498. langchain/tools/dataforseo_api_search/__init__.py +1 -1
  499. langchain/tools/dataforseo_api_search/tool.py +1 -1
  500. langchain/tools/ddg_search/tool.py +1 -1
  501. langchain/tools/e2b_data_analysis/tool.py +2 -2
  502. langchain/tools/edenai/__init__.py +1 -1
  503. langchain/tools/file_management/__init__.py +1 -1
  504. langchain/tools/file_management/copy.py +1 -1
  505. langchain/tools/file_management/delete.py +1 -1
  506. langchain/tools/gmail/__init__.py +2 -2
  507. langchain/tools/gmail/get_message.py +1 -1
  508. langchain/tools/gmail/search.py +1 -1
  509. langchain/tools/gmail/send_message.py +1 -1
  510. langchain/tools/google_finance/__init__.py +1 -1
  511. langchain/tools/google_finance/tool.py +1 -1
  512. langchain/tools/google_scholar/__init__.py +1 -1
  513. langchain/tools/google_scholar/tool.py +1 -1
  514. langchain/tools/google_search/__init__.py +1 -1
  515. langchain/tools/google_search/tool.py +1 -1
  516. langchain/tools/google_serper/__init__.py +1 -1
  517. langchain/tools/google_serper/tool.py +1 -1
  518. langchain/tools/google_trends/__init__.py +1 -1
  519. langchain/tools/google_trends/tool.py +1 -1
  520. langchain/tools/jira/tool.py +20 -1
  521. langchain/tools/json/tool.py +25 -3
  522. langchain/tools/memorize/tool.py +1 -1
  523. langchain/tools/multion/__init__.py +1 -1
  524. langchain/tools/multion/update_session.py +1 -1
  525. langchain/tools/office365/__init__.py +2 -2
  526. langchain/tools/office365/events_search.py +1 -1
  527. langchain/tools/office365/messages_search.py +1 -1
  528. langchain/tools/office365/send_event.py +1 -1
  529. langchain/tools/office365/send_message.py +1 -1
  530. langchain/tools/openapi/utils/api_models.py +6 -6
  531. langchain/tools/playwright/__init__.py +5 -5
  532. langchain/tools/playwright/click.py +1 -1
  533. langchain/tools/playwright/extract_hyperlinks.py +1 -1
  534. langchain/tools/playwright/get_elements.py +1 -1
  535. langchain/tools/playwright/navigate.py +1 -1
  536. langchain/tools/plugin.py +2 -2
  537. langchain/tools/powerbi/tool.py +1 -1
  538. langchain/tools/python/__init__.py +3 -2
  539. langchain/tools/reddit_search/tool.py +1 -1
  540. langchain/tools/render.py +2 -2
  541. langchain/tools/requests/tool.py +2 -2
  542. langchain/tools/searchapi/tool.py +1 -1
  543. langchain/tools/searx_search/tool.py +1 -1
  544. langchain/tools/slack/get_message.py +1 -1
  545. langchain/tools/spark_sql/tool.py +1 -1
  546. langchain/tools/sql_database/tool.py +1 -1
  547. langchain/tools/tavily_search/__init__.py +1 -1
  548. langchain/tools/tavily_search/tool.py +1 -1
  549. langchain/tools/zapier/__init__.py +1 -1
  550. langchain/tools/zapier/tool.py +24 -2
  551. langchain/utilities/__init__.py +4 -4
  552. langchain/utilities/arcee.py +4 -4
  553. langchain/utilities/clickup.py +4 -4
  554. langchain/utilities/dalle_image_generator.py +1 -1
  555. langchain/utilities/dataforseo_api_search.py +1 -1
  556. langchain/utilities/opaqueprompts.py +1 -1
  557. langchain/utilities/reddit_search.py +1 -1
  558. langchain/utilities/sql_database.py +1 -1
  559. langchain/utilities/tavily_search.py +1 -1
  560. langchain/utilities/vertexai.py +2 -2
  561. langchain/utils/__init__.py +1 -1
  562. langchain/utils/aiter.py +1 -1
  563. langchain/utils/html.py +3 -3
  564. langchain/utils/input.py +1 -1
  565. langchain/utils/iter.py +1 -1
  566. langchain/utils/json_schema.py +1 -3
  567. langchain/utils/strings.py +1 -1
  568. langchain/utils/utils.py +6 -6
  569. langchain/vectorstores/__init__.py +5 -5
  570. langchain/vectorstores/alibabacloud_opensearch.py +1 -1
  571. langchain/vectorstores/azure_cosmos_db.py +1 -1
  572. langchain/vectorstores/clickhouse.py +1 -1
  573. langchain/vectorstores/elastic_vector_search.py +1 -1
  574. langchain/vectorstores/elasticsearch.py +2 -2
  575. langchain/vectorstores/myscale.py +1 -1
  576. langchain/vectorstores/neo4j_vector.py +1 -1
  577. langchain/vectorstores/pgembedding.py +1 -1
  578. langchain/vectorstores/qdrant.py +1 -1
  579. langchain/vectorstores/redis/__init__.py +1 -1
  580. langchain/vectorstores/redis/base.py +1 -1
  581. langchain/vectorstores/redis/filters.py +4 -4
  582. langchain/vectorstores/redis/schema.py +6 -6
  583. langchain/vectorstores/sklearn.py +2 -2
  584. langchain/vectorstores/starrocks.py +1 -1
  585. langchain/vectorstores/utils.py +1 -1
  586. {langchain-0.3.26.dist-info → langchain-0.4.0.dev0.dist-info}/METADATA +4 -14
  587. {langchain-0.3.26.dist-info → langchain-0.4.0.dev0.dist-info}/RECORD +590 -591
  588. {langchain-0.3.26.dist-info → langchain-0.4.0.dev0.dist-info}/WHEEL +1 -1
  589. langchain/smith/evaluation/utils.py +0 -0
  590. {langchain-0.3.26.dist-info → langchain-0.4.0.dev0.dist-info}/entry_points.txt +0 -0
  591. {langchain-0.3.26.dist-info → langchain-0.4.0.dev0.dist-info}/licenses/LICENSE +0 -0
@@ -3,7 +3,6 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import inspect
6
- import warnings
7
6
  from abc import abstractmethod
8
7
  from typing import Any, Optional
9
8
 
@@ -19,6 +18,7 @@ from langchain_core.prompts import PromptTemplate
19
18
  from langchain_core.retrievers import BaseRetriever
20
19
  from langchain_core.vectorstores import VectorStore
21
20
  from pydantic import ConfigDict, Field, model_validator
21
+ from typing_extensions import override
22
22
 
23
23
  from langchain.chains.base import Chain
24
24
  from langchain.chains.combine_documents.base import BaseCombineDocumentsChain
@@ -69,7 +69,7 @@ class BaseRetrievalQA(Chain):
69
69
  """
70
70
  _output_keys = [self.output_key]
71
71
  if self.return_source_documents:
72
- _output_keys = _output_keys + ["source_documents"]
72
+ _output_keys = [*_output_keys, "source_documents"]
73
73
  return _output_keys
74
74
 
75
75
  @classmethod
@@ -84,10 +84,14 @@ class BaseRetrievalQA(Chain):
84
84
  """Initialize from LLM."""
85
85
  _prompt = prompt or PROMPT_SELECTOR.get_prompt(llm)
86
86
  llm_chain = LLMChain(
87
- llm=llm, prompt=_prompt, callbacks=callbacks, **(llm_chain_kwargs or {})
87
+ llm=llm,
88
+ prompt=_prompt,
89
+ callbacks=callbacks,
90
+ **(llm_chain_kwargs or {}),
88
91
  )
89
92
  document_prompt = PromptTemplate(
90
- input_variables=["page_content"], template="Context:\n{page_content}"
93
+ input_variables=["page_content"],
94
+ template="Context:\n{page_content}",
91
95
  )
92
96
  combine_documents_chain = StuffDocumentsChain(
93
97
  llm_chain=llm_chain,
@@ -113,7 +117,9 @@ class BaseRetrievalQA(Chain):
113
117
  """Load chain from chain type."""
114
118
  _chain_type_kwargs = chain_type_kwargs or {}
115
119
  combine_documents_chain = load_qa_chain(
116
- llm, chain_type=chain_type, **_chain_type_kwargs
120
+ llm,
121
+ chain_type=chain_type,
122
+ **_chain_type_kwargs,
117
123
  )
118
124
  return cls(combine_documents_chain=combine_documents_chain, **kwargs)
119
125
 
@@ -141,6 +147,7 @@ class BaseRetrievalQA(Chain):
141
147
 
142
148
  res = indexqa({'query': 'This is my query'})
143
149
  answer, docs = res['result'], res['source_documents']
150
+
144
151
  """
145
152
  _run_manager = run_manager or CallbackManagerForChainRun.get_noop_manager()
146
153
  question = inputs[self.input_key]
@@ -152,13 +159,14 @@ class BaseRetrievalQA(Chain):
152
159
  else:
153
160
  docs = self._get_docs(question) # type: ignore[call-arg]
154
161
  answer = self.combine_documents_chain.run(
155
- input_documents=docs, question=question, callbacks=_run_manager.get_child()
162
+ input_documents=docs,
163
+ question=question,
164
+ callbacks=_run_manager.get_child(),
156
165
  )
157
166
 
158
167
  if self.return_source_documents:
159
168
  return {self.output_key: answer, "source_documents": docs}
160
- else:
161
- return {self.output_key: answer}
169
+ return {self.output_key: answer}
162
170
 
163
171
  @abstractmethod
164
172
  async def _aget_docs(
@@ -184,6 +192,7 @@ class BaseRetrievalQA(Chain):
184
192
 
185
193
  res = indexqa({'query': 'This is my query'})
186
194
  answer, docs = res['result'], res['source_documents']
195
+
187
196
  """
188
197
  _run_manager = run_manager or AsyncCallbackManagerForChainRun.get_noop_manager()
189
198
  question = inputs[self.input_key]
@@ -195,13 +204,14 @@ class BaseRetrievalQA(Chain):
195
204
  else:
196
205
  docs = await self._aget_docs(question) # type: ignore[call-arg]
197
206
  answer = await self.combine_documents_chain.arun(
198
- input_documents=docs, question=question, callbacks=_run_manager.get_child()
207
+ input_documents=docs,
208
+ question=question,
209
+ callbacks=_run_manager.get_child(),
199
210
  )
200
211
 
201
212
  if self.return_source_documents:
202
213
  return {self.output_key: answer, "source_documents": docs}
203
- else:
204
- return {self.output_key: answer}
214
+ return {self.output_key: answer}
205
215
 
206
216
 
207
217
  @deprecated(
@@ -269,7 +279,8 @@ class RetrievalQA(BaseRetrievalQA):
269
279
  ) -> list[Document]:
270
280
  """Get docs."""
271
281
  return self.retriever.invoke(
272
- question, config={"callbacks": run_manager.get_child()}
282
+ question,
283
+ config={"callbacks": run_manager.get_child()},
273
284
  )
274
285
 
275
286
  async def _aget_docs(
@@ -280,7 +291,8 @@ class RetrievalQA(BaseRetrievalQA):
280
291
  ) -> list[Document]:
281
292
  """Get docs."""
282
293
  return await self.retriever.ainvoke(
283
- question, config={"callbacks": run_manager.get_child()}
294
+ question,
295
+ config={"callbacks": run_manager.get_child()},
284
296
  )
285
297
 
286
298
  @property
@@ -310,15 +322,6 @@ class VectorDBQA(BaseRetrievalQA):
310
322
  search_kwargs: dict[str, Any] = Field(default_factory=dict)
311
323
  """Extra search args."""
312
324
 
313
- @model_validator(mode="before")
314
- @classmethod
315
- def raise_deprecation(cls, values: dict) -> Any:
316
- warnings.warn(
317
- "`VectorDBQA` is deprecated - "
318
- "please use `from langchain.chains import RetrievalQA`"
319
- )
320
- return values
321
-
322
325
  @model_validator(mode="before")
323
326
  @classmethod
324
327
  def validate_search_type(cls, values: dict) -> Any:
@@ -326,9 +329,11 @@ class VectorDBQA(BaseRetrievalQA):
326
329
  if "search_type" in values:
327
330
  search_type = values["search_type"]
328
331
  if search_type not in ("similarity", "mmr"):
329
- raise ValueError(f"search_type of {search_type} not allowed.")
332
+ msg = f"search_type of {search_type} not allowed."
333
+ raise ValueError(msg)
330
334
  return values
331
335
 
336
+ @override
332
337
  def _get_docs(
333
338
  self,
334
339
  question: str,
@@ -338,14 +343,19 @@ class VectorDBQA(BaseRetrievalQA):
338
343
  """Get docs."""
339
344
  if self.search_type == "similarity":
340
345
  docs = self.vectorstore.similarity_search(
341
- question, k=self.k, **self.search_kwargs
346
+ question,
347
+ k=self.k,
348
+ **self.search_kwargs,
342
349
  )
343
350
  elif self.search_type == "mmr":
344
351
  docs = self.vectorstore.max_marginal_relevance_search(
345
- question, k=self.k, **self.search_kwargs
352
+ question,
353
+ k=self.k,
354
+ **self.search_kwargs,
346
355
  )
347
356
  else:
348
- raise ValueError(f"search_type of {self.search_type} not allowed.")
357
+ msg = f"search_type of {self.search_type} not allowed."
358
+ raise ValueError(msg)
349
359
  return docs
350
360
 
351
361
  async def _aget_docs(
@@ -355,7 +365,8 @@ class VectorDBQA(BaseRetrievalQA):
355
365
  run_manager: AsyncCallbackManagerForChainRun,
356
366
  ) -> list[Document]:
357
367
  """Get docs."""
358
- raise NotImplementedError("VectorDBQA does not support async")
368
+ msg = "VectorDBQA does not support async"
369
+ raise NotImplementedError(msg)
359
370
 
360
371
  @property
361
372
  def _chain_type(self) -> str:
@@ -1,4 +1,3 @@
1
- # flake8: noqa
2
1
  from langchain_core.prompts import PromptTemplate
3
2
 
4
3
  prompt_template = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.
@@ -6,7 +5,7 @@ prompt_template = """Use the following pieces of context to answer the question
6
5
  {context}
7
6
 
8
7
  Question: {question}
9
- Helpful Answer:"""
8
+ Helpful Answer:""" # noqa: E501
10
9
  PROMPT = PromptTemplate(
11
10
  template=prompt_template, input_variables=["context", "question"]
12
11
  )
@@ -4,9 +4,9 @@ from langchain.chains.router.multi_prompt import MultiPromptChain
4
4
  from langchain.chains.router.multi_retrieval_qa import MultiRetrievalQAChain
5
5
 
6
6
  __all__ = [
7
- "RouterChain",
8
- "MultiRouteChain",
7
+ "LLMRouterChain",
9
8
  "MultiPromptChain",
10
9
  "MultiRetrievalQAChain",
11
- "LLMRouterChain",
10
+ "MultiRouteChain",
11
+ "RouterChain",
12
12
  ]
@@ -12,11 +12,14 @@ from langchain_core.callbacks import (
12
12
  Callbacks,
13
13
  )
14
14
  from pydantic import ConfigDict
15
+ from typing_extensions import override
15
16
 
16
17
  from langchain.chains.base import Chain
17
18
 
18
19
 
19
20
  class Route(NamedTuple):
21
+ """A route to a destination chain."""
22
+
20
23
  destination: Optional[str]
21
24
  next_inputs: dict[str, Any]
22
25
 
@@ -25,12 +28,12 @@ class RouterChain(Chain, ABC):
25
28
  """Chain that outputs the name of a destination chain and the inputs to it."""
26
29
 
27
30
  @property
31
+ @override
28
32
  def output_keys(self) -> list[str]:
29
33
  return ["destination", "next_inputs"]
30
34
 
31
35
  def route(self, inputs: dict[str, Any], callbacks: Callbacks = None) -> Route:
32
- """
33
- Route inputs to a destination chain.
36
+ """Route inputs to a destination chain.
34
37
 
35
38
  Args:
36
39
  inputs: inputs to the chain
@@ -43,8 +46,19 @@ class RouterChain(Chain, ABC):
43
46
  return Route(result["destination"], result["next_inputs"])
44
47
 
45
48
  async def aroute(
46
- self, inputs: dict[str, Any], callbacks: Callbacks = None
49
+ self,
50
+ inputs: dict[str, Any],
51
+ callbacks: Callbacks = None,
47
52
  ) -> Route:
53
+ """Route inputs to a destination chain.
54
+
55
+ Args:
56
+ inputs: inputs to the chain
57
+ callbacks: callbacks to use for the chain
58
+
59
+ Returns:
60
+ a Route object
61
+ """
48
62
  result = await self.acall(inputs, callbacks=callbacks)
49
63
  return Route(result["destination"], result["next_inputs"])
50
64
 
@@ -59,7 +73,7 @@ class MultiRouteChain(Chain):
59
73
  default_chain: Chain
60
74
  """Default chain to use when none of the destination chains are suitable."""
61
75
  silent_errors: bool = False
62
- """If True, use default_chain when an invalid destination name is provided.
76
+ """If True, use default_chain when an invalid destination name is provided.
63
77
  Defaults to False."""
64
78
 
65
79
  model_config = ConfigDict(
@@ -93,20 +107,20 @@ class MultiRouteChain(Chain):
93
107
  route = self.router_chain.route(inputs, callbacks=callbacks)
94
108
 
95
109
  _run_manager.on_text(
96
- str(route.destination) + ": " + str(route.next_inputs), verbose=self.verbose
110
+ str(route.destination) + ": " + str(route.next_inputs),
111
+ verbose=self.verbose,
97
112
  )
98
113
  if not route.destination:
99
114
  return self.default_chain(route.next_inputs, callbacks=callbacks)
100
- elif route.destination in self.destination_chains:
115
+ if route.destination in self.destination_chains:
101
116
  return self.destination_chains[route.destination](
102
- route.next_inputs, callbacks=callbacks
117
+ route.next_inputs,
118
+ callbacks=callbacks,
103
119
  )
104
- elif self.silent_errors:
120
+ if self.silent_errors:
105
121
  return self.default_chain(route.next_inputs, callbacks=callbacks)
106
- else:
107
- raise ValueError(
108
- f"Received invalid destination chain name '{route.destination}'"
109
- )
122
+ msg = f"Received invalid destination chain name '{route.destination}'"
123
+ raise ValueError(msg)
110
124
 
111
125
  async def _acall(
112
126
  self,
@@ -118,21 +132,23 @@ class MultiRouteChain(Chain):
118
132
  route = await self.router_chain.aroute(inputs, callbacks=callbacks)
119
133
 
120
134
  await _run_manager.on_text(
121
- str(route.destination) + ": " + str(route.next_inputs), verbose=self.verbose
135
+ str(route.destination) + ": " + str(route.next_inputs),
136
+ verbose=self.verbose,
122
137
  )
123
138
  if not route.destination:
124
139
  return await self.default_chain.acall(
125
- route.next_inputs, callbacks=callbacks
140
+ route.next_inputs,
141
+ callbacks=callbacks,
126
142
  )
127
- elif route.destination in self.destination_chains:
143
+ if route.destination in self.destination_chains:
128
144
  return await self.destination_chains[route.destination].acall(
129
- route.next_inputs, callbacks=callbacks
145
+ route.next_inputs,
146
+ callbacks=callbacks,
130
147
  )
131
- elif self.silent_errors:
148
+ if self.silent_errors:
132
149
  return await self.default_chain.acall(
133
- route.next_inputs, callbacks=callbacks
134
- )
135
- else:
136
- raise ValueError(
137
- f"Received invalid destination chain name '{route.destination}'"
150
+ route.next_inputs,
151
+ callbacks=callbacks,
138
152
  )
153
+ msg = f"Received invalid destination chain name '{route.destination}'"
154
+ raise ValueError(msg)
@@ -11,6 +11,7 @@ from langchain_core.documents import Document
11
11
  from langchain_core.embeddings import Embeddings
12
12
  from langchain_core.vectorstores import VectorStore
13
13
  from pydantic import ConfigDict
14
+ from typing_extensions import override
14
15
 
15
16
  from langchain.chains.router.base import RouterChain
16
17
 
@@ -34,6 +35,7 @@ class EmbeddingRouterChain(RouterChain):
34
35
  """
35
36
  return self.routing_keys
36
37
 
38
+ @override
37
39
  def _call(
38
40
  self,
39
41
  inputs: dict[str, Any],
@@ -43,6 +45,7 @@ class EmbeddingRouterChain(RouterChain):
43
45
  results = self.vectorstore.similarity_search(_input, k=1)
44
46
  return {"next_inputs": inputs, "destination": results[0].metadata["name"]}
45
47
 
48
+ @override
46
49
  async def _acall(
47
50
  self,
48
51
  inputs: dict[str, Any],
@@ -63,10 +66,12 @@ class EmbeddingRouterChain(RouterChain):
63
66
  """Convenience constructor."""
64
67
  documents = []
65
68
  for name, descriptions in names_and_descriptions:
66
- for description in descriptions:
67
- documents.append(
69
+ documents.extend(
70
+ [
68
71
  Document(page_content=description, metadata={"name": name})
69
- )
72
+ for description in descriptions
73
+ ]
74
+ )
70
75
  vectorstore = vectorstore_cls.from_documents(documents, embeddings)
71
76
  return cls(vectorstore=vectorstore, **kwargs)
72
77
 
@@ -80,10 +85,12 @@ class EmbeddingRouterChain(RouterChain):
80
85
  ) -> EmbeddingRouterChain:
81
86
  """Convenience constructor."""
82
87
  documents = []
83
- for name, descriptions in names_and_descriptions:
84
- for description in descriptions:
85
- documents.append(
86
- Document(page_content=description, metadata={"name": name})
87
- )
88
+ documents.extend(
89
+ [
90
+ Document(page_content=description, metadata={"name": name})
91
+ for name, descriptions in names_and_descriptions
92
+ for description in descriptions
93
+ ]
94
+ )
88
95
  vectorstore = await vectorstore_cls.afrom_documents(documents, embeddings)
89
96
  return cls(vectorstore=vectorstore, **kwargs)
@@ -15,7 +15,7 @@ from langchain_core.output_parsers import BaseOutputParser
15
15
  from langchain_core.prompts import BasePromptTemplate
16
16
  from langchain_core.utils.json import parse_and_check_json_markdown
17
17
  from pydantic import model_validator
18
- from typing_extensions import Self
18
+ from typing_extensions import Self, override
19
19
 
20
20
  from langchain.chains import LLMChain
21
21
  from langchain.chains.router.base import RouterChain
@@ -27,7 +27,7 @@ from langchain.chains.router.base import RouterChain
27
27
  message=(
28
28
  "Use RunnableLambda to select from multiple prompt templates. See example "
29
29
  "in API reference: "
30
- "https://api.python.langchain.com/en/latest/chains/langchain.chains.router.llm_router.LLMRouterChain.html" # noqa: E501
30
+ "https://api.python.langchain.com/en/latest/chains/langchain.chains.router.llm_router.LLMRouterChain.html"
31
31
  ),
32
32
  )
33
33
  class LLMRouterChain(RouterChain):
@@ -96,21 +96,23 @@ class LLMRouterChain(RouterChain):
96
96
  )
97
97
 
98
98
  chain.invoke({"query": "what color are carrots"})
99
+
99
100
  """ # noqa: E501
100
101
 
101
102
  llm_chain: LLMChain
102
103
  """LLM chain used to perform routing"""
103
104
 
104
105
  @model_validator(mode="after")
105
- def validate_prompt(self) -> Self:
106
+ def _validate_prompt(self) -> Self:
106
107
  prompt = self.llm_chain.prompt
107
108
  if prompt.output_parser is None:
108
- raise ValueError(
109
+ msg = (
109
110
  "LLMRouterChain requires base llm_chain prompt to have an output"
110
111
  " parser that converts LLM text output to a dictionary with keys"
111
112
  " 'destination' and 'next_inputs'. Received a prompt with no output"
112
113
  " parser."
113
114
  )
115
+ raise ValueError(msg)
114
116
  return self
115
117
 
116
118
  @property
@@ -124,7 +126,7 @@ class LLMRouterChain(RouterChain):
124
126
  def _validate_outputs(self, outputs: dict[str, Any]) -> None:
125
127
  super()._validate_outputs(outputs)
126
128
  if not isinstance(outputs["next_inputs"], dict):
127
- raise ValueError
129
+ raise ValueError # noqa: TRY004
128
130
 
129
131
  def _call(
130
132
  self,
@@ -135,11 +137,10 @@ class LLMRouterChain(RouterChain):
135
137
  callbacks = _run_manager.get_child()
136
138
 
137
139
  prediction = self.llm_chain.predict(callbacks=callbacks, **inputs)
138
- output = cast(
139
- dict[str, Any],
140
+ return cast(
141
+ "dict[str, Any]",
140
142
  self.llm_chain.prompt.output_parser.parse(prediction),
141
143
  )
142
- return output
143
144
 
144
145
  async def _acall(
145
146
  self,
@@ -148,15 +149,17 @@ class LLMRouterChain(RouterChain):
148
149
  ) -> dict[str, Any]:
149
150
  _run_manager = run_manager or CallbackManagerForChainRun.get_noop_manager()
150
151
  callbacks = _run_manager.get_child()
151
- output = cast(
152
- dict[str, Any],
152
+ return cast(
153
+ "dict[str, Any]",
153
154
  await self.llm_chain.apredict_and_parse(callbacks=callbacks, **inputs),
154
155
  )
155
- return output
156
156
 
157
157
  @classmethod
158
158
  def from_llm(
159
- cls, llm: BaseLanguageModel, prompt: BasePromptTemplate, **kwargs: Any
159
+ cls,
160
+ llm: BaseLanguageModel,
161
+ prompt: BasePromptTemplate,
162
+ **kwargs: Any,
160
163
  ) -> LLMRouterChain:
161
164
  """Convenience constructor."""
162
165
  llm_chain = LLMChain(llm=llm, prompt=prompt)
@@ -170,16 +173,17 @@ class RouterOutputParser(BaseOutputParser[dict[str, str]]):
170
173
  next_inputs_type: type = str
171
174
  next_inputs_inner_key: str = "input"
172
175
 
176
+ @override
173
177
  def parse(self, text: str) -> dict[str, Any]:
174
178
  try:
175
179
  expected_keys = ["destination", "next_inputs"]
176
180
  parsed = parse_and_check_json_markdown(text, expected_keys)
177
181
  if not isinstance(parsed["destination"], str):
178
- raise ValueError("Expected 'destination' to be a string.")
182
+ msg = "Expected 'destination' to be a string."
183
+ raise TypeError(msg)
179
184
  if not isinstance(parsed["next_inputs"], self.next_inputs_type):
180
- raise ValueError(
181
- f"Expected 'next_inputs' to be {self.next_inputs_type}."
182
- )
185
+ msg = f"Expected 'next_inputs' to be {self.next_inputs_type}."
186
+ raise TypeError(msg)
183
187
  parsed["next_inputs"] = {self.next_inputs_inner_key: parsed["next_inputs"]}
184
188
  if (
185
189
  parsed["destination"].strip().lower()
@@ -188,8 +192,7 @@ class RouterOutputParser(BaseOutputParser[dict[str, str]]):
188
192
  parsed["destination"] = None
189
193
  else:
190
194
  parsed["destination"] = parsed["destination"].strip()
191
- return parsed
192
195
  except Exception as e:
193
- raise OutputParserException(
194
- f"Parsing text\n{text}\n raised following error:\n{e}"
195
- )
196
+ msg = f"Parsing text\n{text}\n raised following error:\n{e}"
197
+ raise OutputParserException(msg) from e
198
+ return parsed
@@ -7,6 +7,7 @@ from typing import Any, Optional
7
7
  from langchain_core._api import deprecated
8
8
  from langchain_core.language_models import BaseLanguageModel
9
9
  from langchain_core.prompts import PromptTemplate
10
+ from typing_extensions import override
10
11
 
11
12
  from langchain.chains import ConversationChain
12
13
  from langchain.chains.base import Chain
@@ -21,7 +22,7 @@ from langchain.chains.router.multi_prompt_prompt import MULTI_PROMPT_ROUTER_TEMP
21
22
  removal="1.0",
22
23
  message=(
23
24
  "Please see migration guide here for recommended implementation: "
24
- "https://python.langchain.com/docs/versions/migrating_chains/multi_prompt_chain/" # noqa: E501
25
+ "https://python.langchain.com/docs/versions/migrating_chains/multi_prompt_chain/"
25
26
  ),
26
27
  )
27
28
  class MultiPromptChain(MultiRouteChain):
@@ -139,9 +140,11 @@ class MultiPromptChain(MultiRouteChain):
139
140
  result = await app.ainvoke({"query": "what color are carrots"})
140
141
  print(result["destination"])
141
142
  print(result["answer"])
143
+
142
144
  """ # noqa: E501
143
145
 
144
146
  @property
147
+ @override
145
148
  def output_keys(self) -> list[str]:
146
149
  return ["text"]
147
150
 
@@ -157,7 +160,7 @@ class MultiPromptChain(MultiRouteChain):
157
160
  destinations = [f"{p['name']}: {p['description']}" for p in prompt_infos]
158
161
  destinations_str = "\n".join(destinations)
159
162
  router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(
160
- destinations=destinations_str
163
+ destinations=destinations_str,
161
164
  )
162
165
  router_prompt = PromptTemplate(
163
166
  template=router_template,
@@ -8,6 +8,7 @@ from typing import Any, Optional
8
8
  from langchain_core.language_models import BaseLanguageModel
9
9
  from langchain_core.prompts import PromptTemplate
10
10
  from langchain_core.retrievers import BaseRetriever
11
+ from typing_extensions import override
11
12
 
12
13
  from langchain.chains import ConversationChain
13
14
  from langchain.chains.base import Chain
@@ -32,6 +33,7 @@ class MultiRetrievalQAChain(MultiRouteChain):
32
33
  """Default chain to use when router doesn't map input to one of the destinations."""
33
34
 
34
35
  @property
36
+ @override
35
37
  def output_keys(self) -> list[str]:
36
38
  return ["result"]
37
39
 
@@ -47,15 +49,32 @@ class MultiRetrievalQAChain(MultiRouteChain):
47
49
  default_chain_llm: Optional[BaseLanguageModel] = None,
48
50
  **kwargs: Any,
49
51
  ) -> MultiRetrievalQAChain:
52
+ """Create a multi retrieval qa chain from an LLM and a default chain.
53
+
54
+ Args:
55
+ llm: The language model to use.
56
+ retriever_infos: Dictionaries containing retriever information.
57
+ default_retriever: Optional default retriever to use if no default chain
58
+ is provided.
59
+ default_prompt: Optional prompt template to use for the default retriever.
60
+ default_chain: Optional default chain to use when router doesn't map input
61
+ to one of the destinations.
62
+ default_chain_llm: Optional language model to use if no default chain and
63
+ no default retriever are provided.
64
+ **kwargs: Additional keyword arguments to pass to the chain.
65
+ Returns:
66
+ An instance of the multi retrieval qa chain.
67
+ """
50
68
  if default_prompt and not default_retriever:
51
- raise ValueError(
69
+ msg = (
52
70
  "`default_retriever` must be specified if `default_prompt` is "
53
71
  "provided. Received only `default_prompt`."
54
72
  )
73
+ raise ValueError(msg)
55
74
  destinations = [f"{r['name']}: {r['description']}" for r in retriever_infos]
56
75
  destinations_str = "\n".join(destinations)
57
76
  router_template = MULTI_RETRIEVAL_ROUTER_TEMPLATE.format(
58
- destinations=destinations_str
77
+ destinations=destinations_str,
59
78
  )
60
79
  router_prompt = PromptTemplate(
61
80
  template=router_template,
@@ -74,15 +93,18 @@ class MultiRetrievalQAChain(MultiRouteChain):
74
93
  _default_chain = default_chain
75
94
  elif default_retriever:
76
95
  _default_chain = RetrievalQA.from_llm(
77
- llm, prompt=default_prompt, retriever=default_retriever
96
+ llm,
97
+ prompt=default_prompt,
98
+ retriever=default_retriever,
78
99
  )
79
100
  else:
80
101
  prompt_template = DEFAULT_TEMPLATE.replace("input", "query")
81
102
  prompt = PromptTemplate(
82
- template=prompt_template, input_variables=["history", "query"]
103
+ template=prompt_template,
104
+ input_variables=["history", "query"],
83
105
  )
84
106
  if default_chain_llm is None:
85
- raise NotImplementedError(
107
+ msg = (
86
108
  "conversation_llm must be provided if default_chain is not "
87
109
  "specified. This API has been changed to avoid instantiating "
88
110
  "default LLMs on behalf of users."
@@ -90,6 +112,7 @@ class MultiRetrievalQAChain(MultiRouteChain):
90
112
  "from langchain_openai import ChatOpenAI\n"
91
113
  "llm = ChatOpenAI()"
92
114
  )
115
+ raise NotImplementedError(msg)
93
116
  _default_chain = ConversationChain(
94
117
  llm=default_chain_llm,
95
118
  prompt=prompt,