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
@@ -1,49 +1,123 @@
1
- from typing import Union
1
+ import re
2
+ from typing import Literal, Optional, Union
2
3
 
3
4
  from langchain_core.agents import AgentAction, AgentFinish
5
+ from pydantic import Field
6
+ from typing_extensions import override
4
7
 
5
8
  from langchain.agents import AgentOutputParser
6
9
 
7
10
 
11
+ def _unescape(text: str) -> str:
12
+ """Convert custom tag delimiters back into XML tags."""
13
+ replacements = {
14
+ "[[tool]]": "<tool>",
15
+ "[[/tool]]": "</tool>",
16
+ "[[tool_input]]": "<tool_input>",
17
+ "[[/tool_input]]": "</tool_input>",
18
+ "[[observation]]": "<observation>",
19
+ "[[/observation]]": "</observation>",
20
+ }
21
+ for repl, orig in replacements.items():
22
+ text = text.replace(repl, orig)
23
+ return text
24
+
25
+
8
26
  class XMLAgentOutputParser(AgentOutputParser):
9
- """Parses tool invocations and final answers in XML format.
27
+ """Parses tool invocations and final answers from XML-formatted agent output.
28
+
29
+ This parser extracts structured information from XML tags to determine whether
30
+ an agent should perform a tool action or provide a final answer. It includes
31
+ built-in escaping support to safely handle tool names and inputs
32
+ containing XML special characters.
33
+
34
+ Args:
35
+ escape_format: The escaping format to use when parsing XML content.
36
+ Supports 'minimal' which uses custom delimiters like [[tool]] to replace
37
+ XML tags within content, preventing parsing conflicts.
38
+ Use 'minimal' if using a corresponding encoding format that uses
39
+ the _escape function when formatting the output (e.g., with format_xml).
40
+
41
+ Expected formats:
42
+ Tool invocation (returns AgentAction):
43
+ <tool>search</tool>
44
+ <tool_input>what is 2 + 2</tool_input>
10
45
 
11
- Expects output to be in one of two formats.
46
+ Final answer (returns AgentFinish):
47
+ <final_answer>The answer is 4</final_answer>
12
48
 
13
- If the output signals that an action should be taken,
14
- should be in the below format. This will result in an AgentAction
15
- being returned.
49
+ Note:
50
+ Minimal escaping allows tool names containing XML tags to be safely
51
+ represented. For example, a tool named "search<tool>nested</tool>" would be
52
+ escaped as "search[[tool]]nested[[/tool]]" in the XML and automatically
53
+ unescaped during parsing.
16
54
 
17
- ```
18
- <tool>search</tool>
19
- <tool_input>what is 2 + 2</tool_input>
20
- ```
55
+ Raises:
56
+ ValueError: If the input doesn't match either expected XML format or
57
+ contains malformed XML structure.
58
+ """
59
+
60
+ escape_format: Optional[Literal["minimal"]] = Field(default="minimal")
61
+ """The format to use for escaping XML characters.
21
62
 
22
- If the output signals that a final answer should be given,
23
- should be in the below format. This will result in an AgentFinish
24
- being returned.
63
+ minimal - uses custom delimiters to replace XML tags within content,
64
+ preventing parsing conflicts. This is the only supported format currently.
25
65
 
26
- ```
27
- <final_answer>Foo</final_answer>
28
- ```
66
+ None - no escaping is applied, which may lead to parsing conflicts.
29
67
  """
30
68
 
69
+ @override
31
70
  def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
32
- if "</tool>" in text:
33
- tool, tool_input = text.split("</tool>")
34
- _tool = tool.split("<tool>")[1]
35
- _tool_input = tool_input.split("<tool_input>")[1]
36
- if "</tool_input>" in _tool_input:
37
- _tool_input = _tool_input.split("</tool_input>")[0]
71
+ # Check for tool invocation first
72
+ tool_matches = re.findall(r"<tool>(.*?)</tool>", text, re.DOTALL)
73
+ if tool_matches:
74
+ if len(tool_matches) != 1:
75
+ msg = (
76
+ f"Malformed tool invocation: expected exactly one <tool> block, "
77
+ f"but found {len(tool_matches)}."
78
+ )
79
+ raise ValueError(msg)
80
+ _tool = tool_matches[0]
81
+
82
+ # Match optional tool input
83
+ input_matches = re.findall(
84
+ r"<tool_input>(.*?)</tool_input>", text, re.DOTALL
85
+ )
86
+ if len(input_matches) > 1:
87
+ msg = (
88
+ f"Malformed tool invocation: expected at most one <tool_input> "
89
+ f"block, but found {len(input_matches)}."
90
+ )
91
+ raise ValueError(msg)
92
+ _tool_input = input_matches[0] if input_matches else ""
93
+
94
+ # Unescape if minimal escape format is used
95
+ if self.escape_format == "minimal":
96
+ _tool = _unescape(_tool)
97
+ _tool_input = _unescape(_tool_input)
98
+
38
99
  return AgentAction(tool=_tool, tool_input=_tool_input, log=text)
39
- elif "<final_answer>" in text:
40
- _, answer = text.split("<final_answer>")
41
- if "</final_answer>" in answer:
42
- answer = answer.split("</final_answer>")[0]
100
+ # Check for final answer
101
+ if "<final_answer>" in text and "</final_answer>" in text:
102
+ matches = re.findall(r"<final_answer>(.*?)</final_answer>", text, re.DOTALL)
103
+ if len(matches) != 1:
104
+ msg = (
105
+ "Malformed output: expected exactly one "
106
+ "<final_answer>...</final_answer> block."
107
+ )
108
+ raise ValueError(msg)
109
+ answer = matches[0]
110
+ # Unescape custom delimiters in final answer
111
+ if self.escape_format == "minimal":
112
+ answer = _unescape(answer)
43
113
  return AgentFinish(return_values={"output": answer}, log=text)
44
- else:
45
- raise ValueError
114
+ msg = (
115
+ "Malformed output: expected either a tool invocation "
116
+ "or a final answer in XML format."
117
+ )
118
+ raise ValueError(msg)
46
119
 
120
+ @override
47
121
  def get_format_instructions(self) -> str:
48
122
  raise NotImplementedError
49
123
 
@@ -116,12 +116,14 @@ def create_react_agent(
116
116
  Thought:{agent_scratchpad}'''
117
117
 
118
118
  prompt = PromptTemplate.from_template(template)
119
+
119
120
  """ # noqa: E501
120
121
  missing_vars = {"tools", "tool_names", "agent_scratchpad"}.difference(
121
- prompt.input_variables + list(prompt.partial_variables)
122
+ prompt.input_variables + list(prompt.partial_variables),
122
123
  )
123
124
  if missing_vars:
124
- raise ValueError(f"Prompt missing required variables: {missing_vars}")
125
+ msg = f"Prompt missing required variables: {missing_vars}"
126
+ raise ValueError(msg)
125
127
 
126
128
  prompt = prompt.partial(
127
129
  tools=tools_renderer(list(tools)),
@@ -133,7 +135,7 @@ def create_react_agent(
133
135
  else:
134
136
  llm_with_stop = llm
135
137
  output_parser = output_parser or ReActSingleInputOutputParser()
136
- agent = (
138
+ return (
137
139
  RunnablePassthrough.assign(
138
140
  agent_scratchpad=lambda x: format_log_to_str(x["intermediate_steps"]),
139
141
  )
@@ -141,4 +143,3 @@ def create_react_agent(
141
143
  | llm_with_stop
142
144
  | output_parser
143
145
  )
144
- return agent
@@ -11,6 +11,7 @@ from langchain_core.language_models import BaseLanguageModel
11
11
  from langchain_core.prompts import BasePromptTemplate
12
12
  from langchain_core.tools import BaseTool, Tool
13
13
  from pydantic import Field
14
+ from typing_extensions import override
14
15
 
15
16
  from langchain._api.deprecation import AGENT_DEPRECATION_WARNING
16
17
  from langchain.agents.agent import Agent, AgentExecutor, AgentOutputParser
@@ -24,6 +25,9 @@ if TYPE_CHECKING:
24
25
  from langchain_community.docstore.base import Docstore
25
26
 
26
27
 
28
+ _LOOKUP_AND_SEARCH_TOOLS = {"Lookup", "Search"}
29
+
30
+
27
31
  @deprecated(
28
32
  "0.1.0",
29
33
  message=AGENT_DEPRECATION_WARNING,
@@ -35,6 +39,7 @@ class ReActDocstoreAgent(Agent):
35
39
  output_parser: AgentOutputParser = Field(default_factory=ReActOutputParser)
36
40
 
37
41
  @classmethod
42
+ @override
38
43
  def _get_default_output_parser(cls, **kwargs: Any) -> AgentOutputParser:
39
44
  return ReActOutputParser()
40
45
 
@@ -44,6 +49,7 @@ class ReActDocstoreAgent(Agent):
44
49
  return AgentType.REACT_DOCSTORE
45
50
 
46
51
  @classmethod
52
+ @override
47
53
  def create_prompt(cls, tools: Sequence[BaseTool]) -> BasePromptTemplate:
48
54
  """Return default prompt."""
49
55
  return WIKI_PROMPT
@@ -52,13 +58,13 @@ class ReActDocstoreAgent(Agent):
52
58
  def _validate_tools(cls, tools: Sequence[BaseTool]) -> None:
53
59
  validate_tools_single_input(cls.__name__, tools)
54
60
  super()._validate_tools(tools)
55
- if len(tools) != 2:
56
- raise ValueError(f"Exactly two tools must be specified, but got {tools}")
61
+ if len(tools) != len(_LOOKUP_AND_SEARCH_TOOLS):
62
+ msg = f"Exactly two tools must be specified, but got {tools}"
63
+ raise ValueError(msg)
57
64
  tool_names = {tool.name for tool in tools}
58
- if tool_names != {"Lookup", "Search"}:
59
- raise ValueError(
60
- f"Tool names should be Lookup and Search, got {tool_names}"
61
- )
65
+ if tool_names != _LOOKUP_AND_SEARCH_TOOLS:
66
+ msg = f"Tool names should be Lookup and Search, got {tool_names}"
67
+ raise ValueError(msg)
62
68
 
63
69
  @property
64
70
  def observation_prefix(self) -> str:
@@ -96,14 +102,14 @@ class DocstoreExplorer:
96
102
  if isinstance(result, Document):
97
103
  self.document = result
98
104
  return self._summary
99
- else:
100
- self.document = None
101
- return result
105
+ self.document = None
106
+ return result
102
107
 
103
108
  def lookup(self, term: str) -> str:
104
109
  """Lookup a term in document (if saved)."""
105
110
  if self.document is None:
106
- raise ValueError("Cannot lookup without a successful search first")
111
+ msg = "Cannot lookup without a successful search first"
112
+ raise ValueError(msg)
107
113
  if term.lower() != self.lookup_str:
108
114
  self.lookup_str = term.lower()
109
115
  self.lookup_index = 0
@@ -112,11 +118,10 @@ class DocstoreExplorer:
112
118
  lookups = [p for p in self._paragraphs if self.lookup_str in p.lower()]
113
119
  if len(lookups) == 0:
114
120
  return "No Results"
115
- elif self.lookup_index >= len(lookups):
121
+ if self.lookup_index >= len(lookups):
116
122
  return "No More Results"
117
- else:
118
- result_prefix = f"(Result {self.lookup_index + 1}/{len(lookups)})"
119
- return f"{result_prefix} {lookups[self.lookup_index]}"
123
+ result_prefix = f"(Result {self.lookup_index + 1}/{len(lookups)})"
124
+ return f"{result_prefix} {lookups[self.lookup_index]}"
120
125
 
121
126
  @property
122
127
  def _summary(self) -> str:
@@ -125,7 +130,8 @@ class DocstoreExplorer:
125
130
  @property
126
131
  def _paragraphs(self) -> list[str]:
127
132
  if self.document is None:
128
- raise ValueError("Cannot get paragraphs without a document")
133
+ msg = "Cannot get paragraphs without a document"
134
+ raise ValueError(msg)
129
135
  return self.document.page_content.split("\n\n")
130
136
 
131
137
 
@@ -138,6 +144,7 @@ class ReActTextWorldAgent(ReActDocstoreAgent):
138
144
  """Agent for the ReAct TextWorld chain."""
139
145
 
140
146
  @classmethod
147
+ @override
141
148
  def create_prompt(cls, tools: Sequence[BaseTool]) -> BasePromptTemplate:
142
149
  """Return default prompt."""
143
150
  return TEXTWORLD_PROMPT
@@ -147,10 +154,12 @@ class ReActTextWorldAgent(ReActDocstoreAgent):
147
154
  validate_tools_single_input(cls.__name__, tools)
148
155
  super()._validate_tools(tools)
149
156
  if len(tools) != 1:
150
- raise ValueError(f"Exactly one tool must be specified, but got {tools}")
157
+ msg = f"Exactly one tool must be specified, but got {tools}"
158
+ raise ValueError(msg)
151
159
  tool_names = {tool.name for tool in tools}
152
160
  if tool_names != {"Play"}:
153
- raise ValueError(f"Tool name should be Play, got {tool_names}")
161
+ msg = f"Tool name should be Play, got {tool_names}"
162
+ raise ValueError(msg)
154
163
 
155
164
 
156
165
  @deprecated(
@@ -3,6 +3,7 @@ from typing import Union
3
3
 
4
4
  from langchain_core.agents import AgentAction, AgentFinish
5
5
  from langchain_core.exceptions import OutputParserException
6
+ from typing_extensions import override
6
7
 
7
8
  from langchain.agents.agent import AgentOutputParser
8
9
 
@@ -10,24 +11,24 @@ from langchain.agents.agent import AgentOutputParser
10
11
  class ReActOutputParser(AgentOutputParser):
11
12
  """Output parser for the ReAct agent."""
12
13
 
14
+ @override
13
15
  def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
14
16
  action_prefix = "Action: "
15
17
  if not text.strip().split("\n")[-1].startswith(action_prefix):
16
- raise OutputParserException(f"Could not parse LLM Output: {text}")
18
+ msg = f"Could not parse LLM Output: {text}"
19
+ raise OutputParserException(msg)
17
20
  action_block = text.strip().split("\n")[-1]
18
21
 
19
22
  action_str = action_block[len(action_prefix) :]
20
23
  # Parse out the action and the directive.
21
24
  re_matches = re.search(r"(.*?)\[(.*?)\]", action_str)
22
25
  if re_matches is None:
23
- raise OutputParserException(
24
- f"Could not parse action directive: {action_str}"
25
- )
26
+ msg = f"Could not parse action directive: {action_str}"
27
+ raise OutputParserException(msg)
26
28
  action, action_input = re_matches.group(1), re_matches.group(2)
27
29
  if action == "Finish":
28
30
  return AgentFinish({"output": action_input}, text)
29
- else:
30
- return AgentAction(action, action_input, text)
31
+ return AgentAction(action, action_input, text)
31
32
 
32
33
  @property
33
34
  def _type(self) -> str:
@@ -1,4 +1,3 @@
1
- # flake8: noqa
2
1
  from langchain_core.prompts.prompt import PromptTemplate
3
2
 
4
3
  EXAMPLES = [
@@ -1,4 +1,3 @@
1
- # flake8: noqa
2
1
  from langchain_core.prompts.prompt import PromptTemplate
3
2
 
4
3
  EXAMPLES = [
@@ -16,7 +15,7 @@ Thought: I need to instead search High Plains (United States).
16
15
  Action: Search[High Plains (United States)]
17
16
  Observation: The High Plains are a subregion of the Great Plains. From east to west, the High Plains rise in elevation from around 1,800 to 7,000 ft (550 to 2,130 m).[3]
18
17
  Thought: High Plains rise in elevation from around 1,800 to 7,000 ft, so the answer is 1,800 to 7,000 ft.
19
- Action: Finish[1,800 to 7,000 ft]""",
18
+ Action: Finish[1,800 to 7,000 ft]""", # noqa: E501
20
19
  """Question: Musician and satirist Allie Goertz wrote a song about the "The Simpsons" character Milhouse, who Matt Groening named after who?
21
20
  Thought: The question simplifies to "The Simpsons" character Milhouse is named after who. I only need to search Milhouse and find who it is named after.
22
21
  Action: Search[Milhouse]
@@ -25,16 +24,16 @@ Thought: The paragraph does not tell who Milhouse is named after, maybe I can lo
25
24
  Action: Lookup[named after]
26
25
  Observation: (Result 1 / 1) Milhouse was named after U.S. president Richard Nixon, whose middle name was Milhous.
27
26
  Thought: Milhouse was named after U.S. president Richard Nixon, so the answer is Richard Nixon.
28
- Action: Finish[Richard Nixon]""",
27
+ Action: Finish[Richard Nixon]""", # noqa: E501
29
28
  """Question: Which documentary is about Finnish rock groups, Adam Clayton Powell or The Saimaa Gesture?
30
29
  Thought: I need to search Adam Clayton Powell and The Saimaa Gesture, and find which documentary is about Finnish rock groups.
31
30
  Action: Search[Adam Clayton Powell]
32
- Observation: Could not find [Adam Clayton Powell]. Similar: [Adam Clayton Powell III’, Seventh Avenue (Manhattan)’, Adam Clayton Powell Jr. State Office Building’, Isabel Washington Powell’, Adam Powell’, Adam Clayton Powell (film)’, Giancarlo Esposito].
31
+ Observation: Could not find [Adam Clayton Powell]. Similar: ['Adam Clayton Powell III', 'Seventh Avenue (Manhattan)', 'Adam Clayton Powell Jr. State Office Building', 'Isabel Washington Powell', 'Adam Powell', 'Adam Clayton Powell (film)', 'Giancarlo Esposito'].
33
32
  Thought: To find the documentary, I can search Adam Clayton Powell (film).
34
33
  Action: Search[Adam Clayton Powell (film)]
35
34
  Observation: Adam Clayton Powell is a 1989 American documentary film directed by Richard Kilberg. The film is about the rise and fall of influential African-American politician Adam Clayton Powell Jr.[3][4] It was later aired as part of the PBS series The American Experience.
36
35
  Thought: Adam Clayton Powell (film) is a documentary about an African-American politician, not Finnish rock groups. So the documentary about Finnish rock groups must instead be The Saimaa Gesture.
37
- Action: Finish[The Saimaa Gesture]""",
36
+ Action: Finish[The Saimaa Gesture]""", # noqa: E501
38
37
  """Question: What profession does Nicholas Ray and Elia Kazan have in common?
39
38
  Thought: I need to search Nicholas Ray and Elia Kazan, find their professions, then find the profession they have in common.
40
39
  Action: Search[Nicholas Ray]
@@ -43,16 +42,16 @@ Thought: Professions of Nicholas Ray are director, screenwriter, and actor. I ne
43
42
  Action: Search[Elia Kazan]
44
43
  Observation: Elia Kazan was an American film and theatre director, producer, screenwriter and actor.
45
44
  Thought: Professions of Elia Kazan are director, producer, screenwriter, and actor. So profession Nicholas Ray and Elia Kazan have in common is director, screenwriter, and actor.
46
- Action: Finish[director, screenwriter, actor]""",
47
- """Question: Which magazine was started first Arthurs Magazine or First for Women?
48
- Thought: I need to search Arthurs Magazine and First for Women, and find which was started first.
49
- Action: Search[Arthurs Magazine]
50
- Observation: Arthurs Magazine (1844-1846) was an American literary periodical published in Philadelphia in the 19th century.
51
- Thought: Arthurs Magazine was started in 1844. I need to search First for Women next.
45
+ Action: Finish[director, screenwriter, actor]""", # noqa: E501
46
+ """Question: Which magazine was started first Arthur's Magazine or First for Women?
47
+ Thought: I need to search Arthur's Magazine and First for Women, and find which was started first.
48
+ Action: Search[Arthur's Magazine]
49
+ Observation: Arthur's Magazine (1844-1846) was an American literary periodical published in Philadelphia in the 19th century.
50
+ Thought: Arthur's Magazine was started in 1844. I need to search First for Women next.
52
51
  Action: Search[First for Women]
53
- Observation: First for Women is a womans magazine published by Bauer Media Group in the USA.[1] The magazine was started in 1989.
54
- Thought: First for Women was started in 1989. 1844 (Arthurs Magazine) < 1989 (First for Women), so Arthurs Magazine was started first.
55
- Action: Finish[Arthurs Magazine]""",
52
+ Observation: First for Women is a woman's magazine published by Bauer Media Group in the USA.[1] The magazine was started in 1989.
53
+ Thought: First for Women was started in 1989. 1844 (Arthur's Magazine) < 1989 (First for Women), so Arthur's Magazine was started first.
54
+ Action: Finish[Arthur's Magazine]""", # noqa: E501
56
55
  """Question: Were Pavel Urysohn and Leonid Levin known for the same type of work?
57
56
  Thought: I need to search Pavel Urysohn and Leonid Levin, find their types of work, then find if they are the same.
58
57
  Action: Search[Pavel Urysohn]
@@ -61,7 +60,7 @@ Thought: Pavel Urysohn is a mathematician. I need to search Leonid Levin next an
61
60
  Action: Search[Leonid Levin]
62
61
  Observation: Leonid Anatolievich Levin is a Soviet-American mathematician and computer scientist.
63
62
  Thought: Leonid Levin is a mathematician and computer scientist. So Pavel Urysohn and Leonid Levin have the same type of work.
64
- Action: Finish[yes]""",
63
+ Action: Finish[yes]""", # noqa: E501
65
64
  ]
66
65
  SUFFIX = """\nQuestion: {input}
67
66
  {agent_scratchpad}"""
@@ -2,17 +2,20 @@ from typing import Any
2
2
 
3
3
  from langchain_core.agents import AgentAction
4
4
  from langchain_core.prompts.chat import ChatPromptTemplate
5
+ from typing_extensions import override
5
6
 
6
7
 
7
8
  class AgentScratchPadChatPromptTemplate(ChatPromptTemplate):
8
9
  """Chat prompt template for the agent scratchpad."""
9
10
 
10
11
  @classmethod
12
+ @override
11
13
  def is_lc_serializable(cls) -> bool:
12
14
  return False
13
15
 
14
16
  def _construct_agent_scratchpad(
15
- self, intermediate_steps: list[tuple[AgentAction, str]]
17
+ self,
18
+ intermediate_steps: list[tuple[AgentAction, str]],
16
19
  ) -> str:
17
20
  if len(intermediate_steps) == 0:
18
21
  return ""
@@ -29,6 +32,6 @@ class AgentScratchPadChatPromptTemplate(ChatPromptTemplate):
29
32
  def _merge_partial_and_user_variables(self, **kwargs: Any) -> dict[str, Any]:
30
33
  intermediate_steps = kwargs.pop("intermediate_steps")
31
34
  kwargs["agent_scratchpad"] = self._construct_agent_scratchpad(
32
- intermediate_steps
35
+ intermediate_steps,
33
36
  )
34
37
  return kwargs
@@ -11,6 +11,7 @@ from langchain_core.prompts import BasePromptTemplate
11
11
  from langchain_core.runnables import Runnable, RunnablePassthrough
12
12
  from langchain_core.tools import BaseTool, Tool
13
13
  from pydantic import Field
14
+ from typing_extensions import override
14
15
 
15
16
  from langchain.agents.agent import Agent, AgentExecutor, AgentOutputParser
16
17
  from langchain.agents.agent_types import AgentType
@@ -32,6 +33,7 @@ class SelfAskWithSearchAgent(Agent):
32
33
  output_parser: AgentOutputParser = Field(default_factory=SelfAskOutputParser)
33
34
 
34
35
  @classmethod
36
+ @override
35
37
  def _get_default_output_parser(cls, **kwargs: Any) -> AgentOutputParser:
36
38
  return SelfAskOutputParser()
37
39
 
@@ -41,6 +43,7 @@ class SelfAskWithSearchAgent(Agent):
41
43
  return AgentType.SELF_ASK_WITH_SEARCH
42
44
 
43
45
  @classmethod
46
+ @override
44
47
  def create_prompt(cls, tools: Sequence[BaseTool]) -> BasePromptTemplate:
45
48
  """Prompt does not depend on tools."""
46
49
  return PROMPT
@@ -50,12 +53,12 @@ class SelfAskWithSearchAgent(Agent):
50
53
  validate_tools_single_input(cls.__name__, tools)
51
54
  super()._validate_tools(tools)
52
55
  if len(tools) != 1:
53
- raise ValueError(f"Exactly one tool must be specified, but got {tools}")
56
+ msg = f"Exactly one tool must be specified, but got {tools}"
57
+ raise ValueError(msg)
54
58
  tool_names = {tool.name for tool in tools}
55
59
  if tool_names != {"Intermediate Answer"}:
56
- raise ValueError(
57
- f"Tool name should be Intermediate Answer, got {tool_names}"
58
- )
60
+ msg = f"Tool name should be Intermediate Answer, got {tool_names}"
61
+ raise ValueError(msg)
59
62
 
60
63
  @property
61
64
  def observation_prefix(self) -> str:
@@ -76,7 +79,9 @@ class SelfAskWithSearchChain(AgentExecutor):
76
79
  self,
77
80
  llm: BaseLanguageModel,
78
81
  search_chain: Union[
79
- GoogleSerperAPIWrapper, SearchApiAPIWrapper, SerpAPIWrapper
82
+ GoogleSerperAPIWrapper,
83
+ SearchApiAPIWrapper,
84
+ SerpAPIWrapper,
80
85
  ],
81
86
  **kwargs: Any,
82
87
  ):
@@ -92,7 +97,9 @@ class SelfAskWithSearchChain(AgentExecutor):
92
97
 
93
98
 
94
99
  def create_self_ask_with_search_agent(
95
- llm: BaseLanguageModel, tools: Sequence[BaseTool], prompt: BasePromptTemplate
100
+ llm: BaseLanguageModel,
101
+ tools: Sequence[BaseTool],
102
+ prompt: BasePromptTemplate,
96
103
  ) -> Runnable:
97
104
  """Create an agent that uses self-ask with search prompting.
98
105
 
@@ -178,23 +185,25 @@ def create_self_ask_with_search_agent(
178
185
  Are followup questions needed here:{agent_scratchpad}'''
179
186
 
180
187
  prompt = PromptTemplate.from_template(template)
188
+
181
189
  """ # noqa: E501
182
190
  missing_vars = {"agent_scratchpad"}.difference(
183
- prompt.input_variables + list(prompt.partial_variables)
191
+ prompt.input_variables + list(prompt.partial_variables),
184
192
  )
185
193
  if missing_vars:
186
- raise ValueError(f"Prompt missing required variables: {missing_vars}")
194
+ msg = f"Prompt missing required variables: {missing_vars}"
195
+ raise ValueError(msg)
187
196
 
188
197
  if len(tools) != 1:
189
- raise ValueError("This agent expects exactly one tool")
190
- tool = list(tools)[0]
198
+ msg = "This agent expects exactly one tool"
199
+ raise ValueError(msg)
200
+ tool = next(iter(tools))
191
201
  if tool.name != "Intermediate Answer":
192
- raise ValueError(
193
- "This agent expects the tool to be named `Intermediate Answer`"
194
- )
202
+ msg = "This agent expects the tool to be named `Intermediate Answer`"
203
+ raise ValueError(msg)
195
204
 
196
205
  llm_with_stop = llm.bind(stop=["\nIntermediate answer:"])
197
- agent = (
206
+ return (
198
207
  RunnablePassthrough.assign(
199
208
  agent_scratchpad=lambda x: format_log_to_str(
200
209
  x["intermediate_steps"],
@@ -208,4 +217,3 @@ def create_self_ask_with_search_agent(
208
217
  | llm_with_stop
209
218
  | SelfAskOutputParser()
210
219
  )
211
- return agent
@@ -1,4 +1,3 @@
1
- # flake8: noqa
2
1
  from langchain_core.prompts.prompt import PromptTemplate
3
2
 
4
3
  _DEFAULT_TEMPLATE = """Question: Who lived longer, Muhammad Ali or Alan Turing?
@@ -16,6 +16,7 @@ from langchain_core.runnables import Runnable, RunnablePassthrough
16
16
  from langchain_core.tools import BaseTool
17
17
  from langchain_core.tools.render import ToolsRenderer
18
18
  from pydantic import Field
19
+ from typing_extensions import override
19
20
 
20
21
  from langchain.agents.agent import Agent, AgentOutputParser
21
22
  from langchain.agents.format_scratchpad import format_log_to_str
@@ -35,7 +36,7 @@ class StructuredChatAgent(Agent):
35
36
  """Structured Chat Agent."""
36
37
 
37
38
  output_parser: AgentOutputParser = Field(
38
- default_factory=StructuredChatOutputParserWithRetries
39
+ default_factory=StructuredChatOutputParserWithRetries,
39
40
  )
40
41
  """Output parser for the agent."""
41
42
 
@@ -50,35 +51,41 @@ class StructuredChatAgent(Agent):
50
51
  return "Thought:"
51
52
 
52
53
  def _construct_scratchpad(
53
- self, intermediate_steps: list[tuple[AgentAction, str]]
54
+ self,
55
+ intermediate_steps: list[tuple[AgentAction, str]],
54
56
  ) -> str:
55
57
  agent_scratchpad = super()._construct_scratchpad(intermediate_steps)
56
58
  if not isinstance(agent_scratchpad, str):
57
- raise ValueError("agent_scratchpad should be of type string.")
59
+ msg = "agent_scratchpad should be of type string."
60
+ raise ValueError(msg) # noqa: TRY004
58
61
  if agent_scratchpad:
59
62
  return (
60
63
  f"This was your previous work "
61
64
  f"(but I haven't seen any of it! I only see what "
62
65
  f"you return as final answer):\n{agent_scratchpad}"
63
66
  )
64
- else:
65
- return agent_scratchpad
67
+ return agent_scratchpad
66
68
 
67
69
  @classmethod
68
70
  def _validate_tools(cls, tools: Sequence[BaseTool]) -> None:
69
71
  pass
70
72
 
71
73
  @classmethod
74
+ @override
72
75
  def _get_default_output_parser(
73
- cls, llm: Optional[BaseLanguageModel] = None, **kwargs: Any
76
+ cls,
77
+ llm: Optional[BaseLanguageModel] = None,
78
+ **kwargs: Any,
74
79
  ) -> AgentOutputParser:
75
80
  return StructuredChatOutputParserWithRetries.from_llm(llm=llm)
76
81
 
77
82
  @property
83
+ @override
78
84
  def _stop(self) -> list[str]:
79
85
  return ["Observation:"]
80
86
 
81
87
  @classmethod
88
+ @override
82
89
  def create_prompt(
83
90
  cls,
84
91
  tools: Sequence[BaseTool],
@@ -96,7 +103,7 @@ class StructuredChatAgent(Agent):
96
103
  formatted_tools = "\n".join(tool_strings)
97
104
  tool_names = ", ".join([tool.name for tool in tools])
98
105
  format_instructions = format_instructions.format(tool_names=tool_names)
99
- template = "\n\n".join([prefix, formatted_tools, format_instructions, suffix])
106
+ template = f"{prefix}\n\n{formatted_tools}\n\n{format_instructions}\n\n{suffix}"
100
107
  if input_variables is None:
101
108
  input_variables = ["input", "agent_scratchpad"]
102
109
  _memory_prompts = memory_prompts or []
@@ -273,12 +280,14 @@ def create_structured_chat_agent(
273
280
  ("human", human),
274
281
  ]
275
282
  )
283
+
276
284
  """ # noqa: E501
277
285
  missing_vars = {"tools", "tool_names", "agent_scratchpad"}.difference(
278
- prompt.input_variables + list(prompt.partial_variables)
286
+ prompt.input_variables + list(prompt.partial_variables),
279
287
  )
280
288
  if missing_vars:
281
- raise ValueError(f"Prompt missing required variables: {missing_vars}")
289
+ msg = f"Prompt missing required variables: {missing_vars}"
290
+ raise ValueError(msg)
282
291
 
283
292
  prompt = prompt.partial(
284
293
  tools=tools_renderer(list(tools)),
@@ -290,7 +299,7 @@ def create_structured_chat_agent(
290
299
  else:
291
300
  llm_with_stop = llm
292
301
 
293
- agent = (
302
+ return (
294
303
  RunnablePassthrough.assign(
295
304
  agent_scratchpad=lambda x: format_log_to_str(x["intermediate_steps"]),
296
305
  )
@@ -298,4 +307,3 @@ def create_structured_chat_agent(
298
307
  | llm_with_stop
299
308
  | JSONAgentOutputParser()
300
309
  )
301
- return agent