langchain 0.3.26__py3-none-any.whl → 0.3.27__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (580) 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 +160 -133
  9. langchain/agents/agent_iterator.py +31 -14
  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 +2 -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 +6 -12
  49. langchain/agents/chat/output_parser.py +9 -6
  50. langchain/agents/chat/prompt.py +3 -4
  51. langchain/agents/conversational/base.py +9 -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 +7 -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 +16 -8
  63. langchain/agents/json_chat/base.py +18 -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 +9 -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 +80 -70
  71. langchain/agents/openai_functions_agent/base.py +46 -37
  72. langchain/agents/openai_functions_multi_agent/base.py +39 -26
  73. langchain/agents/openai_tools/base.py +8 -8
  74. langchain/agents/output_parsers/__init__.py +3 -3
  75. langchain/agents/output_parsers/json.py +6 -6
  76. langchain/agents/output_parsers/openai_functions.py +15 -7
  77. langchain/agents/output_parsers/openai_tools.py +9 -4
  78. langchain/agents/output_parsers/react_json_single_input.py +10 -5
  79. langchain/agents/output_parsers/react_single_input.py +15 -11
  80. langchain/agents/output_parsers/self_ask.py +3 -2
  81. langchain/agents/output_parsers/tools.py +18 -13
  82. langchain/agents/output_parsers/xml.py +99 -28
  83. langchain/agents/react/agent.py +4 -4
  84. langchain/agents/react/base.py +22 -17
  85. langchain/agents/react/output_parser.py +5 -6
  86. langchain/agents/react/textworld_prompt.py +0 -1
  87. langchain/agents/react/wiki_prompt.py +14 -15
  88. langchain/agents/schema.py +3 -2
  89. langchain/agents/self_ask_with_search/base.py +19 -15
  90. langchain/agents/self_ask_with_search/prompt.py +0 -1
  91. langchain/agents/structured_chat/base.py +14 -11
  92. langchain/agents/structured_chat/output_parser.py +16 -18
  93. langchain/agents/structured_chat/prompt.py +3 -4
  94. langchain/agents/tool_calling_agent/base.py +7 -6
  95. langchain/agents/tools.py +2 -2
  96. langchain/agents/utils.py +2 -3
  97. langchain/agents/xml/base.py +5 -5
  98. langchain/agents/xml/prompt.py +1 -2
  99. langchain/cache.py +12 -12
  100. langchain/callbacks/__init__.py +11 -11
  101. langchain/callbacks/aim_callback.py +2 -2
  102. langchain/callbacks/argilla_callback.py +1 -1
  103. langchain/callbacks/arize_callback.py +1 -1
  104. langchain/callbacks/arthur_callback.py +1 -1
  105. langchain/callbacks/base.py +7 -7
  106. langchain/callbacks/clearml_callback.py +1 -1
  107. langchain/callbacks/comet_ml_callback.py +1 -1
  108. langchain/callbacks/confident_callback.py +1 -1
  109. langchain/callbacks/context_callback.py +1 -1
  110. langchain/callbacks/flyte_callback.py +1 -1
  111. langchain/callbacks/human.py +2 -2
  112. langchain/callbacks/infino_callback.py +1 -1
  113. langchain/callbacks/labelstudio_callback.py +1 -1
  114. langchain/callbacks/llmonitor_callback.py +1 -1
  115. langchain/callbacks/manager.py +5 -5
  116. langchain/callbacks/mlflow_callback.py +2 -2
  117. langchain/callbacks/openai_info.py +1 -1
  118. langchain/callbacks/promptlayer_callback.py +1 -1
  119. langchain/callbacks/sagemaker_callback.py +1 -1
  120. langchain/callbacks/streaming_aiter.py +4 -1
  121. langchain/callbacks/streaming_aiter_final_only.py +5 -3
  122. langchain/callbacks/streaming_stdout_final_only.py +5 -3
  123. langchain/callbacks/streamlit/__init__.py +3 -2
  124. langchain/callbacks/streamlit/mutable_expander.py +1 -1
  125. langchain/callbacks/streamlit/streamlit_callback_handler.py +3 -3
  126. langchain/callbacks/tracers/__init__.py +1 -1
  127. langchain/callbacks/tracers/comet.py +1 -1
  128. langchain/callbacks/tracers/evaluation.py +1 -1
  129. langchain/callbacks/tracers/log_stream.py +1 -1
  130. langchain/callbacks/tracers/logging.py +1 -1
  131. langchain/callbacks/tracers/stdout.py +1 -1
  132. langchain/callbacks/trubrics_callback.py +1 -1
  133. langchain/callbacks/utils.py +4 -4
  134. langchain/callbacks/wandb_callback.py +1 -1
  135. langchain/callbacks/whylabs_callback.py +1 -1
  136. langchain/chains/api/base.py +36 -22
  137. langchain/chains/api/news_docs.py +1 -2
  138. langchain/chains/api/open_meteo_docs.py +1 -2
  139. langchain/chains/api/openapi/requests_chain.py +1 -1
  140. langchain/chains/api/openapi/response_chain.py +1 -1
  141. langchain/chains/api/podcast_docs.py +1 -2
  142. langchain/chains/api/prompt.py +1 -2
  143. langchain/chains/api/tmdb_docs.py +1 -2
  144. langchain/chains/base.py +88 -54
  145. langchain/chains/chat_vector_db/prompts.py +2 -3
  146. langchain/chains/combine_documents/__init__.py +1 -1
  147. langchain/chains/combine_documents/base.py +23 -10
  148. langchain/chains/combine_documents/map_reduce.py +38 -30
  149. langchain/chains/combine_documents/map_rerank.py +33 -20
  150. langchain/chains/combine_documents/reduce.py +47 -26
  151. langchain/chains/combine_documents/refine.py +26 -17
  152. langchain/chains/combine_documents/stuff.py +19 -12
  153. langchain/chains/constitutional_ai/base.py +4 -4
  154. langchain/chains/constitutional_ai/principles.py +22 -25
  155. langchain/chains/constitutional_ai/prompts.py +25 -28
  156. langchain/chains/conversation/base.py +5 -3
  157. langchain/chains/conversation/memory.py +5 -5
  158. langchain/chains/conversation/prompt.py +5 -5
  159. langchain/chains/conversational_retrieval/base.py +41 -20
  160. langchain/chains/conversational_retrieval/prompts.py +2 -3
  161. langchain/chains/elasticsearch_database/base.py +8 -9
  162. langchain/chains/elasticsearch_database/prompts.py +2 -3
  163. langchain/chains/ernie_functions/__init__.py +2 -2
  164. langchain/chains/example_generator.py +3 -1
  165. langchain/chains/flare/base.py +26 -12
  166. langchain/chains/graph_qa/cypher.py +2 -2
  167. langchain/chains/graph_qa/falkordb.py +1 -1
  168. langchain/chains/graph_qa/gremlin.py +1 -1
  169. langchain/chains/graph_qa/neptune_sparql.py +1 -1
  170. langchain/chains/graph_qa/prompts.py +2 -2
  171. langchain/chains/history_aware_retriever.py +2 -1
  172. langchain/chains/hyde/base.py +6 -5
  173. langchain/chains/hyde/prompts.py +5 -6
  174. langchain/chains/llm.py +77 -61
  175. langchain/chains/llm_bash/__init__.py +2 -1
  176. langchain/chains/llm_checker/base.py +7 -5
  177. langchain/chains/llm_checker/prompt.py +3 -4
  178. langchain/chains/llm_math/base.py +16 -9
  179. langchain/chains/llm_math/prompt.py +1 -2
  180. langchain/chains/llm_summarization_checker/base.py +9 -6
  181. langchain/chains/llm_symbolic_math/__init__.py +2 -1
  182. langchain/chains/loading.py +151 -95
  183. langchain/chains/mapreduce.py +4 -3
  184. langchain/chains/moderation.py +8 -9
  185. langchain/chains/natbot/base.py +8 -8
  186. langchain/chains/natbot/crawler.py +73 -76
  187. langchain/chains/natbot/prompt.py +2 -3
  188. langchain/chains/openai_functions/__init__.py +7 -7
  189. langchain/chains/openai_functions/base.py +13 -10
  190. langchain/chains/openai_functions/citation_fuzzy_match.py +12 -11
  191. langchain/chains/openai_functions/extraction.py +19 -19
  192. langchain/chains/openai_functions/openapi.py +35 -35
  193. langchain/chains/openai_functions/qa_with_structure.py +19 -12
  194. langchain/chains/openai_functions/tagging.py +2 -4
  195. langchain/chains/openai_tools/extraction.py +7 -8
  196. langchain/chains/qa_generation/base.py +4 -3
  197. langchain/chains/qa_generation/prompt.py +5 -5
  198. langchain/chains/qa_with_sources/base.py +14 -6
  199. langchain/chains/qa_with_sources/loading.py +16 -8
  200. langchain/chains/qa_with_sources/map_reduce_prompt.py +8 -9
  201. langchain/chains/qa_with_sources/refine_prompts.py +0 -1
  202. langchain/chains/qa_with_sources/retrieval.py +14 -5
  203. langchain/chains/qa_with_sources/stuff_prompt.py +6 -7
  204. langchain/chains/qa_with_sources/vector_db.py +17 -6
  205. langchain/chains/query_constructor/base.py +34 -33
  206. langchain/chains/query_constructor/ir.py +4 -4
  207. langchain/chains/query_constructor/parser.py +37 -32
  208. langchain/chains/query_constructor/prompt.py +5 -6
  209. langchain/chains/question_answering/chain.py +21 -10
  210. langchain/chains/question_answering/map_reduce_prompt.py +14 -14
  211. langchain/chains/question_answering/map_rerank_prompt.py +3 -3
  212. langchain/chains/question_answering/refine_prompts.py +2 -5
  213. langchain/chains/question_answering/stuff_prompt.py +5 -5
  214. langchain/chains/retrieval.py +1 -3
  215. langchain/chains/retrieval_qa/base.py +34 -27
  216. langchain/chains/retrieval_qa/prompt.py +1 -2
  217. langchain/chains/router/__init__.py +3 -3
  218. langchain/chains/router/base.py +24 -20
  219. langchain/chains/router/embedding_router.py +12 -8
  220. langchain/chains/router/llm_router.py +17 -16
  221. langchain/chains/router/multi_prompt.py +2 -2
  222. langchain/chains/router/multi_retrieval_qa.py +10 -5
  223. langchain/chains/sequential.py +30 -18
  224. langchain/chains/sql_database/prompt.py +14 -16
  225. langchain/chains/sql_database/query.py +6 -5
  226. langchain/chains/structured_output/__init__.py +1 -1
  227. langchain/chains/structured_output/base.py +75 -67
  228. langchain/chains/summarize/chain.py +11 -5
  229. langchain/chains/summarize/map_reduce_prompt.py +0 -1
  230. langchain/chains/summarize/stuff_prompt.py +0 -1
  231. langchain/chains/transform.py +5 -6
  232. langchain/chat_loaders/facebook_messenger.py +1 -1
  233. langchain/chat_loaders/langsmith.py +1 -1
  234. langchain/chat_loaders/utils.py +3 -3
  235. langchain/chat_models/__init__.py +20 -19
  236. langchain/chat_models/anthropic.py +1 -1
  237. langchain/chat_models/azureml_endpoint.py +1 -1
  238. langchain/chat_models/baidu_qianfan_endpoint.py +1 -1
  239. langchain/chat_models/base.py +160 -123
  240. langchain/chat_models/bedrock.py +1 -1
  241. langchain/chat_models/fake.py +1 -1
  242. langchain/chat_models/meta.py +1 -1
  243. langchain/chat_models/pai_eas_endpoint.py +1 -1
  244. langchain/chat_models/promptlayer_openai.py +1 -1
  245. langchain/chat_models/volcengine_maas.py +1 -1
  246. langchain/docstore/base.py +1 -1
  247. langchain/document_loaders/__init__.py +9 -9
  248. langchain/document_loaders/airbyte.py +3 -3
  249. langchain/document_loaders/assemblyai.py +1 -1
  250. langchain/document_loaders/azure_blob_storage_container.py +1 -1
  251. langchain/document_loaders/azure_blob_storage_file.py +1 -1
  252. langchain/document_loaders/baiducloud_bos_file.py +1 -1
  253. langchain/document_loaders/base.py +1 -1
  254. langchain/document_loaders/blob_loaders/__init__.py +1 -1
  255. langchain/document_loaders/blockchain.py +1 -1
  256. langchain/document_loaders/chatgpt.py +1 -1
  257. langchain/document_loaders/college_confidential.py +1 -1
  258. langchain/document_loaders/confluence.py +1 -1
  259. langchain/document_loaders/email.py +1 -1
  260. langchain/document_loaders/facebook_chat.py +1 -1
  261. langchain/document_loaders/markdown.py +1 -1
  262. langchain/document_loaders/notebook.py +1 -1
  263. langchain/document_loaders/org_mode.py +1 -1
  264. langchain/document_loaders/parsers/__init__.py +1 -1
  265. langchain/document_loaders/parsers/docai.py +1 -1
  266. langchain/document_loaders/parsers/generic.py +1 -1
  267. langchain/document_loaders/parsers/html/__init__.py +1 -1
  268. langchain/document_loaders/parsers/html/bs4.py +1 -1
  269. langchain/document_loaders/parsers/language/cobol.py +1 -1
  270. langchain/document_loaders/parsers/language/python.py +1 -1
  271. langchain/document_loaders/parsers/msword.py +1 -1
  272. langchain/document_loaders/parsers/pdf.py +5 -5
  273. langchain/document_loaders/parsers/registry.py +1 -1
  274. langchain/document_loaders/pdf.py +8 -8
  275. langchain/document_loaders/powerpoint.py +1 -1
  276. langchain/document_loaders/pyspark_dataframe.py +1 -1
  277. langchain/document_loaders/telegram.py +2 -2
  278. langchain/document_loaders/tencent_cos_directory.py +1 -1
  279. langchain/document_loaders/unstructured.py +5 -5
  280. langchain/document_loaders/url_playwright.py +1 -1
  281. langchain/document_loaders/whatsapp_chat.py +1 -1
  282. langchain/document_loaders/youtube.py +2 -2
  283. langchain/document_transformers/__init__.py +3 -3
  284. langchain/document_transformers/beautiful_soup_transformer.py +1 -1
  285. langchain/document_transformers/doctran_text_extract.py +1 -1
  286. langchain/document_transformers/doctran_text_qa.py +1 -1
  287. langchain/document_transformers/doctran_text_translate.py +1 -1
  288. langchain/document_transformers/embeddings_redundant_filter.py +3 -3
  289. langchain/document_transformers/google_translate.py +1 -1
  290. langchain/document_transformers/html2text.py +1 -1
  291. langchain/document_transformers/nuclia_text_transform.py +1 -1
  292. langchain/embeddings/__init__.py +5 -5
  293. langchain/embeddings/base.py +33 -24
  294. langchain/embeddings/cache.py +36 -31
  295. langchain/embeddings/fake.py +1 -1
  296. langchain/embeddings/huggingface.py +2 -2
  297. langchain/evaluation/__init__.py +22 -22
  298. langchain/evaluation/agents/trajectory_eval_chain.py +23 -23
  299. langchain/evaluation/agents/trajectory_eval_prompt.py +6 -9
  300. langchain/evaluation/comparison/__init__.py +1 -1
  301. langchain/evaluation/comparison/eval_chain.py +20 -13
  302. langchain/evaluation/comparison/prompt.py +1 -2
  303. langchain/evaluation/criteria/__init__.py +1 -1
  304. langchain/evaluation/criteria/eval_chain.py +20 -11
  305. langchain/evaluation/criteria/prompt.py +2 -3
  306. langchain/evaluation/embedding_distance/base.py +23 -20
  307. langchain/evaluation/loading.py +15 -11
  308. langchain/evaluation/parsing/base.py +4 -1
  309. langchain/evaluation/parsing/json_distance.py +5 -2
  310. langchain/evaluation/parsing/json_schema.py +12 -8
  311. langchain/evaluation/qa/__init__.py +1 -1
  312. langchain/evaluation/qa/eval_chain.py +12 -5
  313. langchain/evaluation/qa/eval_prompt.py +7 -8
  314. langchain/evaluation/qa/generate_chain.py +2 -1
  315. langchain/evaluation/qa/generate_prompt.py +2 -4
  316. langchain/evaluation/schema.py +38 -30
  317. langchain/evaluation/scoring/__init__.py +1 -1
  318. langchain/evaluation/scoring/eval_chain.py +22 -15
  319. langchain/evaluation/scoring/prompt.py +0 -1
  320. langchain/evaluation/string_distance/base.py +14 -9
  321. langchain/globals.py +12 -11
  322. langchain/graphs/__init__.py +6 -6
  323. langchain/graphs/graph_document.py +1 -1
  324. langchain/graphs/networkx_graph.py +2 -2
  325. langchain/hub.py +9 -11
  326. langchain/indexes/__init__.py +3 -3
  327. langchain/indexes/_sql_record_manager.py +63 -46
  328. langchain/indexes/prompts/entity_extraction.py +1 -2
  329. langchain/indexes/prompts/entity_summarization.py +1 -2
  330. langchain/indexes/prompts/knowledge_triplet_extraction.py +1 -3
  331. langchain/indexes/vectorstore.py +35 -19
  332. langchain/llms/__init__.py +13 -13
  333. langchain/llms/ai21.py +1 -1
  334. langchain/llms/azureml_endpoint.py +4 -4
  335. langchain/llms/base.py +15 -7
  336. langchain/llms/bedrock.py +1 -1
  337. langchain/llms/cloudflare_workersai.py +1 -1
  338. langchain/llms/gradient_ai.py +1 -1
  339. langchain/llms/loading.py +1 -1
  340. langchain/llms/openai.py +1 -1
  341. langchain/llms/sagemaker_endpoint.py +1 -1
  342. langchain/load/dump.py +1 -1
  343. langchain/load/load.py +1 -1
  344. langchain/load/serializable.py +3 -3
  345. langchain/memory/__init__.py +3 -3
  346. langchain/memory/buffer.py +9 -7
  347. langchain/memory/chat_memory.py +14 -8
  348. langchain/memory/chat_message_histories/__init__.py +1 -1
  349. langchain/memory/chat_message_histories/astradb.py +1 -1
  350. langchain/memory/chat_message_histories/cassandra.py +1 -1
  351. langchain/memory/chat_message_histories/cosmos_db.py +1 -1
  352. langchain/memory/chat_message_histories/dynamodb.py +1 -1
  353. langchain/memory/chat_message_histories/elasticsearch.py +1 -1
  354. langchain/memory/chat_message_histories/file.py +1 -1
  355. langchain/memory/chat_message_histories/firestore.py +1 -1
  356. langchain/memory/chat_message_histories/momento.py +1 -1
  357. langchain/memory/chat_message_histories/mongodb.py +1 -1
  358. langchain/memory/chat_message_histories/neo4j.py +1 -1
  359. langchain/memory/chat_message_histories/postgres.py +1 -1
  360. langchain/memory/chat_message_histories/redis.py +1 -1
  361. langchain/memory/chat_message_histories/rocksetdb.py +1 -1
  362. langchain/memory/chat_message_histories/singlestoredb.py +1 -1
  363. langchain/memory/chat_message_histories/streamlit.py +1 -1
  364. langchain/memory/chat_message_histories/upstash_redis.py +1 -1
  365. langchain/memory/chat_message_histories/xata.py +1 -1
  366. langchain/memory/chat_message_histories/zep.py +1 -1
  367. langchain/memory/combined.py +13 -12
  368. langchain/memory/entity.py +84 -61
  369. langchain/memory/prompt.py +10 -11
  370. langchain/memory/readonly.py +0 -2
  371. langchain/memory/simple.py +1 -3
  372. langchain/memory/summary.py +13 -11
  373. langchain/memory/summary_buffer.py +17 -8
  374. langchain/memory/utils.py +3 -2
  375. langchain/memory/vectorstore.py +12 -5
  376. langchain/memory/vectorstore_token_buffer_memory.py +5 -5
  377. langchain/model_laboratory.py +12 -11
  378. langchain/output_parsers/__init__.py +4 -4
  379. langchain/output_parsers/boolean.py +7 -4
  380. langchain/output_parsers/combining.py +10 -5
  381. langchain/output_parsers/datetime.py +32 -31
  382. langchain/output_parsers/enum.py +5 -3
  383. langchain/output_parsers/fix.py +52 -52
  384. langchain/output_parsers/format_instructions.py +6 -8
  385. langchain/output_parsers/json.py +2 -2
  386. langchain/output_parsers/list.py +2 -2
  387. langchain/output_parsers/loading.py +9 -9
  388. langchain/output_parsers/openai_functions.py +3 -3
  389. langchain/output_parsers/openai_tools.py +1 -1
  390. langchain/output_parsers/pandas_dataframe.py +43 -47
  391. langchain/output_parsers/prompts.py +1 -2
  392. langchain/output_parsers/rail_parser.py +1 -1
  393. langchain/output_parsers/regex.py +7 -8
  394. langchain/output_parsers/regex_dict.py +7 -10
  395. langchain/output_parsers/retry.py +77 -78
  396. langchain/output_parsers/structured.py +11 -6
  397. langchain/output_parsers/yaml.py +15 -11
  398. langchain/prompts/__init__.py +5 -3
  399. langchain/prompts/base.py +5 -5
  400. langchain/prompts/chat.py +8 -8
  401. langchain/prompts/example_selector/__init__.py +3 -1
  402. langchain/prompts/example_selector/semantic_similarity.py +2 -2
  403. langchain/prompts/few_shot.py +1 -1
  404. langchain/prompts/loading.py +3 -3
  405. langchain/prompts/prompt.py +1 -1
  406. langchain/retrievers/__init__.py +5 -5
  407. langchain/retrievers/bedrock.py +2 -2
  408. langchain/retrievers/bm25.py +1 -1
  409. langchain/retrievers/contextual_compression.py +14 -8
  410. langchain/retrievers/docarray.py +1 -1
  411. langchain/retrievers/document_compressors/__init__.py +5 -4
  412. langchain/retrievers/document_compressors/base.py +12 -6
  413. langchain/retrievers/document_compressors/chain_extract.py +2 -2
  414. langchain/retrievers/document_compressors/chain_extract_prompt.py +2 -3
  415. langchain/retrievers/document_compressors/chain_filter.py +9 -9
  416. langchain/retrievers/document_compressors/chain_filter_prompt.py +1 -2
  417. langchain/retrievers/document_compressors/cohere_rerank.py +15 -15
  418. langchain/retrievers/document_compressors/embeddings_filter.py +21 -17
  419. langchain/retrievers/document_compressors/flashrank_rerank.py +1 -1
  420. langchain/retrievers/document_compressors/listwise_rerank.py +7 -5
  421. langchain/retrievers/ensemble.py +28 -25
  422. langchain/retrievers/google_cloud_documentai_warehouse.py +1 -1
  423. langchain/retrievers/google_vertex_ai_search.py +2 -2
  424. langchain/retrievers/kendra.py +10 -10
  425. langchain/retrievers/llama_index.py +1 -1
  426. langchain/retrievers/merger_retriever.py +11 -11
  427. langchain/retrievers/milvus.py +1 -1
  428. langchain/retrievers/multi_query.py +32 -26
  429. langchain/retrievers/multi_vector.py +20 -8
  430. langchain/retrievers/parent_document_retriever.py +18 -9
  431. langchain/retrievers/re_phraser.py +6 -5
  432. langchain/retrievers/self_query/base.py +138 -127
  433. langchain/retrievers/time_weighted_retriever.py +18 -7
  434. langchain/retrievers/zilliz.py +1 -1
  435. langchain/runnables/openai_functions.py +6 -2
  436. langchain/schema/__init__.py +23 -23
  437. langchain/schema/cache.py +1 -1
  438. langchain/schema/callbacks/base.py +7 -7
  439. langchain/schema/callbacks/manager.py +19 -19
  440. langchain/schema/callbacks/tracers/base.py +1 -1
  441. langchain/schema/callbacks/tracers/evaluation.py +1 -1
  442. langchain/schema/callbacks/tracers/langchain.py +1 -1
  443. langchain/schema/callbacks/tracers/langchain_v1.py +1 -1
  444. langchain/schema/callbacks/tracers/log_stream.py +1 -1
  445. langchain/schema/callbacks/tracers/schemas.py +8 -8
  446. langchain/schema/callbacks/tracers/stdout.py +3 -3
  447. langchain/schema/document.py +1 -1
  448. langchain/schema/language_model.py +2 -2
  449. langchain/schema/messages.py +12 -12
  450. langchain/schema/output.py +3 -3
  451. langchain/schema/output_parser.py +3 -3
  452. langchain/schema/runnable/__init__.py +3 -3
  453. langchain/schema/runnable/base.py +9 -9
  454. langchain/schema/runnable/config.py +5 -5
  455. langchain/schema/runnable/configurable.py +1 -1
  456. langchain/schema/runnable/history.py +1 -1
  457. langchain/schema/runnable/passthrough.py +1 -1
  458. langchain/schema/runnable/utils.py +16 -16
  459. langchain/schema/vectorstore.py +1 -1
  460. langchain/smith/__init__.py +1 -1
  461. langchain/smith/evaluation/__init__.py +2 -2
  462. langchain/smith/evaluation/config.py +10 -7
  463. langchain/smith/evaluation/name_generation.py +3 -3
  464. langchain/smith/evaluation/progress.py +11 -2
  465. langchain/smith/evaluation/runner_utils.py +179 -127
  466. langchain/smith/evaluation/string_run_evaluator.py +75 -68
  467. langchain/storage/__init__.py +2 -2
  468. langchain/storage/_lc_store.py +4 -2
  469. langchain/storage/encoder_backed.py +6 -2
  470. langchain/storage/file_system.py +19 -16
  471. langchain/storage/in_memory.py +1 -1
  472. langchain/storage/upstash_redis.py +1 -1
  473. langchain/text_splitter.py +15 -15
  474. langchain/tools/__init__.py +28 -26
  475. langchain/tools/ainetwork/app.py +1 -1
  476. langchain/tools/ainetwork/base.py +1 -1
  477. langchain/tools/ainetwork/owner.py +1 -1
  478. langchain/tools/ainetwork/rule.py +1 -1
  479. langchain/tools/ainetwork/transfer.py +1 -1
  480. langchain/tools/ainetwork/value.py +1 -1
  481. langchain/tools/amadeus/closest_airport.py +1 -1
  482. langchain/tools/amadeus/flight_search.py +1 -1
  483. langchain/tools/azure_cognitive_services/__init__.py +1 -1
  484. langchain/tools/base.py +4 -4
  485. langchain/tools/bearly/tool.py +1 -1
  486. langchain/tools/bing_search/__init__.py +1 -1
  487. langchain/tools/bing_search/tool.py +1 -1
  488. langchain/tools/dataforseo_api_search/__init__.py +1 -1
  489. langchain/tools/dataforseo_api_search/tool.py +1 -1
  490. langchain/tools/ddg_search/tool.py +1 -1
  491. langchain/tools/e2b_data_analysis/tool.py +2 -2
  492. langchain/tools/edenai/__init__.py +1 -1
  493. langchain/tools/file_management/__init__.py +1 -1
  494. langchain/tools/file_management/copy.py +1 -1
  495. langchain/tools/file_management/delete.py +1 -1
  496. langchain/tools/gmail/__init__.py +2 -2
  497. langchain/tools/gmail/get_message.py +1 -1
  498. langchain/tools/gmail/search.py +1 -1
  499. langchain/tools/gmail/send_message.py +1 -1
  500. langchain/tools/google_finance/__init__.py +1 -1
  501. langchain/tools/google_finance/tool.py +1 -1
  502. langchain/tools/google_scholar/__init__.py +1 -1
  503. langchain/tools/google_scholar/tool.py +1 -1
  504. langchain/tools/google_search/__init__.py +1 -1
  505. langchain/tools/google_search/tool.py +1 -1
  506. langchain/tools/google_serper/__init__.py +1 -1
  507. langchain/tools/google_serper/tool.py +1 -1
  508. langchain/tools/google_trends/__init__.py +1 -1
  509. langchain/tools/google_trends/tool.py +1 -1
  510. langchain/tools/jira/tool.py +20 -1
  511. langchain/tools/json/tool.py +25 -3
  512. langchain/tools/memorize/tool.py +1 -1
  513. langchain/tools/multion/__init__.py +1 -1
  514. langchain/tools/multion/update_session.py +1 -1
  515. langchain/tools/office365/__init__.py +2 -2
  516. langchain/tools/office365/events_search.py +1 -1
  517. langchain/tools/office365/messages_search.py +1 -1
  518. langchain/tools/office365/send_event.py +1 -1
  519. langchain/tools/office365/send_message.py +1 -1
  520. langchain/tools/openapi/utils/api_models.py +6 -6
  521. langchain/tools/playwright/__init__.py +5 -5
  522. langchain/tools/playwright/click.py +1 -1
  523. langchain/tools/playwright/extract_hyperlinks.py +1 -1
  524. langchain/tools/playwright/get_elements.py +1 -1
  525. langchain/tools/playwright/navigate.py +1 -1
  526. langchain/tools/plugin.py +2 -2
  527. langchain/tools/powerbi/tool.py +1 -1
  528. langchain/tools/python/__init__.py +2 -1
  529. langchain/tools/reddit_search/tool.py +1 -1
  530. langchain/tools/render.py +2 -2
  531. langchain/tools/requests/tool.py +2 -2
  532. langchain/tools/searchapi/tool.py +1 -1
  533. langchain/tools/searx_search/tool.py +1 -1
  534. langchain/tools/slack/get_message.py +1 -1
  535. langchain/tools/spark_sql/tool.py +1 -1
  536. langchain/tools/sql_database/tool.py +1 -1
  537. langchain/tools/tavily_search/__init__.py +1 -1
  538. langchain/tools/tavily_search/tool.py +1 -1
  539. langchain/tools/zapier/__init__.py +1 -1
  540. langchain/tools/zapier/tool.py +24 -2
  541. langchain/utilities/__init__.py +4 -4
  542. langchain/utilities/arcee.py +4 -4
  543. langchain/utilities/clickup.py +4 -4
  544. langchain/utilities/dalle_image_generator.py +1 -1
  545. langchain/utilities/dataforseo_api_search.py +1 -1
  546. langchain/utilities/opaqueprompts.py +1 -1
  547. langchain/utilities/reddit_search.py +1 -1
  548. langchain/utilities/sql_database.py +1 -1
  549. langchain/utilities/tavily_search.py +1 -1
  550. langchain/utilities/vertexai.py +2 -2
  551. langchain/utils/__init__.py +1 -1
  552. langchain/utils/aiter.py +1 -1
  553. langchain/utils/html.py +3 -3
  554. langchain/utils/input.py +1 -1
  555. langchain/utils/iter.py +1 -1
  556. langchain/utils/json_schema.py +1 -3
  557. langchain/utils/strings.py +1 -1
  558. langchain/utils/utils.py +6 -6
  559. langchain/vectorstores/__init__.py +5 -5
  560. langchain/vectorstores/alibabacloud_opensearch.py +1 -1
  561. langchain/vectorstores/azure_cosmos_db.py +1 -1
  562. langchain/vectorstores/clickhouse.py +1 -1
  563. langchain/vectorstores/elastic_vector_search.py +1 -1
  564. langchain/vectorstores/elasticsearch.py +2 -2
  565. langchain/vectorstores/myscale.py +1 -1
  566. langchain/vectorstores/neo4j_vector.py +1 -1
  567. langchain/vectorstores/pgembedding.py +1 -1
  568. langchain/vectorstores/qdrant.py +1 -1
  569. langchain/vectorstores/redis/__init__.py +1 -1
  570. langchain/vectorstores/redis/base.py +1 -1
  571. langchain/vectorstores/redis/filters.py +4 -4
  572. langchain/vectorstores/redis/schema.py +6 -6
  573. langchain/vectorstores/sklearn.py +2 -2
  574. langchain/vectorstores/starrocks.py +1 -1
  575. langchain/vectorstores/utils.py +1 -1
  576. {langchain-0.3.26.dist-info → langchain-0.3.27.dist-info}/METADATA +4 -4
  577. {langchain-0.3.26.dist-info → langchain-0.3.27.dist-info}/RECORD +580 -580
  578. {langchain-0.3.26.dist-info → langchain-0.3.27.dist-info}/WHEEL +1 -1
  579. {langchain-0.3.26.dist-info → langchain-0.3.27.dist-info}/entry_points.txt +0 -0
  580. {langchain-0.3.26.dist-info → langchain-0.3.27.dist-info}/licenses/LICENSE +0 -0
@@ -20,7 +20,7 @@ from langchain_core.runnables import RunnableConfig, RunnableSerializable, ensur
20
20
  from langchain_core.tools import BaseTool
21
21
  from langchain_core.utils.function_calling import convert_to_openai_tool
22
22
  from pydantic import BaseModel, Field, model_validator
23
- from typing_extensions import Self
23
+ from typing_extensions import Self, override
24
24
 
25
25
  if TYPE_CHECKING:
26
26
  import openai
@@ -80,14 +80,14 @@ def _get_openai_client() -> openai.OpenAI:
80
80
 
81
81
  return openai.OpenAI()
82
82
  except ImportError as e:
83
- raise ImportError(
84
- "Unable to import openai, please install with `pip install openai`."
85
- ) from e
83
+ msg = "Unable to import openai, please install with `pip install openai`."
84
+ raise ImportError(msg) from e
86
85
  except AttributeError as e:
87
- raise AttributeError(
86
+ msg = (
88
87
  "Please make sure you are using a v1.1-compatible version of openai. You "
89
88
  'can install with `pip install "openai>=1.1"`.'
90
- ) from e
89
+ )
90
+ raise AttributeError(msg) from e
91
91
 
92
92
 
93
93
  def _get_openai_async_client() -> openai.AsyncOpenAI:
@@ -96,14 +96,14 @@ def _get_openai_async_client() -> openai.AsyncOpenAI:
96
96
 
97
97
  return openai.AsyncOpenAI()
98
98
  except ImportError as e:
99
- raise ImportError(
100
- "Unable to import openai, please install with `pip install openai`."
101
- ) from e
99
+ msg = "Unable to import openai, please install with `pip install openai`."
100
+ raise ImportError(msg) from e
102
101
  except AttributeError as e:
103
- raise AttributeError(
102
+ msg = (
104
103
  "Please make sure you are using a v1.1-compatible version of openai. You "
105
104
  'can install with `pip install "openai>=1.1"`.'
106
- ) from e
105
+ )
106
+ raise AttributeError(msg) from e
107
107
 
108
108
 
109
109
  def _is_assistants_builtin_tool(
@@ -128,8 +128,7 @@ def _get_assistants_tool(
128
128
  """
129
129
  if _is_assistants_builtin_tool(tool):
130
130
  return tool # type: ignore[return-value]
131
- else:
132
- return convert_to_openai_tool(tool)
131
+ return convert_to_openai_tool(tool)
133
132
 
134
133
 
135
134
  OutputType = Union[
@@ -272,8 +271,12 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
272
271
  )
273
272
  return cls(assistant_id=assistant.id, client=client, **kwargs)
274
273
 
274
+ @override
275
275
  def invoke(
276
- self, input: dict, config: Optional[RunnableConfig] = None, **kwargs: Any
276
+ self,
277
+ input: dict,
278
+ config: Optional[RunnableConfig] = None,
279
+ **kwargs: Any,
277
280
  ) -> OutputType:
278
281
  """Invoke assistant.
279
282
 
@@ -314,13 +317,15 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
314
317
  inheritable_metadata=config.get("metadata"),
315
318
  )
316
319
  run_manager = callback_manager.on_chain_start(
317
- dumpd(self), input, name=config.get("run_name") or self.get_name()
320
+ dumpd(self),
321
+ input,
322
+ name=config.get("run_name") or self.get_name(),
318
323
  )
319
324
  try:
320
325
  # Being run within AgentExecutor and there are tool outputs to submit.
321
326
  if self.as_agent and input.get("intermediate_steps"):
322
327
  tool_outputs = self._parse_intermediate_steps(
323
- input["intermediate_steps"]
328
+ input["intermediate_steps"],
324
329
  )
325
330
  run = self.client.beta.threads.runs.submit_tool_outputs(**tool_outputs)
326
331
  # Starting a new thread and a new run.
@@ -332,7 +337,7 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
332
337
  "content": input["content"],
333
338
  "metadata": input.get("message_metadata"),
334
339
  "attachments": input.get("attachments"),
335
- }
340
+ },
336
341
  ],
337
342
  "metadata": input.get("thread_metadata"),
338
343
  }
@@ -353,12 +358,12 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
353
358
  run = self._wait_for_run(run.id, run.thread_id)
354
359
  except BaseException as e:
355
360
  run_manager.on_chain_error(e)
356
- raise e
361
+ raise
357
362
  try:
358
363
  response = self._get_response(run)
359
364
  except BaseException as e:
360
365
  run_manager.on_chain_error(e, metadata=run.dict())
361
- raise e
366
+ raise
362
367
  else:
363
368
  run_manager.on_chain_end(response)
364
369
  return response
@@ -399,8 +404,12 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
399
404
  )
400
405
  return cls(assistant_id=assistant.id, async_client=async_client, **kwargs)
401
406
 
407
+ @override
402
408
  async def ainvoke(
403
- self, input: dict, config: Optional[RunnableConfig] = None, **kwargs: Any
409
+ self,
410
+ input: dict,
411
+ config: Optional[RunnableConfig] = None,
412
+ **kwargs: Any,
404
413
  ) -> OutputType:
405
414
  """Async invoke assistant.
406
415
 
@@ -441,16 +450,18 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
441
450
  inheritable_metadata=config.get("metadata"),
442
451
  )
443
452
  run_manager = callback_manager.on_chain_start(
444
- dumpd(self), input, name=config.get("run_name") or self.get_name()
453
+ dumpd(self),
454
+ input,
455
+ name=config.get("run_name") or self.get_name(),
445
456
  )
446
457
  try:
447
458
  # Being run within AgentExecutor and there are tool outputs to submit.
448
459
  if self.as_agent and input.get("intermediate_steps"):
449
460
  tool_outputs = await self._aparse_intermediate_steps(
450
- input["intermediate_steps"]
461
+ input["intermediate_steps"],
451
462
  )
452
463
  run = await self.async_client.beta.threads.runs.submit_tool_outputs(
453
- **tool_outputs
464
+ **tool_outputs,
454
465
  )
455
466
  # Starting a new thread and a new run.
456
467
  elif "thread_id" not in input:
@@ -460,7 +471,7 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
460
471
  "role": "user",
461
472
  "content": input["content"],
462
473
  "metadata": input.get("message_metadata"),
463
- }
474
+ },
464
475
  ],
465
476
  "metadata": input.get("thread_metadata"),
466
477
  }
@@ -478,23 +489,24 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
478
489
  # framework.
479
490
  else:
480
491
  run = await self.async_client.beta.threads.runs.submit_tool_outputs(
481
- **input
492
+ **input,
482
493
  )
483
494
  run = await self._await_for_run(run.id, run.thread_id)
484
495
  except BaseException as e:
485
496
  run_manager.on_chain_error(e)
486
- raise e
497
+ raise
487
498
  try:
488
499
  response = self._get_response(run)
489
500
  except BaseException as e:
490
501
  run_manager.on_chain_error(e, metadata=run.dict())
491
- raise e
502
+ raise
492
503
  else:
493
504
  run_manager.on_chain_end(response)
494
505
  return response
495
506
 
496
507
  def _parse_intermediate_steps(
497
- self, intermediate_steps: list[tuple[OpenAIAssistantAction, str]]
508
+ self,
509
+ intermediate_steps: list[tuple[OpenAIAssistantAction, str]],
498
510
  ) -> dict:
499
511
  last_action, last_output = intermediate_steps[-1]
500
512
  run = self._wait_for_run(last_action.run_id, last_action.thread_id)
@@ -508,17 +520,16 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
508
520
  for action, output in intermediate_steps
509
521
  if action.tool_call_id in required_tool_call_ids
510
522
  ]
511
- submit_tool_outputs = {
523
+ return {
512
524
  "tool_outputs": tool_outputs,
513
525
  "run_id": last_action.run_id,
514
526
  "thread_id": last_action.thread_id,
515
527
  }
516
- return submit_tool_outputs
517
528
 
518
- def _create_run(self, input: dict) -> Any:
529
+ def _create_run(self, input_dict: dict) -> Any:
519
530
  params = {
520
531
  k: v
521
- for k, v in input.items()
532
+ for k, v in input_dict.items()
522
533
  if k
523
534
  in (
524
535
  "instructions",
@@ -534,15 +545,15 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
534
545
  )
535
546
  }
536
547
  return self.client.beta.threads.runs.create(
537
- input["thread_id"],
548
+ input_dict["thread_id"],
538
549
  assistant_id=self.assistant_id,
539
550
  **params,
540
551
  )
541
552
 
542
- def _create_thread_and_run(self, input: dict, thread: dict) -> Any:
553
+ def _create_thread_and_run(self, input_dict: dict, thread: dict) -> Any:
543
554
  params = {
544
555
  k: v
545
- for k, v in input.items()
556
+ for k, v in input_dict.items()
546
557
  if k
547
558
  in (
548
559
  "instructions",
@@ -556,12 +567,11 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
556
567
  "run_metadata",
557
568
  )
558
569
  }
559
- run = self.client.beta.threads.create_and_run(
570
+ return self.client.beta.threads.create_and_run(
560
571
  assistant_id=self.assistant_id,
561
572
  thread=thread,
562
573
  **params,
563
574
  )
564
- return run
565
575
 
566
576
  def _get_response(self, run: Any) -> Any:
567
577
  # TODO: Pagination
@@ -572,11 +582,12 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
572
582
  major_version = int(openai.version.VERSION.split(".")[0])
573
583
  minor_version = int(openai.version.VERSION.split(".")[1])
574
584
  version_gte_1_14 = (major_version > 1) or (
575
- major_version == 1 and minor_version >= 14
585
+ major_version == 1 and minor_version >= 14 # noqa: PLR2004
576
586
  )
577
587
 
578
588
  messages = self.client.beta.threads.messages.list(
579
- run.thread_id, order="asc"
589
+ run.thread_id,
590
+ order="asc",
580
591
  )
581
592
  new_messages = [msg for msg in messages if msg.run_id == run.id]
582
593
  if not self.as_agent:
@@ -610,7 +621,7 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
610
621
  run_id=run.id,
611
622
  thread_id=run.thread_id,
612
623
  )
613
- elif run.status == "requires_action":
624
+ if run.status == "requires_action":
614
625
  if not self.as_agent:
615
626
  return run.required_action.submit_tool_outputs.tool_calls
616
627
  actions = []
@@ -619,10 +630,11 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
619
630
  try:
620
631
  args = json.loads(function.arguments, strict=False)
621
632
  except JSONDecodeError as e:
622
- raise ValueError(
633
+ msg = (
623
634
  f"Received invalid JSON function arguments: "
624
635
  f"{function.arguments} for function {function.name}"
625
- ) from e
636
+ )
637
+ raise ValueError(msg) from e
626
638
  if len(args) == 1 and "__arg1" in args:
627
639
  args = args["__arg1"]
628
640
  actions.append(
@@ -633,14 +645,12 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
633
645
  log="",
634
646
  run_id=run.id,
635
647
  thread_id=run.thread_id,
636
- )
648
+ ),
637
649
  )
638
650
  return actions
639
- else:
640
- run_info = json.dumps(run.dict(), indent=2)
641
- raise ValueError(
642
- f"Unexpected run status: {run.status}. Full run info:\n\n{run_info})"
643
- )
651
+ run_info = json.dumps(run.dict(), indent=2)
652
+ msg = f"Unexpected run status: {run.status}. Full run info:\n\n{run_info}"
653
+ raise ValueError(msg)
644
654
 
645
655
  def _wait_for_run(self, run_id: str, thread_id: str) -> Any:
646
656
  in_progress = True
@@ -652,7 +662,8 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
652
662
  return run
653
663
 
654
664
  async def _aparse_intermediate_steps(
655
- self, intermediate_steps: list[tuple[OpenAIAssistantAction, str]]
665
+ self,
666
+ intermediate_steps: list[tuple[OpenAIAssistantAction, str]],
656
667
  ) -> dict:
657
668
  last_action, last_output = intermediate_steps[-1]
658
669
  run = self._wait_for_run(last_action.run_id, last_action.thread_id)
@@ -666,17 +677,16 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
666
677
  for action, output in intermediate_steps
667
678
  if action.tool_call_id in required_tool_call_ids
668
679
  ]
669
- submit_tool_outputs = {
680
+ return {
670
681
  "tool_outputs": tool_outputs,
671
682
  "run_id": last_action.run_id,
672
683
  "thread_id": last_action.thread_id,
673
684
  }
674
- return submit_tool_outputs
675
685
 
676
- async def _acreate_run(self, input: dict) -> Any:
686
+ async def _acreate_run(self, input_dict: dict) -> Any:
677
687
  params = {
678
688
  k: v
679
- for k, v in input.items()
689
+ for k, v in input_dict.items()
680
690
  if k
681
691
  in (
682
692
  "instructions",
@@ -692,15 +702,15 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
692
702
  )
693
703
  }
694
704
  return await self.async_client.beta.threads.runs.create(
695
- input["thread_id"],
705
+ input_dict["thread_id"],
696
706
  assistant_id=self.assistant_id,
697
707
  **params,
698
708
  )
699
709
 
700
- async def _acreate_thread_and_run(self, input: dict, thread: dict) -> Any:
710
+ async def _acreate_thread_and_run(self, input_dict: dict, thread: dict) -> Any:
701
711
  params = {
702
712
  k: v
703
- for k, v in input.items()
713
+ for k, v in input_dict.items()
704
714
  if k
705
715
  in (
706
716
  "instructions",
@@ -714,12 +724,11 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
714
724
  "run_metadata",
715
725
  )
716
726
  }
717
- run = await self.async_client.beta.threads.create_and_run(
727
+ return await self.async_client.beta.threads.create_and_run(
718
728
  assistant_id=self.assistant_id,
719
729
  thread=thread,
720
730
  **params,
721
731
  )
722
- return run
723
732
 
724
733
  async def _aget_response(self, run: Any) -> Any:
725
734
  # TODO: Pagination
@@ -730,11 +739,12 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
730
739
  major_version = int(openai.version.VERSION.split(".")[0])
731
740
  minor_version = int(openai.version.VERSION.split(".")[1])
732
741
  version_gte_1_14 = (major_version > 1) or (
733
- major_version == 1 and minor_version >= 14
742
+ major_version == 1 and minor_version >= 14 # noqa: PLR2004
734
743
  )
735
744
 
736
745
  messages = await self.async_client.beta.threads.messages.list(
737
- run.thread_id, order="asc"
746
+ run.thread_id,
747
+ order="asc",
738
748
  )
739
749
  new_messages = [msg for msg in messages if msg.run_id == run.id]
740
750
  if not self.as_agent:
@@ -764,7 +774,7 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
764
774
  run_id=run.id,
765
775
  thread_id=run.thread_id,
766
776
  )
767
- elif run.status == "requires_action":
777
+ if run.status == "requires_action":
768
778
  if not self.as_agent:
769
779
  return run.required_action.submit_tool_outputs.tool_calls
770
780
  actions = []
@@ -773,10 +783,11 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
773
783
  try:
774
784
  args = json.loads(function.arguments, strict=False)
775
785
  except JSONDecodeError as e:
776
- raise ValueError(
786
+ msg = (
777
787
  f"Received invalid JSON function arguments: "
778
788
  f"{function.arguments} for function {function.name}"
779
- ) from e
789
+ )
790
+ raise ValueError(msg) from e
780
791
  if len(args) == 1 and "__arg1" in args:
781
792
  args = args["__arg1"]
782
793
  actions.append(
@@ -787,20 +798,19 @@ class OpenAIAssistantRunnable(RunnableSerializable[dict, OutputType]):
787
798
  log="",
788
799
  run_id=run.id,
789
800
  thread_id=run.thread_id,
790
- )
801
+ ),
791
802
  )
792
803
  return actions
793
- else:
794
- run_info = json.dumps(run.dict(), indent=2)
795
- raise ValueError(
796
- f"Unexpected run status: {run.status}. Full run info:\n\n{run_info})"
797
- )
804
+ run_info = json.dumps(run.dict(), indent=2)
805
+ msg = f"Unexpected run status: {run.status}. Full run info:\n\n{run_info}"
806
+ raise ValueError(msg)
798
807
 
799
808
  async def _await_for_run(self, run_id: str, thread_id: str) -> Any:
800
809
  in_progress = True
801
810
  while in_progress:
802
811
  run = await self.async_client.beta.threads.runs.retrieve(
803
- run_id, thread_id=thread_id
812
+ run_id,
813
+ thread_id=thread_id,
804
814
  )
805
815
  in_progress = run.status in ("in_progress", "queued")
806
816
  if in_progress:
@@ -32,6 +32,8 @@ from langchain.agents.output_parsers.openai_functions import (
32
32
  OpenAIFunctionsAgentOutputParser,
33
33
  )
34
34
 
35
+ _NOT_SET = object()
36
+
35
37
 
36
38
  @deprecated("0.1.0", alternative="create_openai_functions_agent", removal="1.0")
37
39
  class OpenAIFunctionsAgent(BaseSingleActionAgent):
@@ -75,10 +77,11 @@ class OpenAIFunctionsAgent(BaseSingleActionAgent):
75
77
  """
76
78
  prompt: BasePromptTemplate = self.prompt
77
79
  if "agent_scratchpad" not in prompt.input_variables:
78
- raise ValueError(
80
+ msg = (
79
81
  "`agent_scratchpad` should be one of the variables in the prompt, "
80
82
  f"got {prompt.input_variables}"
81
83
  )
84
+ raise ValueError(msg)
82
85
  return self
83
86
 
84
87
  @property
@@ -96,7 +99,7 @@ class OpenAIFunctionsAgent(BaseSingleActionAgent):
96
99
  self,
97
100
  intermediate_steps: list[tuple[AgentAction, str]],
98
101
  callbacks: Callbacks = None,
99
- with_functions: bool = True,
102
+ with_functions: bool = True, # noqa: FBT001,FBT002
100
103
  **kwargs: Any,
101
104
  ) -> Union[AgentAction, AgentFinish]:
102
105
  """Given input, decided what to do.
@@ -131,8 +134,7 @@ class OpenAIFunctionsAgent(BaseSingleActionAgent):
131
134
  messages,
132
135
  callbacks=callbacks,
133
136
  )
134
- agent_decision = self.output_parser._parse_ai_message(predicted_message)
135
- return agent_decision
137
+ return self.output_parser._parse_ai_message(predicted_message)
136
138
 
137
139
  async def aplan(
138
140
  self,
@@ -161,10 +163,11 @@ class OpenAIFunctionsAgent(BaseSingleActionAgent):
161
163
  prompt = self.prompt.format_prompt(**full_inputs)
162
164
  messages = prompt.to_messages()
163
165
  predicted_message = await self.llm.apredict_messages(
164
- messages, functions=self.functions, callbacks=callbacks
166
+ messages,
167
+ functions=self.functions,
168
+ callbacks=callbacks,
165
169
  )
166
- agent_decision = self.output_parser._parse_ai_message(predicted_message)
167
- return agent_decision
170
+ return self.output_parser._parse_ai_message(predicted_message)
168
171
 
169
172
  def return_stopped_response(
170
173
  self,
@@ -189,31 +192,30 @@ class OpenAIFunctionsAgent(BaseSingleActionAgent):
189
192
  if early_stopping_method == "force":
190
193
  # `force` just returns a constant string
191
194
  return AgentFinish(
192
- {"output": "Agent stopped due to iteration limit or time limit."}, ""
195
+ {"output": "Agent stopped due to iteration limit or time limit."},
196
+ "",
193
197
  )
194
- elif early_stopping_method == "generate":
198
+ if early_stopping_method == "generate":
195
199
  # Generate does one final forward pass
196
200
  agent_decision = self.plan(
197
- intermediate_steps, with_functions=False, **kwargs
201
+ intermediate_steps,
202
+ with_functions=False,
203
+ **kwargs,
198
204
  )
199
205
  if isinstance(agent_decision, AgentFinish):
200
206
  return agent_decision
201
- else:
202
- raise ValueError(
203
- f"got AgentAction with no functions provided: {agent_decision}"
204
- )
205
- else:
206
- raise ValueError(
207
- "early_stopping_method should be one of `force` or `generate`, "
208
- f"got {early_stopping_method}"
209
- )
207
+ msg = f"got AgentAction with no functions provided: {agent_decision}"
208
+ raise ValueError(msg)
209
+ msg = (
210
+ "early_stopping_method should be one of `force` or `generate`, "
211
+ f"got {early_stopping_method}"
212
+ )
213
+ raise ValueError(msg)
210
214
 
211
215
  @classmethod
212
216
  def create_prompt(
213
217
  cls,
214
- system_message: Optional[SystemMessage] = SystemMessage(
215
- content="You are a helpful AI assistant."
216
- ),
218
+ system_message: Optional[SystemMessage] = _NOT_SET, # type: ignore[assignment]
217
219
  extra_prompt_messages: Optional[list[BaseMessagePromptTemplate]] = None,
218
220
  ) -> ChatPromptTemplate:
219
221
  """Create prompt for this agent.
@@ -228,18 +230,20 @@ class OpenAIFunctionsAgent(BaseSingleActionAgent):
228
230
  A prompt template to pass into this agent.
229
231
  """
230
232
  _prompts = extra_prompt_messages or []
233
+ system_message_ = (
234
+ system_message
235
+ if system_message is not _NOT_SET
236
+ else SystemMessage(content="You are a helpful AI assistant.")
237
+ )
231
238
  messages: list[Union[BaseMessagePromptTemplate, BaseMessage]]
232
- if system_message:
233
- messages = [system_message]
234
- else:
235
- messages = []
239
+ messages = [system_message_] if system_message_ else []
236
240
 
237
241
  messages.extend(
238
242
  [
239
243
  *_prompts,
240
244
  HumanMessagePromptTemplate.from_template("{input}"),
241
245
  MessagesPlaceholder(variable_name="agent_scratchpad"),
242
- ]
246
+ ],
243
247
  )
244
248
  return ChatPromptTemplate(messages=messages)
245
249
 
@@ -250,9 +254,7 @@ class OpenAIFunctionsAgent(BaseSingleActionAgent):
250
254
  tools: Sequence[BaseTool],
251
255
  callback_manager: Optional[BaseCallbackManager] = None,
252
256
  extra_prompt_messages: Optional[list[BaseMessagePromptTemplate]] = None,
253
- system_message: Optional[SystemMessage] = SystemMessage(
254
- content="You are a helpful AI assistant."
255
- ),
257
+ system_message: Optional[SystemMessage] = _NOT_SET, # type: ignore[assignment]
256
258
  **kwargs: Any,
257
259
  ) -> BaseSingleActionAgent:
258
260
  """Construct an agent from an LLM and tools.
@@ -266,9 +268,14 @@ class OpenAIFunctionsAgent(BaseSingleActionAgent):
266
268
  Defaults to a default system message.
267
269
  kwargs: Additional parameters to pass to the agent.
268
270
  """
271
+ system_message_ = (
272
+ system_message
273
+ if system_message is not _NOT_SET
274
+ else SystemMessage(content="You are a helpful AI assistant.")
275
+ )
269
276
  prompt = cls.create_prompt(
270
277
  extra_prompt_messages=extra_prompt_messages,
271
- system_message=system_message,
278
+ system_message=system_message_,
272
279
  )
273
280
  return cls( # type: ignore[call-arg]
274
281
  llm=llm,
@@ -280,7 +287,9 @@ class OpenAIFunctionsAgent(BaseSingleActionAgent):
280
287
 
281
288
 
282
289
  def create_openai_functions_agent(
283
- llm: BaseLanguageModel, tools: Sequence[BaseTool], prompt: ChatPromptTemplate
290
+ llm: BaseLanguageModel,
291
+ tools: Sequence[BaseTool],
292
+ prompt: ChatPromptTemplate,
284
293
  ) -> Runnable:
285
294
  """Create an agent that uses OpenAI function calling.
286
295
 
@@ -354,19 +363,19 @@ def create_openai_functions_agent(
354
363
  if "agent_scratchpad" not in (
355
364
  prompt.input_variables + list(prompt.partial_variables)
356
365
  ):
357
- raise ValueError(
366
+ msg = (
358
367
  "Prompt must have input variable `agent_scratchpad`, but wasn't found. "
359
368
  f"Found {prompt.input_variables} instead."
360
369
  )
370
+ raise ValueError(msg)
361
371
  llm_with_tools = llm.bind(functions=[convert_to_openai_function(t) for t in tools])
362
- agent = (
372
+ return (
363
373
  RunnablePassthrough.assign(
364
374
  agent_scratchpad=lambda x: format_to_openai_function_messages(
365
- x["intermediate_steps"]
366
- )
375
+ x["intermediate_steps"],
376
+ ),
367
377
  )
368
378
  | prompt
369
379
  | llm_with_tools
370
380
  | OpenAIFunctionsAgentOutputParser()
371
381
  )
372
- return agent