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
@@ -38,26 +38,29 @@ _FunctionsAgentAction = AgentActionMessageLog
38
38
  def _parse_ai_message(message: BaseMessage) -> Union[list[AgentAction], AgentFinish]:
39
39
  """Parse an AI message."""
40
40
  if not isinstance(message, AIMessage):
41
- raise TypeError(f"Expected an AI message got {type(message)}")
41
+ msg = f"Expected an AI message got {type(message)}"
42
+ raise TypeError(msg)
42
43
 
43
44
  function_call = message.additional_kwargs.get("function_call", {})
44
45
 
45
46
  if function_call:
46
47
  try:
47
48
  arguments = json.loads(function_call["arguments"], strict=False)
48
- except JSONDecodeError:
49
- raise OutputParserException(
49
+ except JSONDecodeError as e:
50
+ msg = (
50
51
  f"Could not parse tool input: {function_call} because "
51
52
  f"the `arguments` is not valid JSON."
52
53
  )
54
+ raise OutputParserException(msg) from e
53
55
 
54
56
  try:
55
57
  tools = arguments["actions"]
56
- except (TypeError, KeyError):
57
- raise OutputParserException(
58
+ except (TypeError, KeyError) as e:
59
+ msg = (
58
60
  f"Could not parse tool input: {function_call} because "
59
61
  f"the `arguments` JSON does not contain `actions` key."
60
62
  )
63
+ raise OutputParserException(msg) from e
61
64
 
62
65
  final_tools: list[AgentAction] = []
63
66
  for tool_schema in tools:
@@ -92,10 +95,14 @@ def _parse_ai_message(message: BaseMessage) -> Union[list[AgentAction], AgentFin
92
95
  return final_tools
93
96
 
94
97
  return AgentFinish(
95
- return_values={"output": message.content}, log=str(message.content)
98
+ return_values={"output": message.content},
99
+ log=str(message.content),
96
100
  )
97
101
 
98
102
 
103
+ _NOT_SET = object()
104
+
105
+
99
106
  @deprecated("0.1.0", alternative="create_openai_tools_agent", removal="1.0")
100
107
  class OpenAIMultiFunctionsAgent(BaseMultiActionAgent):
101
108
  """Agent driven by OpenAIs function powered API.
@@ -118,13 +125,14 @@ class OpenAIMultiFunctionsAgent(BaseMultiActionAgent):
118
125
  return [t.name for t in self.tools]
119
126
 
120
127
  @model_validator(mode="after")
121
- def validate_prompt(self) -> Self:
128
+ def _validate_prompt(self) -> Self:
122
129
  prompt: BasePromptTemplate = self.prompt
123
130
  if "agent_scratchpad" not in prompt.input_variables:
124
- raise ValueError(
131
+ msg = (
125
132
  "`agent_scratchpad` should be one of the variables in the prompt, "
126
133
  f"got {prompt.input_variables}"
127
134
  )
135
+ raise ValueError(msg)
128
136
  return self
129
137
 
130
138
  @property
@@ -186,7 +194,7 @@ class OpenAIMultiFunctionsAgent(BaseMultiActionAgent):
186
194
  },
187
195
  "required": ["action_name", "action"],
188
196
  },
189
- }
197
+ },
190
198
  },
191
199
  "required": ["actions"],
192
200
  },
@@ -218,10 +226,11 @@ class OpenAIMultiFunctionsAgent(BaseMultiActionAgent):
218
226
  prompt = self.prompt.format_prompt(**full_inputs)
219
227
  messages = prompt.to_messages()
220
228
  predicted_message = self.llm.predict_messages(
221
- messages, functions=self.functions, callbacks=callbacks
229
+ messages,
230
+ functions=self.functions,
231
+ callbacks=callbacks,
222
232
  )
223
- agent_decision = _parse_ai_message(predicted_message)
224
- return agent_decision
233
+ return _parse_ai_message(predicted_message)
225
234
 
226
235
  async def aplan(
227
236
  self,
@@ -248,17 +257,16 @@ class OpenAIMultiFunctionsAgent(BaseMultiActionAgent):
248
257
  prompt = self.prompt.format_prompt(**full_inputs)
249
258
  messages = prompt.to_messages()
250
259
  predicted_message = await self.llm.apredict_messages(
251
- messages, functions=self.functions, callbacks=callbacks
260
+ messages,
261
+ functions=self.functions,
262
+ callbacks=callbacks,
252
263
  )
253
- agent_decision = _parse_ai_message(predicted_message)
254
- return agent_decision
264
+ return _parse_ai_message(predicted_message)
255
265
 
256
266
  @classmethod
257
267
  def create_prompt(
258
268
  cls,
259
- system_message: Optional[SystemMessage] = SystemMessage(
260
- content="You are a helpful AI assistant."
261
- ),
269
+ system_message: Optional[SystemMessage] = _NOT_SET, # type: ignore[assignment]
262
270
  extra_prompt_messages: Optional[list[BaseMessagePromptTemplate]] = None,
263
271
  ) -> BasePromptTemplate:
264
272
  """Create prompt for this agent.
@@ -273,18 +281,20 @@ class OpenAIMultiFunctionsAgent(BaseMultiActionAgent):
273
281
  A prompt template to pass into this agent.
274
282
  """
275
283
  _prompts = extra_prompt_messages or []
284
+ system_message_ = (
285
+ system_message
286
+ if system_message is not _NOT_SET
287
+ else SystemMessage(content="You are a helpful AI assistant.")
288
+ )
276
289
  messages: list[Union[BaseMessagePromptTemplate, BaseMessage]]
277
- if system_message:
278
- messages = [system_message]
279
- else:
280
- messages = []
290
+ messages = [system_message_] if system_message_ else []
281
291
 
282
292
  messages.extend(
283
293
  [
284
294
  *_prompts,
285
295
  HumanMessagePromptTemplate.from_template("{input}"),
286
296
  MessagesPlaceholder(variable_name="agent_scratchpad"),
287
- ]
297
+ ],
288
298
  )
289
299
  return ChatPromptTemplate(messages=messages)
290
300
 
@@ -295,9 +305,7 @@ class OpenAIMultiFunctionsAgent(BaseMultiActionAgent):
295
305
  tools: Sequence[BaseTool],
296
306
  callback_manager: Optional[BaseCallbackManager] = None,
297
307
  extra_prompt_messages: Optional[list[BaseMessagePromptTemplate]] = None,
298
- system_message: Optional[SystemMessage] = SystemMessage(
299
- content="You are a helpful AI assistant."
300
- ),
308
+ system_message: Optional[SystemMessage] = _NOT_SET, # type: ignore[assignment]
301
309
  **kwargs: Any,
302
310
  ) -> BaseMultiActionAgent:
303
311
  """Construct an agent from an LLM and tools.
@@ -311,9 +319,14 @@ class OpenAIMultiFunctionsAgent(BaseMultiActionAgent):
311
319
  Default is a default system message.
312
320
  kwargs: Additional arguments.
313
321
  """
322
+ system_message_ = (
323
+ system_message
324
+ if system_message is not _NOT_SET
325
+ else SystemMessage(content="You are a helpful AI assistant.")
326
+ )
314
327
  prompt = cls.create_prompt(
315
328
  extra_prompt_messages=extra_prompt_messages,
316
- system_message=system_message,
329
+ system_message=system_message_,
317
330
  )
318
331
  return cls( # type: ignore[call-arg]
319
332
  llm=llm,
@@ -17,7 +17,7 @@ def create_openai_tools_agent(
17
17
  llm: BaseLanguageModel,
18
18
  tools: Sequence[BaseTool],
19
19
  prompt: ChatPromptTemplate,
20
- strict: Optional[bool] = None,
20
+ strict: Optional[bool] = None, # noqa: FBT001
21
21
  ) -> Runnable:
22
22
  """Create an agent that uses OpenAI tools.
23
23
 
@@ -84,25 +84,26 @@ def create_openai_tools_agent(
84
84
  MessagesPlaceholder("agent_scratchpad"),
85
85
  ]
86
86
  )
87
+
87
88
  """
88
89
  missing_vars = {"agent_scratchpad"}.difference(
89
- prompt.input_variables + list(prompt.partial_variables)
90
+ prompt.input_variables + list(prompt.partial_variables),
90
91
  )
91
92
  if missing_vars:
92
- raise ValueError(f"Prompt missing required variables: {missing_vars}")
93
+ msg = f"Prompt missing required variables: {missing_vars}"
94
+ raise ValueError(msg)
93
95
 
94
96
  llm_with_tools = llm.bind(
95
- tools=[convert_to_openai_tool(tool, strict=strict) for tool in tools]
97
+ tools=[convert_to_openai_tool(tool, strict=strict) for tool in tools],
96
98
  )
97
99
 
98
- agent = (
100
+ return (
99
101
  RunnablePassthrough.assign(
100
102
  agent_scratchpad=lambda x: format_to_openai_tool_messages(
101
- x["intermediate_steps"]
102
- )
103
+ x["intermediate_steps"],
104
+ ),
103
105
  )
104
106
  | prompt
105
107
  | llm_with_tools
106
108
  | OpenAIToolsAgentOutputParser()
107
109
  )
108
- return agent
@@ -25,11 +25,11 @@ from langchain.agents.output_parsers.tools import ToolsAgentOutputParser
25
25
  from langchain.agents.output_parsers.xml import XMLAgentOutputParser
26
26
 
27
27
  __all__ = [
28
+ "JSONAgentOutputParser",
29
+ "OpenAIFunctionsAgentOutputParser",
30
+ "ReActJsonSingleInputOutputParser",
28
31
  "ReActSingleInputOutputParser",
29
32
  "SelfAskOutputParser",
30
33
  "ToolsAgentOutputParser",
31
- "ReActJsonSingleInputOutputParser",
32
- "OpenAIFunctionsAgentOutputParser",
33
34
  "XMLAgentOutputParser",
34
- "JSONAgentOutputParser",
35
35
  ]
@@ -6,6 +6,7 @@ from typing import Union
6
6
  from langchain_core.agents import AgentAction, AgentFinish
7
7
  from langchain_core.exceptions import OutputParserException
8
8
  from langchain_core.utils.json import parse_json_markdown
9
+ from typing_extensions import override
9
10
 
10
11
  from langchain.agents.agent import AgentOutputParser
11
12
 
@@ -40,6 +41,7 @@ class JSONAgentOutputParser(AgentOutputParser):
40
41
  ```
41
42
  """
42
43
 
44
+ @override
43
45
  def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
44
46
  try:
45
47
  response = parse_json_markdown(text)
@@ -49,13 +51,13 @@ class JSONAgentOutputParser(AgentOutputParser):
49
51
  response = response[0]
50
52
  if response["action"] == "Final Answer":
51
53
  return AgentFinish({"output": response["action_input"]}, text)
52
- else:
53
- action_input = response.get("action_input", {})
54
- if action_input is None:
55
- action_input = {}
56
- return AgentAction(response["action"], action_input, text)
54
+ action_input = response.get("action_input", {})
55
+ if action_input is None:
56
+ action_input = {}
57
+ return AgentAction(response["action"], action_input, text)
57
58
  except Exception as e:
58
- raise OutputParserException(f"Could not parse LLM output: {text}") from e
59
+ msg = f"Could not parse LLM output: {text}"
60
+ raise OutputParserException(msg) from e
59
61
 
60
62
  @property
61
63
  def _type(self) -> str:
@@ -8,7 +8,10 @@ from langchain_core.messages import (
8
8
  AIMessage,
9
9
  BaseMessage,
10
10
  )
11
+ from langchain_core.messages.utils import convert_from_v1_message
11
12
  from langchain_core.outputs import ChatGeneration, Generation
13
+ from langchain_core.v1.messages import AIMessage as AIMessageV1
14
+ from typing_extensions import override
12
15
 
13
16
  from langchain.agents.agent import AgentOutputParser
14
17
 
@@ -30,10 +33,11 @@ class OpenAIFunctionsAgentOutputParser(AgentOutputParser):
30
33
  return "openai-functions-agent"
31
34
 
32
35
  @staticmethod
33
- def _parse_ai_message(message: BaseMessage) -> Union[AgentAction, AgentFinish]:
36
+ def parse_ai_message(message: BaseMessage) -> Union[AgentAction, AgentFinish]:
34
37
  """Parse an AI message."""
35
38
  if not isinstance(message, AIMessage):
36
- raise TypeError(f"Expected an AI message got {type(message)}")
39
+ msg = f"Expected an AI message got {type(message)}"
40
+ raise TypeError(msg)
37
41
 
38
42
  function_call = message.additional_kwargs.get("function_call", {})
39
43
 
@@ -46,11 +50,12 @@ class OpenAIFunctionsAgentOutputParser(AgentOutputParser):
46
50
  else:
47
51
  # otherwise it returns a json object
48
52
  _tool_input = json.loads(function_call["arguments"], strict=False)
49
- except JSONDecodeError:
50
- raise OutputParserException(
53
+ except JSONDecodeError as e:
54
+ msg = (
51
55
  f"Could not parse tool input: {function_call} because "
52
56
  f"the `arguments` is not valid JSON."
53
57
  )
58
+ raise OutputParserException(msg) from e
54
59
 
55
60
  # HACK HACK HACK:
56
61
  # The code that encodes tool input into Open AI uses a special variable
@@ -73,16 +78,26 @@ class OpenAIFunctionsAgentOutputParser(AgentOutputParser):
73
78
  )
74
79
 
75
80
  return AgentFinish(
76
- return_values={"output": message.content}, log=str(message.content)
81
+ return_values={"output": message.content},
82
+ log=str(message.content),
77
83
  )
78
84
 
85
+ @override
79
86
  def parse_result(
80
- self, result: list[Generation], *, partial: bool = False
87
+ self,
88
+ result: Union[list[Generation], AIMessageV1],
89
+ *,
90
+ partial: bool = False,
81
91
  ) -> Union[AgentAction, AgentFinish]:
92
+ if isinstance(result, AIMessageV1):
93
+ result = [ChatGeneration(message=convert_from_v1_message(result))]
82
94
  if not isinstance(result[0], ChatGeneration):
83
- raise ValueError("This output parser only works on ChatGeneration output")
95
+ msg = "This output parser only works on ChatGeneration output"
96
+ raise ValueError(msg) # noqa: TRY004
84
97
  message = result[0].message
85
- return self._parse_ai_message(message)
98
+ return self.parse_ai_message(message)
86
99
 
100
+ @override
87
101
  def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
88
- raise ValueError("Can only parse messages")
102
+ msg = "Can only parse messages"
103
+ raise ValueError(msg)
@@ -2,7 +2,10 @@ from typing import Union
2
2
 
3
3
  from langchain_core.agents import AgentAction, AgentFinish
4
4
  from langchain_core.messages import BaseMessage
5
+ from langchain_core.messages.utils import convert_from_v1_message
5
6
  from langchain_core.outputs import ChatGeneration, Generation
7
+ from langchain_core.v1.messages import AIMessage as AIMessageV1
8
+ from typing_extensions import override
6
9
 
7
10
  from langchain.agents.agent import MultiActionAgentOutputParser
8
11
  from langchain.agents.output_parsers.tools import (
@@ -30,7 +33,7 @@ def parse_ai_message_to_openai_tool_action(
30
33
  log=action.log,
31
34
  message_log=action.message_log,
32
35
  tool_call_id=action.tool_call_id,
33
- )
36
+ ),
34
37
  )
35
38
  else:
36
39
  final_actions.append(action)
@@ -53,13 +56,22 @@ class OpenAIToolsAgentOutputParser(MultiActionAgentOutputParser):
53
56
  def _type(self) -> str:
54
57
  return "openai-tools-agent-output-parser"
55
58
 
59
+ @override
56
60
  def parse_result(
57
- self, result: list[Generation], *, partial: bool = False
61
+ self,
62
+ result: Union[list[Generation], AIMessageV1],
63
+ *,
64
+ partial: bool = False,
58
65
  ) -> Union[list[AgentAction], AgentFinish]:
66
+ if isinstance(result, AIMessageV1):
67
+ result = [ChatGeneration(message=convert_from_v1_message(result))]
59
68
  if not isinstance(result[0], ChatGeneration):
60
- raise ValueError("This output parser only works on ChatGeneration output")
69
+ msg = "This output parser only works on ChatGeneration output"
70
+ raise ValueError(msg) # noqa: TRY004
61
71
  message = result[0].message
62
72
  return parse_ai_message_to_openai_tool_action(message)
63
73
 
74
+ @override
64
75
  def parse(self, text: str) -> Union[list[AgentAction], AgentFinish]:
65
- raise ValueError("Can only parse messages")
76
+ msg = "Can only parse messages"
77
+ raise ValueError(msg)
@@ -5,6 +5,7 @@ from typing import Union
5
5
 
6
6
  from langchain_core.agents import AgentAction, AgentFinish
7
7
  from langchain_core.exceptions import OutputParserException
8
+ from typing_extensions import override
8
9
 
9
10
  from langchain.agents.agent import AgentOutputParser
10
11
  from langchain.agents.chat.prompt import FORMAT_INSTRUCTIONS
@@ -46,31 +47,38 @@ class ReActJsonSingleInputOutputParser(AgentOutputParser):
46
47
  pattern: Pattern = re.compile(r"^.*?`{3}(?:json)?\n?(.*?)`{3}.*?$", re.DOTALL)
47
48
  """Regex pattern to parse the output."""
48
49
 
50
+ @override
49
51
  def get_format_instructions(self) -> str:
50
52
  return FORMAT_INSTRUCTIONS
51
53
 
54
+ @override
52
55
  def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
53
56
  includes_answer = FINAL_ANSWER_ACTION in text
54
57
  try:
55
58
  found = self.pattern.search(text)
56
59
  if not found:
57
60
  # Fast fail to parse Final Answer.
58
- raise ValueError("action not found")
61
+ msg = "action not found"
62
+ raise ValueError(msg)
59
63
  action = found.group(1)
60
64
  response = json.loads(action.strip())
61
65
  includes_action = "action" in response
62
66
  if includes_answer and includes_action:
63
- raise OutputParserException(
67
+ msg = (
64
68
  "Parsing LLM output produced a final answer "
65
69
  f"and a parse-able action: {text}"
66
70
  )
71
+ raise OutputParserException(msg)
67
72
  return AgentAction(
68
- response["action"], response.get("action_input", {}), text
73
+ response["action"],
74
+ response.get("action_input", {}),
75
+ text,
69
76
  )
70
77
 
71
- except Exception:
78
+ except Exception as e:
72
79
  if not includes_answer:
73
- raise OutputParserException(f"Could not parse LLM output: {text}")
80
+ msg = f"Could not parse LLM output: {text}"
81
+ raise OutputParserException(msg) from e
74
82
  output = text.split(FINAL_ANSWER_ACTION)[-1].strip()
75
83
  return AgentFinish({"output": output}, text)
76
84
 
@@ -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
  from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS
@@ -45,9 +46,11 @@ class ReActSingleInputOutputParser(AgentOutputParser):
45
46
 
46
47
  """
47
48
 
49
+ @override
48
50
  def get_format_instructions(self) -> str:
49
51
  return FORMAT_INSTRUCTIONS
50
52
 
53
+ @override
51
54
  def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
52
55
  includes_answer = FINAL_ANSWER_ACTION in text
53
56
  regex = (
@@ -56,9 +59,8 @@ class ReActSingleInputOutputParser(AgentOutputParser):
56
59
  action_match = re.search(regex, text, re.DOTALL)
57
60
  if action_match:
58
61
  if includes_answer:
59
- raise OutputParserException(
60
- f"{FINAL_ANSWER_AND_PARSABLE_ACTION_ERROR_MESSAGE}: {text}"
61
- )
62
+ msg = f"{FINAL_ANSWER_AND_PARSABLE_ACTION_ERROR_MESSAGE}: {text}"
63
+ raise OutputParserException(msg)
62
64
  action = action_match.group(1).strip()
63
65
  action_input = action_match.group(2)
64
66
  tool_input = action_input.strip(" ")
@@ -66,29 +68,34 @@ class ReActSingleInputOutputParser(AgentOutputParser):
66
68
 
67
69
  return AgentAction(action, tool_input, text)
68
70
 
69
- elif includes_answer:
71
+ if includes_answer:
70
72
  return AgentFinish(
71
- {"output": text.split(FINAL_ANSWER_ACTION)[-1].strip()}, text
73
+ {"output": text.split(FINAL_ANSWER_ACTION)[-1].strip()},
74
+ text,
72
75
  )
73
76
 
74
77
  if not re.search(r"Action\s*\d*\s*:[\s]*(.*?)", text, re.DOTALL):
78
+ msg = f"Could not parse LLM output: `{text}`"
75
79
  raise OutputParserException(
76
- f"Could not parse LLM output: `{text}`",
80
+ msg,
77
81
  observation=MISSING_ACTION_AFTER_THOUGHT_ERROR_MESSAGE,
78
82
  llm_output=text,
79
83
  send_to_llm=True,
80
84
  )
81
- elif not re.search(
82
- r"[\s]*Action\s*\d*\s*Input\s*\d*\s*:[\s]*(.*)", text, re.DOTALL
85
+ if not re.search(
86
+ r"[\s]*Action\s*\d*\s*Input\s*\d*\s*:[\s]*(.*)",
87
+ text,
88
+ re.DOTALL,
83
89
  ):
90
+ msg = f"Could not parse LLM output: `{text}`"
84
91
  raise OutputParserException(
85
- f"Could not parse LLM output: `{text}`",
92
+ msg,
86
93
  observation=MISSING_ACTION_INPUT_AFTER_ACTION_ERROR_MESSAGE,
87
94
  llm_output=text,
88
95
  send_to_llm=True,
89
96
  )
90
- else:
91
- raise OutputParserException(f"Could not parse LLM output: `{text}`")
97
+ msg = f"Could not parse LLM output: `{text}`"
98
+ raise OutputParserException(msg)
92
99
 
93
100
  @property
94
101
  def _type(self) -> str:
@@ -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
 
@@ -35,11 +36,13 @@ class SelfAskOutputParser(AgentOutputParser):
35
36
  followups: Sequence[str] = ("Follow up:", "Followup:")
36
37
  finish_string: str = "So the final answer is: "
37
38
 
39
+ @override
38
40
  def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
39
41
  last_line = text.split("\n")[-1]
40
- if not any([follow in last_line for follow in self.followups]):
42
+ if not any(follow in last_line for follow in self.followups):
41
43
  if self.finish_string not in last_line:
42
- raise OutputParserException(f"Could not parse output: {text}")
44
+ msg = f"Could not parse output: {text}"
45
+ raise OutputParserException(msg)
43
46
  return AgentFinish({"output": last_line[len(self.finish_string) :]}, text)
44
47
 
45
48
  after_colon = text.split(":")[-1].strip()
@@ -9,12 +9,17 @@ from langchain_core.messages import (
9
9
  BaseMessage,
10
10
  ToolCall,
11
11
  )
12
+ from langchain_core.messages.utils import convert_from_v1_message
12
13
  from langchain_core.outputs import ChatGeneration, Generation
14
+ from langchain_core.v1.messages import AIMessage as AIMessageV1
15
+ from typing_extensions import override
13
16
 
14
17
  from langchain.agents.agent import MultiActionAgentOutputParser
15
18
 
16
19
 
17
20
  class ToolAgentAction(AgentActionMessageLog):
21
+ """ "Tool agent action."""
22
+
18
23
  tool_call_id: str
19
24
  """Tool call that this message is responding to."""
20
25
 
@@ -24,7 +29,8 @@ def parse_ai_message_to_tool_action(
24
29
  ) -> Union[list[AgentAction], AgentFinish]:
25
30
  """Parse an AI message potentially containing tool_calls."""
26
31
  if not isinstance(message, AIMessage):
27
- raise TypeError(f"Expected an AI message got {type(message)}")
32
+ msg = f"Expected an AI message got {type(message)}"
33
+ raise TypeError(msg)
28
34
 
29
35
  actions: list = []
30
36
  if message.tool_calls:
@@ -32,7 +38,8 @@ def parse_ai_message_to_tool_action(
32
38
  else:
33
39
  if not message.additional_kwargs.get("tool_calls"):
34
40
  return AgentFinish(
35
- return_values={"output": message.content}, log=str(message.content)
41
+ return_values={"output": message.content},
42
+ log=str(message.content),
36
43
  )
37
44
  # Best-effort parsing
38
45
  tool_calls = []
@@ -42,13 +49,19 @@ def parse_ai_message_to_tool_action(
42
49
  try:
43
50
  args = json.loads(function["arguments"] or "{}")
44
51
  tool_calls.append(
45
- ToolCall(name=function_name, args=args, id=tool_call["id"])
52
+ ToolCall(
53
+ name=function_name,
54
+ args=args,
55
+ id=tool_call["id"],
56
+ type="tool_call",
57
+ )
46
58
  )
47
- except JSONDecodeError:
48
- raise OutputParserException(
59
+ except JSONDecodeError as e:
60
+ msg = (
49
61
  f"Could not parse tool input: {function} because "
50
62
  f"the `arguments` is not valid JSON."
51
63
  )
64
+ raise OutputParserException(msg) from e
52
65
  for tool_call in tool_calls:
53
66
  # HACK HACK HACK:
54
67
  # The code that encodes tool input into Open AI uses a special variable
@@ -58,10 +71,7 @@ def parse_ai_message_to_tool_action(
58
71
  # Open AI does not support passing in a JSON array as an argument.
59
72
  function_name = tool_call["name"]
60
73
  _tool_input = tool_call["args"]
61
- if "__arg1" in _tool_input:
62
- tool_input = _tool_input["__arg1"]
63
- else:
64
- tool_input = _tool_input
74
+ tool_input = _tool_input.get("__arg1", _tool_input)
65
75
 
66
76
  content_msg = f"responded: {message.content}\n" if message.content else "\n"
67
77
  log = f"\nInvoking: `{function_name}` with `{tool_input}`\n{content_msg}\n"
@@ -72,7 +82,7 @@ def parse_ai_message_to_tool_action(
72
82
  log=log,
73
83
  message_log=[message],
74
84
  tool_call_id=tool_call["id"],
75
- )
85
+ ),
76
86
  )
77
87
  return actions
78
88
 
@@ -90,13 +100,22 @@ class ToolsAgentOutputParser(MultiActionAgentOutputParser):
90
100
  def _type(self) -> str:
91
101
  return "tools-agent-output-parser"
92
102
 
103
+ @override
93
104
  def parse_result(
94
- self, result: list[Generation], *, partial: bool = False
105
+ self,
106
+ result: Union[list[Generation], AIMessageV1],
107
+ *,
108
+ partial: bool = False,
95
109
  ) -> Union[list[AgentAction], AgentFinish]:
110
+ if isinstance(result, AIMessageV1):
111
+ result = [ChatGeneration(message=convert_from_v1_message(result))]
96
112
  if not isinstance(result[0], ChatGeneration):
97
- raise ValueError("This output parser only works on ChatGeneration output")
113
+ msg = "This output parser only works on ChatGeneration output"
114
+ raise ValueError(msg) # noqa: TRY004
98
115
  message = result[0].message
99
116
  return parse_ai_message_to_tool_action(message)
100
117
 
118
+ @override
101
119
  def parse(self, text: str) -> Union[list[AgentAction], AgentFinish]:
102
- raise ValueError("Can only parse messages")
120
+ msg = "Can only parse messages"
121
+ raise ValueError(msg)