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.
- langchain/__init__.py +110 -96
- langchain/_api/__init__.py +2 -2
- langchain/_api/deprecation.py +3 -3
- langchain/_api/module_import.py +51 -46
- langchain/_api/path.py +1 -1
- langchain/adapters/openai.py +8 -8
- langchain/agents/__init__.py +15 -12
- langchain/agents/agent.py +174 -151
- langchain/agents/agent_iterator.py +50 -26
- langchain/agents/agent_toolkits/__init__.py +7 -6
- langchain/agents/agent_toolkits/ainetwork/toolkit.py +1 -1
- langchain/agents/agent_toolkits/amadeus/toolkit.py +1 -1
- langchain/agents/agent_toolkits/azure_cognitive_services.py +1 -1
- langchain/agents/agent_toolkits/clickup/toolkit.py +1 -1
- langchain/agents/agent_toolkits/conversational_retrieval/openai_functions.py +6 -4
- langchain/agents/agent_toolkits/csv/__init__.py +4 -2
- langchain/agents/agent_toolkits/file_management/__init__.py +1 -1
- langchain/agents/agent_toolkits/file_management/toolkit.py +1 -1
- langchain/agents/agent_toolkits/github/toolkit.py +9 -9
- langchain/agents/agent_toolkits/gitlab/toolkit.py +1 -1
- langchain/agents/agent_toolkits/json/base.py +1 -1
- langchain/agents/agent_toolkits/multion/toolkit.py +1 -1
- langchain/agents/agent_toolkits/office365/toolkit.py +1 -1
- langchain/agents/agent_toolkits/openapi/base.py +1 -1
- langchain/agents/agent_toolkits/openapi/planner.py +2 -2
- langchain/agents/agent_toolkits/openapi/planner_prompt.py +10 -10
- langchain/agents/agent_toolkits/openapi/prompt.py +1 -1
- langchain/agents/agent_toolkits/openapi/toolkit.py +1 -1
- langchain/agents/agent_toolkits/pandas/__init__.py +4 -2
- langchain/agents/agent_toolkits/playwright/__init__.py +1 -1
- langchain/agents/agent_toolkits/playwright/toolkit.py +1 -1
- langchain/agents/agent_toolkits/powerbi/base.py +1 -1
- langchain/agents/agent_toolkits/powerbi/chat_base.py +1 -1
- langchain/agents/agent_toolkits/powerbi/prompt.py +2 -2
- langchain/agents/agent_toolkits/powerbi/toolkit.py +1 -1
- langchain/agents/agent_toolkits/python/__init__.py +4 -2
- langchain/agents/agent_toolkits/spark/__init__.py +4 -2
- langchain/agents/agent_toolkits/spark_sql/base.py +1 -1
- langchain/agents/agent_toolkits/spark_sql/toolkit.py +1 -1
- langchain/agents/agent_toolkits/sql/prompt.py +1 -1
- langchain/agents/agent_toolkits/sql/toolkit.py +1 -1
- langchain/agents/agent_toolkits/vectorstore/base.py +4 -2
- langchain/agents/agent_toolkits/vectorstore/prompt.py +2 -4
- langchain/agents/agent_toolkits/vectorstore/toolkit.py +12 -11
- langchain/agents/agent_toolkits/xorbits/__init__.py +4 -2
- langchain/agents/agent_toolkits/zapier/toolkit.py +1 -1
- langchain/agents/agent_types.py +6 -6
- langchain/agents/chat/base.py +8 -12
- langchain/agents/chat/output_parser.py +9 -6
- langchain/agents/chat/prompt.py +3 -4
- langchain/agents/conversational/base.py +11 -5
- langchain/agents/conversational/output_parser.py +4 -2
- langchain/agents/conversational/prompt.py +2 -3
- langchain/agents/conversational_chat/base.py +9 -5
- langchain/agents/conversational_chat/output_parser.py +9 -11
- langchain/agents/conversational_chat/prompt.py +5 -6
- langchain/agents/format_scratchpad/__init__.py +3 -3
- langchain/agents/format_scratchpad/log_to_messages.py +1 -1
- langchain/agents/format_scratchpad/openai_functions.py +8 -6
- langchain/agents/format_scratchpad/tools.py +5 -3
- langchain/agents/format_scratchpad/xml.py +33 -2
- langchain/agents/initialize.py +17 -9
- langchain/agents/json_chat/base.py +19 -18
- langchain/agents/json_chat/prompt.py +2 -3
- langchain/agents/load_tools.py +2 -1
- langchain/agents/loading.py +28 -18
- langchain/agents/mrkl/base.py +11 -4
- langchain/agents/mrkl/output_parser.py +17 -13
- langchain/agents/mrkl/prompt.py +1 -2
- langchain/agents/openai_assistant/base.py +81 -71
- langchain/agents/openai_functions_agent/agent_token_buffer_memory.py +2 -0
- langchain/agents/openai_functions_agent/base.py +47 -37
- langchain/agents/openai_functions_multi_agent/base.py +40 -27
- langchain/agents/openai_tools/base.py +9 -8
- langchain/agents/output_parsers/__init__.py +3 -3
- langchain/agents/output_parsers/json.py +8 -6
- langchain/agents/output_parsers/openai_functions.py +24 -9
- langchain/agents/output_parsers/openai_tools.py +16 -4
- langchain/agents/output_parsers/react_json_single_input.py +13 -5
- langchain/agents/output_parsers/react_single_input.py +18 -11
- langchain/agents/output_parsers/self_ask.py +5 -2
- langchain/agents/output_parsers/tools.py +32 -13
- langchain/agents/output_parsers/xml.py +102 -28
- langchain/agents/react/agent.py +5 -4
- langchain/agents/react/base.py +26 -17
- langchain/agents/react/output_parser.py +7 -6
- langchain/agents/react/textworld_prompt.py +0 -1
- langchain/agents/react/wiki_prompt.py +14 -15
- langchain/agents/schema.py +5 -2
- langchain/agents/self_ask_with_search/base.py +23 -15
- langchain/agents/self_ask_with_search/prompt.py +0 -1
- langchain/agents/structured_chat/base.py +19 -11
- langchain/agents/structured_chat/output_parser.py +29 -18
- langchain/agents/structured_chat/prompt.py +3 -4
- langchain/agents/tool_calling_agent/base.py +8 -6
- langchain/agents/tools.py +5 -2
- langchain/agents/utils.py +2 -3
- langchain/agents/xml/base.py +12 -6
- langchain/agents/xml/prompt.py +1 -2
- langchain/cache.py +12 -12
- langchain/callbacks/__init__.py +11 -11
- langchain/callbacks/aim_callback.py +2 -2
- langchain/callbacks/argilla_callback.py +1 -1
- langchain/callbacks/arize_callback.py +1 -1
- langchain/callbacks/arthur_callback.py +1 -1
- langchain/callbacks/base.py +7 -7
- langchain/callbacks/clearml_callback.py +1 -1
- langchain/callbacks/comet_ml_callback.py +1 -1
- langchain/callbacks/confident_callback.py +1 -1
- langchain/callbacks/context_callback.py +1 -1
- langchain/callbacks/flyte_callback.py +1 -1
- langchain/callbacks/human.py +2 -2
- langchain/callbacks/infino_callback.py +1 -1
- langchain/callbacks/labelstudio_callback.py +1 -1
- langchain/callbacks/llmonitor_callback.py +1 -1
- langchain/callbacks/manager.py +5 -5
- langchain/callbacks/mlflow_callback.py +2 -2
- langchain/callbacks/openai_info.py +1 -1
- langchain/callbacks/promptlayer_callback.py +1 -1
- langchain/callbacks/sagemaker_callback.py +1 -1
- langchain/callbacks/streaming_aiter.py +17 -3
- langchain/callbacks/streaming_aiter_final_only.py +16 -5
- langchain/callbacks/streaming_stdout_final_only.py +10 -3
- langchain/callbacks/streamlit/__init__.py +3 -2
- langchain/callbacks/streamlit/mutable_expander.py +1 -1
- langchain/callbacks/streamlit/streamlit_callback_handler.py +3 -3
- langchain/callbacks/tracers/__init__.py +1 -1
- langchain/callbacks/tracers/comet.py +1 -1
- langchain/callbacks/tracers/evaluation.py +1 -1
- langchain/callbacks/tracers/log_stream.py +1 -1
- langchain/callbacks/tracers/logging.py +12 -1
- langchain/callbacks/tracers/stdout.py +1 -1
- langchain/callbacks/trubrics_callback.py +1 -1
- langchain/callbacks/utils.py +4 -4
- langchain/callbacks/wandb_callback.py +1 -1
- langchain/callbacks/whylabs_callback.py +1 -1
- langchain/chains/api/base.py +41 -23
- langchain/chains/api/news_docs.py +1 -2
- langchain/chains/api/open_meteo_docs.py +1 -2
- langchain/chains/api/openapi/requests_chain.py +1 -1
- langchain/chains/api/openapi/response_chain.py +1 -1
- langchain/chains/api/podcast_docs.py +1 -2
- langchain/chains/api/prompt.py +1 -2
- langchain/chains/api/tmdb_docs.py +1 -2
- langchain/chains/base.py +96 -56
- langchain/chains/chat_vector_db/prompts.py +2 -3
- langchain/chains/combine_documents/__init__.py +1 -1
- langchain/chains/combine_documents/base.py +30 -11
- langchain/chains/combine_documents/map_reduce.py +41 -30
- langchain/chains/combine_documents/map_rerank.py +39 -24
- langchain/chains/combine_documents/reduce.py +48 -26
- langchain/chains/combine_documents/refine.py +27 -17
- langchain/chains/combine_documents/stuff.py +24 -13
- langchain/chains/constitutional_ai/base.py +11 -4
- langchain/chains/constitutional_ai/principles.py +22 -25
- langchain/chains/constitutional_ai/prompts.py +25 -28
- langchain/chains/conversation/base.py +9 -4
- langchain/chains/conversation/memory.py +5 -5
- langchain/chains/conversation/prompt.py +5 -5
- langchain/chains/conversational_retrieval/base.py +108 -79
- langchain/chains/conversational_retrieval/prompts.py +2 -3
- langchain/chains/elasticsearch_database/base.py +10 -10
- langchain/chains/elasticsearch_database/prompts.py +2 -3
- langchain/chains/ernie_functions/__init__.py +2 -2
- langchain/chains/example_generator.py +3 -1
- langchain/chains/flare/base.py +28 -12
- langchain/chains/flare/prompts.py +2 -0
- langchain/chains/graph_qa/cypher.py +2 -2
- langchain/chains/graph_qa/falkordb.py +1 -1
- langchain/chains/graph_qa/gremlin.py +1 -1
- langchain/chains/graph_qa/neptune_sparql.py +1 -1
- langchain/chains/graph_qa/prompts.py +2 -2
- langchain/chains/history_aware_retriever.py +2 -1
- langchain/chains/hyde/base.py +6 -5
- langchain/chains/hyde/prompts.py +5 -6
- langchain/chains/llm.py +82 -61
- langchain/chains/llm_bash/__init__.py +3 -2
- langchain/chains/llm_checker/base.py +19 -6
- langchain/chains/llm_checker/prompt.py +3 -4
- langchain/chains/llm_math/base.py +25 -10
- langchain/chains/llm_math/prompt.py +1 -2
- langchain/chains/llm_summarization_checker/base.py +22 -7
- langchain/chains/llm_symbolic_math/__init__.py +3 -2
- langchain/chains/loading.py +155 -97
- langchain/chains/mapreduce.py +4 -3
- langchain/chains/moderation.py +11 -9
- langchain/chains/natbot/base.py +11 -9
- langchain/chains/natbot/crawler.py +102 -76
- langchain/chains/natbot/prompt.py +2 -3
- langchain/chains/openai_functions/__init__.py +7 -7
- langchain/chains/openai_functions/base.py +15 -10
- langchain/chains/openai_functions/citation_fuzzy_match.py +21 -11
- langchain/chains/openai_functions/extraction.py +19 -19
- langchain/chains/openai_functions/openapi.py +39 -35
- langchain/chains/openai_functions/qa_with_structure.py +22 -15
- langchain/chains/openai_functions/tagging.py +4 -4
- langchain/chains/openai_tools/extraction.py +7 -8
- langchain/chains/qa_generation/base.py +8 -3
- langchain/chains/qa_generation/prompt.py +5 -5
- langchain/chains/qa_with_sources/base.py +17 -6
- langchain/chains/qa_with_sources/loading.py +16 -8
- langchain/chains/qa_with_sources/map_reduce_prompt.py +8 -9
- langchain/chains/qa_with_sources/refine_prompts.py +0 -1
- langchain/chains/qa_with_sources/retrieval.py +15 -6
- langchain/chains/qa_with_sources/stuff_prompt.py +6 -7
- langchain/chains/qa_with_sources/vector_db.py +21 -8
- langchain/chains/query_constructor/base.py +37 -34
- langchain/chains/query_constructor/ir.py +4 -4
- langchain/chains/query_constructor/parser.py +101 -34
- langchain/chains/query_constructor/prompt.py +5 -6
- langchain/chains/question_answering/chain.py +21 -10
- langchain/chains/question_answering/map_reduce_prompt.py +14 -14
- langchain/chains/question_answering/map_rerank_prompt.py +3 -3
- langchain/chains/question_answering/refine_prompts.py +2 -5
- langchain/chains/question_answering/stuff_prompt.py +5 -5
- langchain/chains/retrieval.py +1 -3
- langchain/chains/retrieval_qa/base.py +38 -27
- langchain/chains/retrieval_qa/prompt.py +1 -2
- langchain/chains/router/__init__.py +3 -3
- langchain/chains/router/base.py +38 -22
- langchain/chains/router/embedding_router.py +15 -8
- langchain/chains/router/llm_router.py +23 -20
- langchain/chains/router/multi_prompt.py +5 -2
- langchain/chains/router/multi_retrieval_qa.py +28 -5
- langchain/chains/sequential.py +30 -18
- langchain/chains/sql_database/prompt.py +14 -16
- langchain/chains/sql_database/query.py +7 -5
- langchain/chains/structured_output/__init__.py +1 -1
- langchain/chains/structured_output/base.py +77 -67
- langchain/chains/summarize/chain.py +11 -5
- langchain/chains/summarize/map_reduce_prompt.py +0 -1
- langchain/chains/summarize/stuff_prompt.py +0 -1
- langchain/chains/transform.py +9 -6
- langchain/chat_loaders/facebook_messenger.py +1 -1
- langchain/chat_loaders/langsmith.py +1 -1
- langchain/chat_loaders/utils.py +3 -3
- langchain/chat_models/__init__.py +20 -19
- langchain/chat_models/anthropic.py +1 -1
- langchain/chat_models/azureml_endpoint.py +1 -1
- langchain/chat_models/baidu_qianfan_endpoint.py +1 -1
- langchain/chat_models/base.py +213 -139
- langchain/chat_models/bedrock.py +1 -1
- langchain/chat_models/fake.py +1 -1
- langchain/chat_models/meta.py +1 -1
- langchain/chat_models/pai_eas_endpoint.py +1 -1
- langchain/chat_models/promptlayer_openai.py +1 -1
- langchain/chat_models/volcengine_maas.py +1 -1
- langchain/docstore/base.py +1 -1
- langchain/document_loaders/__init__.py +9 -9
- langchain/document_loaders/airbyte.py +3 -3
- langchain/document_loaders/assemblyai.py +1 -1
- langchain/document_loaders/azure_blob_storage_container.py +1 -1
- langchain/document_loaders/azure_blob_storage_file.py +1 -1
- langchain/document_loaders/baiducloud_bos_file.py +1 -1
- langchain/document_loaders/base.py +1 -1
- langchain/document_loaders/blob_loaders/__init__.py +1 -1
- langchain/document_loaders/blob_loaders/schema.py +1 -4
- langchain/document_loaders/blockchain.py +1 -1
- langchain/document_loaders/chatgpt.py +1 -1
- langchain/document_loaders/college_confidential.py +1 -1
- langchain/document_loaders/confluence.py +1 -1
- langchain/document_loaders/email.py +1 -1
- langchain/document_loaders/facebook_chat.py +1 -1
- langchain/document_loaders/markdown.py +1 -1
- langchain/document_loaders/notebook.py +1 -1
- langchain/document_loaders/org_mode.py +1 -1
- langchain/document_loaders/parsers/__init__.py +1 -1
- langchain/document_loaders/parsers/docai.py +1 -1
- langchain/document_loaders/parsers/generic.py +1 -1
- langchain/document_loaders/parsers/html/__init__.py +1 -1
- langchain/document_loaders/parsers/html/bs4.py +1 -1
- langchain/document_loaders/parsers/language/cobol.py +1 -1
- langchain/document_loaders/parsers/language/python.py +1 -1
- langchain/document_loaders/parsers/msword.py +1 -1
- langchain/document_loaders/parsers/pdf.py +5 -5
- langchain/document_loaders/parsers/registry.py +1 -1
- langchain/document_loaders/pdf.py +8 -8
- langchain/document_loaders/powerpoint.py +1 -1
- langchain/document_loaders/pyspark_dataframe.py +1 -1
- langchain/document_loaders/telegram.py +2 -2
- langchain/document_loaders/tencent_cos_directory.py +1 -1
- langchain/document_loaders/unstructured.py +5 -5
- langchain/document_loaders/url_playwright.py +1 -1
- langchain/document_loaders/whatsapp_chat.py +1 -1
- langchain/document_loaders/youtube.py +2 -2
- langchain/document_transformers/__init__.py +3 -3
- langchain/document_transformers/beautiful_soup_transformer.py +1 -1
- langchain/document_transformers/doctran_text_extract.py +1 -1
- langchain/document_transformers/doctran_text_qa.py +1 -1
- langchain/document_transformers/doctran_text_translate.py +1 -1
- langchain/document_transformers/embeddings_redundant_filter.py +3 -3
- langchain/document_transformers/google_translate.py +1 -1
- langchain/document_transformers/html2text.py +1 -1
- langchain/document_transformers/nuclia_text_transform.py +1 -1
- langchain/embeddings/__init__.py +5 -5
- langchain/embeddings/base.py +35 -24
- langchain/embeddings/cache.py +37 -32
- langchain/embeddings/fake.py +1 -1
- langchain/embeddings/huggingface.py +2 -2
- langchain/evaluation/__init__.py +22 -22
- langchain/evaluation/agents/trajectory_eval_chain.py +26 -25
- langchain/evaluation/agents/trajectory_eval_prompt.py +6 -9
- langchain/evaluation/comparison/__init__.py +1 -1
- langchain/evaluation/comparison/eval_chain.py +21 -13
- langchain/evaluation/comparison/prompt.py +1 -2
- langchain/evaluation/criteria/__init__.py +1 -1
- langchain/evaluation/criteria/eval_chain.py +23 -11
- langchain/evaluation/criteria/prompt.py +2 -3
- langchain/evaluation/embedding_distance/base.py +34 -20
- langchain/evaluation/exact_match/base.py +14 -1
- langchain/evaluation/loading.py +16 -11
- langchain/evaluation/parsing/base.py +20 -4
- langchain/evaluation/parsing/json_distance.py +24 -10
- langchain/evaluation/parsing/json_schema.py +13 -12
- langchain/evaluation/qa/__init__.py +1 -1
- langchain/evaluation/qa/eval_chain.py +20 -5
- langchain/evaluation/qa/eval_prompt.py +7 -8
- langchain/evaluation/qa/generate_chain.py +4 -1
- langchain/evaluation/qa/generate_prompt.py +2 -4
- langchain/evaluation/regex_match/base.py +9 -1
- langchain/evaluation/schema.py +38 -30
- langchain/evaluation/scoring/__init__.py +1 -1
- langchain/evaluation/scoring/eval_chain.py +23 -15
- langchain/evaluation/scoring/prompt.py +0 -1
- langchain/evaluation/string_distance/base.py +20 -9
- langchain/globals.py +12 -11
- langchain/graphs/__init__.py +6 -6
- langchain/graphs/graph_document.py +1 -1
- langchain/graphs/networkx_graph.py +2 -2
- langchain/hub.py +9 -11
- langchain/indexes/__init__.py +3 -3
- langchain/indexes/_sql_record_manager.py +63 -46
- langchain/indexes/prompts/entity_extraction.py +1 -2
- langchain/indexes/prompts/entity_summarization.py +1 -2
- langchain/indexes/prompts/knowledge_triplet_extraction.py +1 -3
- langchain/indexes/vectorstore.py +35 -19
- langchain/llms/__init__.py +13 -13
- langchain/llms/ai21.py +1 -1
- langchain/llms/azureml_endpoint.py +4 -4
- langchain/llms/base.py +15 -7
- langchain/llms/bedrock.py +1 -1
- langchain/llms/cloudflare_workersai.py +1 -1
- langchain/llms/gradient_ai.py +1 -1
- langchain/llms/loading.py +1 -1
- langchain/llms/openai.py +1 -1
- langchain/llms/sagemaker_endpoint.py +1 -1
- langchain/load/dump.py +1 -1
- langchain/load/load.py +1 -1
- langchain/load/serializable.py +3 -3
- langchain/memory/__init__.py +3 -3
- langchain/memory/buffer.py +14 -7
- langchain/memory/buffer_window.py +2 -0
- langchain/memory/chat_memory.py +14 -8
- langchain/memory/chat_message_histories/__init__.py +1 -1
- langchain/memory/chat_message_histories/astradb.py +1 -1
- langchain/memory/chat_message_histories/cassandra.py +1 -1
- langchain/memory/chat_message_histories/cosmos_db.py +1 -1
- langchain/memory/chat_message_histories/dynamodb.py +1 -1
- langchain/memory/chat_message_histories/elasticsearch.py +1 -1
- langchain/memory/chat_message_histories/file.py +1 -1
- langchain/memory/chat_message_histories/firestore.py +1 -1
- langchain/memory/chat_message_histories/momento.py +1 -1
- langchain/memory/chat_message_histories/mongodb.py +1 -1
- langchain/memory/chat_message_histories/neo4j.py +1 -1
- langchain/memory/chat_message_histories/postgres.py +1 -1
- langchain/memory/chat_message_histories/redis.py +1 -1
- langchain/memory/chat_message_histories/rocksetdb.py +1 -1
- langchain/memory/chat_message_histories/singlestoredb.py +1 -1
- langchain/memory/chat_message_histories/streamlit.py +1 -1
- langchain/memory/chat_message_histories/upstash_redis.py +1 -1
- langchain/memory/chat_message_histories/xata.py +1 -1
- langchain/memory/chat_message_histories/zep.py +1 -1
- langchain/memory/combined.py +14 -13
- langchain/memory/entity.py +131 -61
- langchain/memory/prompt.py +10 -11
- langchain/memory/readonly.py +0 -2
- langchain/memory/simple.py +4 -3
- langchain/memory/summary.py +43 -11
- langchain/memory/summary_buffer.py +20 -8
- langchain/memory/token_buffer.py +2 -0
- langchain/memory/utils.py +3 -2
- langchain/memory/vectorstore.py +12 -5
- langchain/memory/vectorstore_token_buffer_memory.py +5 -5
- langchain/model_laboratory.py +12 -11
- langchain/output_parsers/__init__.py +4 -4
- langchain/output_parsers/boolean.py +7 -4
- langchain/output_parsers/combining.py +14 -7
- langchain/output_parsers/datetime.py +32 -31
- langchain/output_parsers/enum.py +10 -4
- langchain/output_parsers/fix.py +60 -53
- langchain/output_parsers/format_instructions.py +6 -8
- langchain/output_parsers/json.py +2 -2
- langchain/output_parsers/list.py +2 -2
- langchain/output_parsers/loading.py +9 -9
- langchain/output_parsers/openai_functions.py +3 -3
- langchain/output_parsers/openai_tools.py +1 -1
- langchain/output_parsers/pandas_dataframe.py +59 -48
- langchain/output_parsers/prompts.py +1 -2
- langchain/output_parsers/rail_parser.py +1 -1
- langchain/output_parsers/regex.py +9 -8
- langchain/output_parsers/regex_dict.py +7 -10
- langchain/output_parsers/retry.py +99 -80
- langchain/output_parsers/structured.py +21 -6
- langchain/output_parsers/yaml.py +19 -11
- langchain/prompts/__init__.py +5 -3
- langchain/prompts/base.py +5 -5
- langchain/prompts/chat.py +8 -8
- langchain/prompts/example_selector/__init__.py +3 -1
- langchain/prompts/example_selector/semantic_similarity.py +2 -2
- langchain/prompts/few_shot.py +1 -1
- langchain/prompts/loading.py +3 -3
- langchain/prompts/prompt.py +1 -1
- langchain/pydantic_v1/__init__.py +1 -1
- langchain/retrievers/__init__.py +5 -5
- langchain/retrievers/bedrock.py +2 -2
- langchain/retrievers/bm25.py +1 -1
- langchain/retrievers/contextual_compression.py +14 -8
- langchain/retrievers/docarray.py +1 -1
- langchain/retrievers/document_compressors/__init__.py +5 -4
- langchain/retrievers/document_compressors/base.py +12 -6
- langchain/retrievers/document_compressors/chain_extract.py +5 -3
- langchain/retrievers/document_compressors/chain_extract_prompt.py +2 -3
- langchain/retrievers/document_compressors/chain_filter.py +9 -9
- langchain/retrievers/document_compressors/chain_filter_prompt.py +1 -2
- langchain/retrievers/document_compressors/cohere_rerank.py +17 -15
- langchain/retrievers/document_compressors/cross_encoder_rerank.py +2 -0
- langchain/retrievers/document_compressors/embeddings_filter.py +24 -17
- langchain/retrievers/document_compressors/flashrank_rerank.py +1 -1
- langchain/retrievers/document_compressors/listwise_rerank.py +8 -5
- langchain/retrievers/ensemble.py +30 -27
- langchain/retrievers/google_cloud_documentai_warehouse.py +1 -1
- langchain/retrievers/google_vertex_ai_search.py +2 -2
- langchain/retrievers/kendra.py +10 -10
- langchain/retrievers/llama_index.py +1 -1
- langchain/retrievers/merger_retriever.py +11 -11
- langchain/retrievers/milvus.py +1 -1
- langchain/retrievers/multi_query.py +35 -27
- langchain/retrievers/multi_vector.py +24 -9
- langchain/retrievers/parent_document_retriever.py +33 -9
- langchain/retrievers/re_phraser.py +6 -5
- langchain/retrievers/self_query/base.py +157 -127
- langchain/retrievers/time_weighted_retriever.py +21 -7
- langchain/retrievers/zilliz.py +1 -1
- langchain/runnables/hub.py +12 -0
- langchain/runnables/openai_functions.py +12 -2
- langchain/schema/__init__.py +23 -23
- langchain/schema/cache.py +1 -1
- langchain/schema/callbacks/base.py +7 -7
- langchain/schema/callbacks/manager.py +19 -19
- langchain/schema/callbacks/tracers/base.py +1 -1
- langchain/schema/callbacks/tracers/evaluation.py +1 -1
- langchain/schema/callbacks/tracers/langchain.py +1 -1
- langchain/schema/callbacks/tracers/langchain_v1.py +1 -1
- langchain/schema/callbacks/tracers/log_stream.py +1 -1
- langchain/schema/callbacks/tracers/schemas.py +8 -8
- langchain/schema/callbacks/tracers/stdout.py +3 -3
- langchain/schema/document.py +1 -1
- langchain/schema/language_model.py +2 -2
- langchain/schema/messages.py +12 -12
- langchain/schema/output.py +3 -3
- langchain/schema/output_parser.py +3 -3
- langchain/schema/runnable/__init__.py +3 -3
- langchain/schema/runnable/base.py +9 -9
- langchain/schema/runnable/config.py +5 -5
- langchain/schema/runnable/configurable.py +1 -1
- langchain/schema/runnable/history.py +1 -1
- langchain/schema/runnable/passthrough.py +1 -1
- langchain/schema/runnable/utils.py +16 -16
- langchain/schema/vectorstore.py +1 -1
- langchain/smith/__init__.py +2 -1
- langchain/smith/evaluation/__init__.py +2 -2
- langchain/smith/evaluation/config.py +9 -23
- langchain/smith/evaluation/name_generation.py +3 -3
- langchain/smith/evaluation/progress.py +22 -4
- langchain/smith/evaluation/runner_utils.py +416 -247
- langchain/smith/evaluation/string_run_evaluator.py +102 -68
- langchain/storage/__init__.py +2 -2
- langchain/storage/_lc_store.py +4 -2
- langchain/storage/encoder_backed.py +7 -2
- langchain/storage/file_system.py +19 -16
- langchain/storage/in_memory.py +1 -1
- langchain/storage/upstash_redis.py +1 -1
- langchain/text_splitter.py +15 -15
- langchain/tools/__init__.py +28 -26
- langchain/tools/ainetwork/app.py +1 -1
- langchain/tools/ainetwork/base.py +1 -1
- langchain/tools/ainetwork/owner.py +1 -1
- langchain/tools/ainetwork/rule.py +1 -1
- langchain/tools/ainetwork/transfer.py +1 -1
- langchain/tools/ainetwork/value.py +1 -1
- langchain/tools/amadeus/closest_airport.py +1 -1
- langchain/tools/amadeus/flight_search.py +1 -1
- langchain/tools/azure_cognitive_services/__init__.py +1 -1
- langchain/tools/base.py +4 -4
- langchain/tools/bearly/tool.py +1 -1
- langchain/tools/bing_search/__init__.py +1 -1
- langchain/tools/bing_search/tool.py +1 -1
- langchain/tools/dataforseo_api_search/__init__.py +1 -1
- langchain/tools/dataforseo_api_search/tool.py +1 -1
- langchain/tools/ddg_search/tool.py +1 -1
- langchain/tools/e2b_data_analysis/tool.py +2 -2
- langchain/tools/edenai/__init__.py +1 -1
- langchain/tools/file_management/__init__.py +1 -1
- langchain/tools/file_management/copy.py +1 -1
- langchain/tools/file_management/delete.py +1 -1
- langchain/tools/gmail/__init__.py +2 -2
- langchain/tools/gmail/get_message.py +1 -1
- langchain/tools/gmail/search.py +1 -1
- langchain/tools/gmail/send_message.py +1 -1
- langchain/tools/google_finance/__init__.py +1 -1
- langchain/tools/google_finance/tool.py +1 -1
- langchain/tools/google_scholar/__init__.py +1 -1
- langchain/tools/google_scholar/tool.py +1 -1
- langchain/tools/google_search/__init__.py +1 -1
- langchain/tools/google_search/tool.py +1 -1
- langchain/tools/google_serper/__init__.py +1 -1
- langchain/tools/google_serper/tool.py +1 -1
- langchain/tools/google_trends/__init__.py +1 -1
- langchain/tools/google_trends/tool.py +1 -1
- langchain/tools/jira/tool.py +20 -1
- langchain/tools/json/tool.py +25 -3
- langchain/tools/memorize/tool.py +1 -1
- langchain/tools/multion/__init__.py +1 -1
- langchain/tools/multion/update_session.py +1 -1
- langchain/tools/office365/__init__.py +2 -2
- langchain/tools/office365/events_search.py +1 -1
- langchain/tools/office365/messages_search.py +1 -1
- langchain/tools/office365/send_event.py +1 -1
- langchain/tools/office365/send_message.py +1 -1
- langchain/tools/openapi/utils/api_models.py +6 -6
- langchain/tools/playwright/__init__.py +5 -5
- langchain/tools/playwright/click.py +1 -1
- langchain/tools/playwright/extract_hyperlinks.py +1 -1
- langchain/tools/playwright/get_elements.py +1 -1
- langchain/tools/playwright/navigate.py +1 -1
- langchain/tools/plugin.py +2 -2
- langchain/tools/powerbi/tool.py +1 -1
- langchain/tools/python/__init__.py +3 -2
- langchain/tools/reddit_search/tool.py +1 -1
- langchain/tools/render.py +2 -2
- langchain/tools/requests/tool.py +2 -2
- langchain/tools/searchapi/tool.py +1 -1
- langchain/tools/searx_search/tool.py +1 -1
- langchain/tools/slack/get_message.py +1 -1
- langchain/tools/spark_sql/tool.py +1 -1
- langchain/tools/sql_database/tool.py +1 -1
- langchain/tools/tavily_search/__init__.py +1 -1
- langchain/tools/tavily_search/tool.py +1 -1
- langchain/tools/zapier/__init__.py +1 -1
- langchain/tools/zapier/tool.py +24 -2
- langchain/utilities/__init__.py +4 -4
- langchain/utilities/arcee.py +4 -4
- langchain/utilities/clickup.py +4 -4
- langchain/utilities/dalle_image_generator.py +1 -1
- langchain/utilities/dataforseo_api_search.py +1 -1
- langchain/utilities/opaqueprompts.py +1 -1
- langchain/utilities/reddit_search.py +1 -1
- langchain/utilities/sql_database.py +1 -1
- langchain/utilities/tavily_search.py +1 -1
- langchain/utilities/vertexai.py +2 -2
- langchain/utils/__init__.py +1 -1
- langchain/utils/aiter.py +1 -1
- langchain/utils/html.py +3 -3
- langchain/utils/input.py +1 -1
- langchain/utils/iter.py +1 -1
- langchain/utils/json_schema.py +1 -3
- langchain/utils/strings.py +1 -1
- langchain/utils/utils.py +6 -6
- langchain/vectorstores/__init__.py +5 -5
- langchain/vectorstores/alibabacloud_opensearch.py +1 -1
- langchain/vectorstores/azure_cosmos_db.py +1 -1
- langchain/vectorstores/clickhouse.py +1 -1
- langchain/vectorstores/elastic_vector_search.py +1 -1
- langchain/vectorstores/elasticsearch.py +2 -2
- langchain/vectorstores/myscale.py +1 -1
- langchain/vectorstores/neo4j_vector.py +1 -1
- langchain/vectorstores/pgembedding.py +1 -1
- langchain/vectorstores/qdrant.py +1 -1
- langchain/vectorstores/redis/__init__.py +1 -1
- langchain/vectorstores/redis/base.py +1 -1
- langchain/vectorstores/redis/filters.py +4 -4
- langchain/vectorstores/redis/schema.py +6 -6
- langchain/vectorstores/sklearn.py +2 -2
- langchain/vectorstores/starrocks.py +1 -1
- langchain/vectorstores/utils.py +1 -1
- {langchain-0.3.26.dist-info → langchain-0.4.0.dev0.dist-info}/METADATA +4 -14
- {langchain-0.3.26.dist-info → langchain-0.4.0.dev0.dist-info}/RECORD +590 -591
- {langchain-0.3.26.dist-info → langchain-0.4.0.dev0.dist-info}/WHEEL +1 -1
- langchain/smith/evaluation/utils.py +0 -0
- {langchain-0.3.26.dist-info → langchain-0.4.0.dev0.dist-info}/entry_points.txt +0 -0
- {langchain-0.3.26.dist-info → langchain-0.4.0.dev0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,49 +1,123 @@
|
|
|
1
|
-
|
|
1
|
+
import re
|
|
2
|
+
from typing import Literal, Optional, Union
|
|
2
3
|
|
|
3
4
|
from langchain_core.agents import AgentAction, AgentFinish
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
from typing_extensions import override
|
|
4
7
|
|
|
5
8
|
from langchain.agents import AgentOutputParser
|
|
6
9
|
|
|
7
10
|
|
|
11
|
+
def _unescape(text: str) -> str:
|
|
12
|
+
"""Convert custom tag delimiters back into XML tags."""
|
|
13
|
+
replacements = {
|
|
14
|
+
"[[tool]]": "<tool>",
|
|
15
|
+
"[[/tool]]": "</tool>",
|
|
16
|
+
"[[tool_input]]": "<tool_input>",
|
|
17
|
+
"[[/tool_input]]": "</tool_input>",
|
|
18
|
+
"[[observation]]": "<observation>",
|
|
19
|
+
"[[/observation]]": "</observation>",
|
|
20
|
+
}
|
|
21
|
+
for repl, orig in replacements.items():
|
|
22
|
+
text = text.replace(repl, orig)
|
|
23
|
+
return text
|
|
24
|
+
|
|
25
|
+
|
|
8
26
|
class XMLAgentOutputParser(AgentOutputParser):
|
|
9
|
-
"""Parses tool invocations and final answers
|
|
27
|
+
"""Parses tool invocations and final answers from XML-formatted agent output.
|
|
28
|
+
|
|
29
|
+
This parser extracts structured information from XML tags to determine whether
|
|
30
|
+
an agent should perform a tool action or provide a final answer. It includes
|
|
31
|
+
built-in escaping support to safely handle tool names and inputs
|
|
32
|
+
containing XML special characters.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
escape_format: The escaping format to use when parsing XML content.
|
|
36
|
+
Supports 'minimal' which uses custom delimiters like [[tool]] to replace
|
|
37
|
+
XML tags within content, preventing parsing conflicts.
|
|
38
|
+
Use 'minimal' if using a corresponding encoding format that uses
|
|
39
|
+
the _escape function when formatting the output (e.g., with format_xml).
|
|
40
|
+
|
|
41
|
+
Expected formats:
|
|
42
|
+
Tool invocation (returns AgentAction):
|
|
43
|
+
<tool>search</tool>
|
|
44
|
+
<tool_input>what is 2 + 2</tool_input>
|
|
10
45
|
|
|
11
|
-
|
|
46
|
+
Final answer (returns AgentFinish):
|
|
47
|
+
<final_answer>The answer is 4</final_answer>
|
|
12
48
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
49
|
+
Note:
|
|
50
|
+
Minimal escaping allows tool names containing XML tags to be safely
|
|
51
|
+
represented. For example, a tool named "search<tool>nested</tool>" would be
|
|
52
|
+
escaped as "search[[tool]]nested[[/tool]]" in the XML and automatically
|
|
53
|
+
unescaped during parsing.
|
|
16
54
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
55
|
+
Raises:
|
|
56
|
+
ValueError: If the input doesn't match either expected XML format or
|
|
57
|
+
contains malformed XML structure.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
escape_format: Optional[Literal["minimal"]] = Field(default="minimal")
|
|
61
|
+
"""The format to use for escaping XML characters.
|
|
21
62
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
being returned.
|
|
63
|
+
minimal - uses custom delimiters to replace XML tags within content,
|
|
64
|
+
preventing parsing conflicts. This is the only supported format currently.
|
|
25
65
|
|
|
26
|
-
|
|
27
|
-
<final_answer>Foo</final_answer>
|
|
28
|
-
```
|
|
66
|
+
None - no escaping is applied, which may lead to parsing conflicts.
|
|
29
67
|
"""
|
|
30
68
|
|
|
69
|
+
@override
|
|
31
70
|
def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
71
|
+
# Check for tool invocation first
|
|
72
|
+
tool_matches = re.findall(r"<tool>(.*?)</tool>", text, re.DOTALL)
|
|
73
|
+
if tool_matches:
|
|
74
|
+
if len(tool_matches) != 1:
|
|
75
|
+
msg = (
|
|
76
|
+
f"Malformed tool invocation: expected exactly one <tool> block, "
|
|
77
|
+
f"but found {len(tool_matches)}."
|
|
78
|
+
)
|
|
79
|
+
raise ValueError(msg)
|
|
80
|
+
_tool = tool_matches[0]
|
|
81
|
+
|
|
82
|
+
# Match optional tool input
|
|
83
|
+
input_matches = re.findall(
|
|
84
|
+
r"<tool_input>(.*?)</tool_input>", text, re.DOTALL
|
|
85
|
+
)
|
|
86
|
+
if len(input_matches) > 1:
|
|
87
|
+
msg = (
|
|
88
|
+
f"Malformed tool invocation: expected at most one <tool_input> "
|
|
89
|
+
f"block, but found {len(input_matches)}."
|
|
90
|
+
)
|
|
91
|
+
raise ValueError(msg)
|
|
92
|
+
_tool_input = input_matches[0] if input_matches else ""
|
|
93
|
+
|
|
94
|
+
# Unescape if minimal escape format is used
|
|
95
|
+
if self.escape_format == "minimal":
|
|
96
|
+
_tool = _unescape(_tool)
|
|
97
|
+
_tool_input = _unescape(_tool_input)
|
|
98
|
+
|
|
38
99
|
return AgentAction(tool=_tool, tool_input=_tool_input, log=text)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
100
|
+
# Check for final answer
|
|
101
|
+
if "<final_answer>" in text and "</final_answer>" in text:
|
|
102
|
+
matches = re.findall(r"<final_answer>(.*?)</final_answer>", text, re.DOTALL)
|
|
103
|
+
if len(matches) != 1:
|
|
104
|
+
msg = (
|
|
105
|
+
"Malformed output: expected exactly one "
|
|
106
|
+
"<final_answer>...</final_answer> block."
|
|
107
|
+
)
|
|
108
|
+
raise ValueError(msg)
|
|
109
|
+
answer = matches[0]
|
|
110
|
+
# Unescape custom delimiters in final answer
|
|
111
|
+
if self.escape_format == "minimal":
|
|
112
|
+
answer = _unescape(answer)
|
|
43
113
|
return AgentFinish(return_values={"output": answer}, log=text)
|
|
44
|
-
|
|
45
|
-
|
|
114
|
+
msg = (
|
|
115
|
+
"Malformed output: expected either a tool invocation "
|
|
116
|
+
"or a final answer in XML format."
|
|
117
|
+
)
|
|
118
|
+
raise ValueError(msg)
|
|
46
119
|
|
|
120
|
+
@override
|
|
47
121
|
def get_format_instructions(self) -> str:
|
|
48
122
|
raise NotImplementedError
|
|
49
123
|
|
langchain/agents/react/agent.py
CHANGED
|
@@ -116,12 +116,14 @@ def create_react_agent(
|
|
|
116
116
|
Thought:{agent_scratchpad}'''
|
|
117
117
|
|
|
118
118
|
prompt = PromptTemplate.from_template(template)
|
|
119
|
+
|
|
119
120
|
""" # noqa: E501
|
|
120
121
|
missing_vars = {"tools", "tool_names", "agent_scratchpad"}.difference(
|
|
121
|
-
prompt.input_variables + list(prompt.partial_variables)
|
|
122
|
+
prompt.input_variables + list(prompt.partial_variables),
|
|
122
123
|
)
|
|
123
124
|
if missing_vars:
|
|
124
|
-
|
|
125
|
+
msg = f"Prompt missing required variables: {missing_vars}"
|
|
126
|
+
raise ValueError(msg)
|
|
125
127
|
|
|
126
128
|
prompt = prompt.partial(
|
|
127
129
|
tools=tools_renderer(list(tools)),
|
|
@@ -133,7 +135,7 @@ def create_react_agent(
|
|
|
133
135
|
else:
|
|
134
136
|
llm_with_stop = llm
|
|
135
137
|
output_parser = output_parser or ReActSingleInputOutputParser()
|
|
136
|
-
|
|
138
|
+
return (
|
|
137
139
|
RunnablePassthrough.assign(
|
|
138
140
|
agent_scratchpad=lambda x: format_log_to_str(x["intermediate_steps"]),
|
|
139
141
|
)
|
|
@@ -141,4 +143,3 @@ def create_react_agent(
|
|
|
141
143
|
| llm_with_stop
|
|
142
144
|
| output_parser
|
|
143
145
|
)
|
|
144
|
-
return agent
|
langchain/agents/react/base.py
CHANGED
|
@@ -11,6 +11,7 @@ from langchain_core.language_models import BaseLanguageModel
|
|
|
11
11
|
from langchain_core.prompts import BasePromptTemplate
|
|
12
12
|
from langchain_core.tools import BaseTool, Tool
|
|
13
13
|
from pydantic import Field
|
|
14
|
+
from typing_extensions import override
|
|
14
15
|
|
|
15
16
|
from langchain._api.deprecation import AGENT_DEPRECATION_WARNING
|
|
16
17
|
from langchain.agents.agent import Agent, AgentExecutor, AgentOutputParser
|
|
@@ -24,6 +25,9 @@ if TYPE_CHECKING:
|
|
|
24
25
|
from langchain_community.docstore.base import Docstore
|
|
25
26
|
|
|
26
27
|
|
|
28
|
+
_LOOKUP_AND_SEARCH_TOOLS = {"Lookup", "Search"}
|
|
29
|
+
|
|
30
|
+
|
|
27
31
|
@deprecated(
|
|
28
32
|
"0.1.0",
|
|
29
33
|
message=AGENT_DEPRECATION_WARNING,
|
|
@@ -35,6 +39,7 @@ class ReActDocstoreAgent(Agent):
|
|
|
35
39
|
output_parser: AgentOutputParser = Field(default_factory=ReActOutputParser)
|
|
36
40
|
|
|
37
41
|
@classmethod
|
|
42
|
+
@override
|
|
38
43
|
def _get_default_output_parser(cls, **kwargs: Any) -> AgentOutputParser:
|
|
39
44
|
return ReActOutputParser()
|
|
40
45
|
|
|
@@ -44,6 +49,7 @@ class ReActDocstoreAgent(Agent):
|
|
|
44
49
|
return AgentType.REACT_DOCSTORE
|
|
45
50
|
|
|
46
51
|
@classmethod
|
|
52
|
+
@override
|
|
47
53
|
def create_prompt(cls, tools: Sequence[BaseTool]) -> BasePromptTemplate:
|
|
48
54
|
"""Return default prompt."""
|
|
49
55
|
return WIKI_PROMPT
|
|
@@ -52,13 +58,13 @@ class ReActDocstoreAgent(Agent):
|
|
|
52
58
|
def _validate_tools(cls, tools: Sequence[BaseTool]) -> None:
|
|
53
59
|
validate_tools_single_input(cls.__name__, tools)
|
|
54
60
|
super()._validate_tools(tools)
|
|
55
|
-
if len(tools) !=
|
|
56
|
-
|
|
61
|
+
if len(tools) != len(_LOOKUP_AND_SEARCH_TOOLS):
|
|
62
|
+
msg = f"Exactly two tools must be specified, but got {tools}"
|
|
63
|
+
raise ValueError(msg)
|
|
57
64
|
tool_names = {tool.name for tool in tools}
|
|
58
|
-
if tool_names !=
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
)
|
|
65
|
+
if tool_names != _LOOKUP_AND_SEARCH_TOOLS:
|
|
66
|
+
msg = f"Tool names should be Lookup and Search, got {tool_names}"
|
|
67
|
+
raise ValueError(msg)
|
|
62
68
|
|
|
63
69
|
@property
|
|
64
70
|
def observation_prefix(self) -> str:
|
|
@@ -96,14 +102,14 @@ class DocstoreExplorer:
|
|
|
96
102
|
if isinstance(result, Document):
|
|
97
103
|
self.document = result
|
|
98
104
|
return self._summary
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return result
|
|
105
|
+
self.document = None
|
|
106
|
+
return result
|
|
102
107
|
|
|
103
108
|
def lookup(self, term: str) -> str:
|
|
104
109
|
"""Lookup a term in document (if saved)."""
|
|
105
110
|
if self.document is None:
|
|
106
|
-
|
|
111
|
+
msg = "Cannot lookup without a successful search first"
|
|
112
|
+
raise ValueError(msg)
|
|
107
113
|
if term.lower() != self.lookup_str:
|
|
108
114
|
self.lookup_str = term.lower()
|
|
109
115
|
self.lookup_index = 0
|
|
@@ -112,11 +118,10 @@ class DocstoreExplorer:
|
|
|
112
118
|
lookups = [p for p in self._paragraphs if self.lookup_str in p.lower()]
|
|
113
119
|
if len(lookups) == 0:
|
|
114
120
|
return "No Results"
|
|
115
|
-
|
|
121
|
+
if self.lookup_index >= len(lookups):
|
|
116
122
|
return "No More Results"
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return f"{result_prefix} {lookups[self.lookup_index]}"
|
|
123
|
+
result_prefix = f"(Result {self.lookup_index + 1}/{len(lookups)})"
|
|
124
|
+
return f"{result_prefix} {lookups[self.lookup_index]}"
|
|
120
125
|
|
|
121
126
|
@property
|
|
122
127
|
def _summary(self) -> str:
|
|
@@ -125,7 +130,8 @@ class DocstoreExplorer:
|
|
|
125
130
|
@property
|
|
126
131
|
def _paragraphs(self) -> list[str]:
|
|
127
132
|
if self.document is None:
|
|
128
|
-
|
|
133
|
+
msg = "Cannot get paragraphs without a document"
|
|
134
|
+
raise ValueError(msg)
|
|
129
135
|
return self.document.page_content.split("\n\n")
|
|
130
136
|
|
|
131
137
|
|
|
@@ -138,6 +144,7 @@ class ReActTextWorldAgent(ReActDocstoreAgent):
|
|
|
138
144
|
"""Agent for the ReAct TextWorld chain."""
|
|
139
145
|
|
|
140
146
|
@classmethod
|
|
147
|
+
@override
|
|
141
148
|
def create_prompt(cls, tools: Sequence[BaseTool]) -> BasePromptTemplate:
|
|
142
149
|
"""Return default prompt."""
|
|
143
150
|
return TEXTWORLD_PROMPT
|
|
@@ -147,10 +154,12 @@ class ReActTextWorldAgent(ReActDocstoreAgent):
|
|
|
147
154
|
validate_tools_single_input(cls.__name__, tools)
|
|
148
155
|
super()._validate_tools(tools)
|
|
149
156
|
if len(tools) != 1:
|
|
150
|
-
|
|
157
|
+
msg = f"Exactly one tool must be specified, but got {tools}"
|
|
158
|
+
raise ValueError(msg)
|
|
151
159
|
tool_names = {tool.name for tool in tools}
|
|
152
160
|
if tool_names != {"Play"}:
|
|
153
|
-
|
|
161
|
+
msg = f"Tool name should be Play, got {tool_names}"
|
|
162
|
+
raise ValueError(msg)
|
|
154
163
|
|
|
155
164
|
|
|
156
165
|
@deprecated(
|
|
@@ -3,6 +3,7 @@ from typing import Union
|
|
|
3
3
|
|
|
4
4
|
from langchain_core.agents import AgentAction, AgentFinish
|
|
5
5
|
from langchain_core.exceptions import OutputParserException
|
|
6
|
+
from typing_extensions import override
|
|
6
7
|
|
|
7
8
|
from langchain.agents.agent import AgentOutputParser
|
|
8
9
|
|
|
@@ -10,24 +11,24 @@ from langchain.agents.agent import AgentOutputParser
|
|
|
10
11
|
class ReActOutputParser(AgentOutputParser):
|
|
11
12
|
"""Output parser for the ReAct agent."""
|
|
12
13
|
|
|
14
|
+
@override
|
|
13
15
|
def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
|
|
14
16
|
action_prefix = "Action: "
|
|
15
17
|
if not text.strip().split("\n")[-1].startswith(action_prefix):
|
|
16
|
-
|
|
18
|
+
msg = f"Could not parse LLM Output: {text}"
|
|
19
|
+
raise OutputParserException(msg)
|
|
17
20
|
action_block = text.strip().split("\n")[-1]
|
|
18
21
|
|
|
19
22
|
action_str = action_block[len(action_prefix) :]
|
|
20
23
|
# Parse out the action and the directive.
|
|
21
24
|
re_matches = re.search(r"(.*?)\[(.*?)\]", action_str)
|
|
22
25
|
if re_matches is None:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
+
msg = f"Could not parse action directive: {action_str}"
|
|
27
|
+
raise OutputParserException(msg)
|
|
26
28
|
action, action_input = re_matches.group(1), re_matches.group(2)
|
|
27
29
|
if action == "Finish":
|
|
28
30
|
return AgentFinish({"output": action_input}, text)
|
|
29
|
-
|
|
30
|
-
return AgentAction(action, action_input, text)
|
|
31
|
+
return AgentAction(action, action_input, text)
|
|
31
32
|
|
|
32
33
|
@property
|
|
33
34
|
def _type(self) -> str:
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# flake8: noqa
|
|
2
1
|
from langchain_core.prompts.prompt import PromptTemplate
|
|
3
2
|
|
|
4
3
|
EXAMPLES = [
|
|
@@ -16,7 +15,7 @@ Thought: I need to instead search High Plains (United States).
|
|
|
16
15
|
Action: Search[High Plains (United States)]
|
|
17
16
|
Observation: The High Plains are a subregion of the Great Plains. From east to west, the High Plains rise in elevation from around 1,800 to 7,000 ft (550 to 2,130 m).[3]
|
|
18
17
|
Thought: High Plains rise in elevation from around 1,800 to 7,000 ft, so the answer is 1,800 to 7,000 ft.
|
|
19
|
-
Action: Finish[1,800 to 7,000 ft]""",
|
|
18
|
+
Action: Finish[1,800 to 7,000 ft]""", # noqa: E501
|
|
20
19
|
"""Question: Musician and satirist Allie Goertz wrote a song about the "The Simpsons" character Milhouse, who Matt Groening named after who?
|
|
21
20
|
Thought: The question simplifies to "The Simpsons" character Milhouse is named after who. I only need to search Milhouse and find who it is named after.
|
|
22
21
|
Action: Search[Milhouse]
|
|
@@ -25,16 +24,16 @@ Thought: The paragraph does not tell who Milhouse is named after, maybe I can lo
|
|
|
25
24
|
Action: Lookup[named after]
|
|
26
25
|
Observation: (Result 1 / 1) Milhouse was named after U.S. president Richard Nixon, whose middle name was Milhous.
|
|
27
26
|
Thought: Milhouse was named after U.S. president Richard Nixon, so the answer is Richard Nixon.
|
|
28
|
-
Action: Finish[Richard Nixon]""",
|
|
27
|
+
Action: Finish[Richard Nixon]""", # noqa: E501
|
|
29
28
|
"""Question: Which documentary is about Finnish rock groups, Adam Clayton Powell or The Saimaa Gesture?
|
|
30
29
|
Thought: I need to search Adam Clayton Powell and The Saimaa Gesture, and find which documentary is about Finnish rock groups.
|
|
31
30
|
Action: Search[Adam Clayton Powell]
|
|
32
|
-
Observation: Could not find [Adam Clayton Powell]. Similar: [
|
|
31
|
+
Observation: Could not find [Adam Clayton Powell]. Similar: ['Adam Clayton Powell III', 'Seventh Avenue (Manhattan)', 'Adam Clayton Powell Jr. State Office Building', 'Isabel Washington Powell', 'Adam Powell', 'Adam Clayton Powell (film)', 'Giancarlo Esposito'].
|
|
33
32
|
Thought: To find the documentary, I can search Adam Clayton Powell (film).
|
|
34
33
|
Action: Search[Adam Clayton Powell (film)]
|
|
35
34
|
Observation: Adam Clayton Powell is a 1989 American documentary film directed by Richard Kilberg. The film is about the rise and fall of influential African-American politician Adam Clayton Powell Jr.[3][4] It was later aired as part of the PBS series The American Experience.
|
|
36
35
|
Thought: Adam Clayton Powell (film) is a documentary about an African-American politician, not Finnish rock groups. So the documentary about Finnish rock groups must instead be The Saimaa Gesture.
|
|
37
|
-
Action: Finish[The Saimaa Gesture]""",
|
|
36
|
+
Action: Finish[The Saimaa Gesture]""", # noqa: E501
|
|
38
37
|
"""Question: What profession does Nicholas Ray and Elia Kazan have in common?
|
|
39
38
|
Thought: I need to search Nicholas Ray and Elia Kazan, find their professions, then find the profession they have in common.
|
|
40
39
|
Action: Search[Nicholas Ray]
|
|
@@ -43,16 +42,16 @@ Thought: Professions of Nicholas Ray are director, screenwriter, and actor. I ne
|
|
|
43
42
|
Action: Search[Elia Kazan]
|
|
44
43
|
Observation: Elia Kazan was an American film and theatre director, producer, screenwriter and actor.
|
|
45
44
|
Thought: Professions of Elia Kazan are director, producer, screenwriter, and actor. So profession Nicholas Ray and Elia Kazan have in common is director, screenwriter, and actor.
|
|
46
|
-
Action: Finish[director, screenwriter, actor]""",
|
|
47
|
-
"""Question: Which magazine was started first Arthur
|
|
48
|
-
Thought: I need to search Arthur
|
|
49
|
-
Action: Search[Arthur
|
|
50
|
-
Observation: Arthur
|
|
51
|
-
Thought: Arthur
|
|
45
|
+
Action: Finish[director, screenwriter, actor]""", # noqa: E501
|
|
46
|
+
"""Question: Which magazine was started first Arthur's Magazine or First for Women?
|
|
47
|
+
Thought: I need to search Arthur's Magazine and First for Women, and find which was started first.
|
|
48
|
+
Action: Search[Arthur's Magazine]
|
|
49
|
+
Observation: Arthur's Magazine (1844-1846) was an American literary periodical published in Philadelphia in the 19th century.
|
|
50
|
+
Thought: Arthur's Magazine was started in 1844. I need to search First for Women next.
|
|
52
51
|
Action: Search[First for Women]
|
|
53
|
-
Observation: First for Women is a woman
|
|
54
|
-
Thought: First for Women was started in 1989. 1844 (Arthur
|
|
55
|
-
Action: Finish[Arthur
|
|
52
|
+
Observation: First for Women is a woman's magazine published by Bauer Media Group in the USA.[1] The magazine was started in 1989.
|
|
53
|
+
Thought: First for Women was started in 1989. 1844 (Arthur's Magazine) < 1989 (First for Women), so Arthur's Magazine was started first.
|
|
54
|
+
Action: Finish[Arthur's Magazine]""", # noqa: E501
|
|
56
55
|
"""Question: Were Pavel Urysohn and Leonid Levin known for the same type of work?
|
|
57
56
|
Thought: I need to search Pavel Urysohn and Leonid Levin, find their types of work, then find if they are the same.
|
|
58
57
|
Action: Search[Pavel Urysohn]
|
|
@@ -61,7 +60,7 @@ Thought: Pavel Urysohn is a mathematician. I need to search Leonid Levin next an
|
|
|
61
60
|
Action: Search[Leonid Levin]
|
|
62
61
|
Observation: Leonid Anatolievich Levin is a Soviet-American mathematician and computer scientist.
|
|
63
62
|
Thought: Leonid Levin is a mathematician and computer scientist. So Pavel Urysohn and Leonid Levin have the same type of work.
|
|
64
|
-
Action: Finish[yes]""",
|
|
63
|
+
Action: Finish[yes]""", # noqa: E501
|
|
65
64
|
]
|
|
66
65
|
SUFFIX = """\nQuestion: {input}
|
|
67
66
|
{agent_scratchpad}"""
|
langchain/agents/schema.py
CHANGED
|
@@ -2,17 +2,20 @@ from typing import Any
|
|
|
2
2
|
|
|
3
3
|
from langchain_core.agents import AgentAction
|
|
4
4
|
from langchain_core.prompts.chat import ChatPromptTemplate
|
|
5
|
+
from typing_extensions import override
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class AgentScratchPadChatPromptTemplate(ChatPromptTemplate):
|
|
8
9
|
"""Chat prompt template for the agent scratchpad."""
|
|
9
10
|
|
|
10
11
|
@classmethod
|
|
12
|
+
@override
|
|
11
13
|
def is_lc_serializable(cls) -> bool:
|
|
12
14
|
return False
|
|
13
15
|
|
|
14
16
|
def _construct_agent_scratchpad(
|
|
15
|
-
self,
|
|
17
|
+
self,
|
|
18
|
+
intermediate_steps: list[tuple[AgentAction, str]],
|
|
16
19
|
) -> str:
|
|
17
20
|
if len(intermediate_steps) == 0:
|
|
18
21
|
return ""
|
|
@@ -29,6 +32,6 @@ class AgentScratchPadChatPromptTemplate(ChatPromptTemplate):
|
|
|
29
32
|
def _merge_partial_and_user_variables(self, **kwargs: Any) -> dict[str, Any]:
|
|
30
33
|
intermediate_steps = kwargs.pop("intermediate_steps")
|
|
31
34
|
kwargs["agent_scratchpad"] = self._construct_agent_scratchpad(
|
|
32
|
-
intermediate_steps
|
|
35
|
+
intermediate_steps,
|
|
33
36
|
)
|
|
34
37
|
return kwargs
|
|
@@ -11,6 +11,7 @@ from langchain_core.prompts import BasePromptTemplate
|
|
|
11
11
|
from langchain_core.runnables import Runnable, RunnablePassthrough
|
|
12
12
|
from langchain_core.tools import BaseTool, Tool
|
|
13
13
|
from pydantic import Field
|
|
14
|
+
from typing_extensions import override
|
|
14
15
|
|
|
15
16
|
from langchain.agents.agent import Agent, AgentExecutor, AgentOutputParser
|
|
16
17
|
from langchain.agents.agent_types import AgentType
|
|
@@ -32,6 +33,7 @@ class SelfAskWithSearchAgent(Agent):
|
|
|
32
33
|
output_parser: AgentOutputParser = Field(default_factory=SelfAskOutputParser)
|
|
33
34
|
|
|
34
35
|
@classmethod
|
|
36
|
+
@override
|
|
35
37
|
def _get_default_output_parser(cls, **kwargs: Any) -> AgentOutputParser:
|
|
36
38
|
return SelfAskOutputParser()
|
|
37
39
|
|
|
@@ -41,6 +43,7 @@ class SelfAskWithSearchAgent(Agent):
|
|
|
41
43
|
return AgentType.SELF_ASK_WITH_SEARCH
|
|
42
44
|
|
|
43
45
|
@classmethod
|
|
46
|
+
@override
|
|
44
47
|
def create_prompt(cls, tools: Sequence[BaseTool]) -> BasePromptTemplate:
|
|
45
48
|
"""Prompt does not depend on tools."""
|
|
46
49
|
return PROMPT
|
|
@@ -50,12 +53,12 @@ class SelfAskWithSearchAgent(Agent):
|
|
|
50
53
|
validate_tools_single_input(cls.__name__, tools)
|
|
51
54
|
super()._validate_tools(tools)
|
|
52
55
|
if len(tools) != 1:
|
|
53
|
-
|
|
56
|
+
msg = f"Exactly one tool must be specified, but got {tools}"
|
|
57
|
+
raise ValueError(msg)
|
|
54
58
|
tool_names = {tool.name for tool in tools}
|
|
55
59
|
if tool_names != {"Intermediate Answer"}:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
)
|
|
60
|
+
msg = f"Tool name should be Intermediate Answer, got {tool_names}"
|
|
61
|
+
raise ValueError(msg)
|
|
59
62
|
|
|
60
63
|
@property
|
|
61
64
|
def observation_prefix(self) -> str:
|
|
@@ -76,7 +79,9 @@ class SelfAskWithSearchChain(AgentExecutor):
|
|
|
76
79
|
self,
|
|
77
80
|
llm: BaseLanguageModel,
|
|
78
81
|
search_chain: Union[
|
|
79
|
-
GoogleSerperAPIWrapper,
|
|
82
|
+
GoogleSerperAPIWrapper,
|
|
83
|
+
SearchApiAPIWrapper,
|
|
84
|
+
SerpAPIWrapper,
|
|
80
85
|
],
|
|
81
86
|
**kwargs: Any,
|
|
82
87
|
):
|
|
@@ -92,7 +97,9 @@ class SelfAskWithSearchChain(AgentExecutor):
|
|
|
92
97
|
|
|
93
98
|
|
|
94
99
|
def create_self_ask_with_search_agent(
|
|
95
|
-
llm: BaseLanguageModel,
|
|
100
|
+
llm: BaseLanguageModel,
|
|
101
|
+
tools: Sequence[BaseTool],
|
|
102
|
+
prompt: BasePromptTemplate,
|
|
96
103
|
) -> Runnable:
|
|
97
104
|
"""Create an agent that uses self-ask with search prompting.
|
|
98
105
|
|
|
@@ -178,23 +185,25 @@ def create_self_ask_with_search_agent(
|
|
|
178
185
|
Are followup questions needed here:{agent_scratchpad}'''
|
|
179
186
|
|
|
180
187
|
prompt = PromptTemplate.from_template(template)
|
|
188
|
+
|
|
181
189
|
""" # noqa: E501
|
|
182
190
|
missing_vars = {"agent_scratchpad"}.difference(
|
|
183
|
-
prompt.input_variables + list(prompt.partial_variables)
|
|
191
|
+
prompt.input_variables + list(prompt.partial_variables),
|
|
184
192
|
)
|
|
185
193
|
if missing_vars:
|
|
186
|
-
|
|
194
|
+
msg = f"Prompt missing required variables: {missing_vars}"
|
|
195
|
+
raise ValueError(msg)
|
|
187
196
|
|
|
188
197
|
if len(tools) != 1:
|
|
189
|
-
|
|
190
|
-
|
|
198
|
+
msg = "This agent expects exactly one tool"
|
|
199
|
+
raise ValueError(msg)
|
|
200
|
+
tool = next(iter(tools))
|
|
191
201
|
if tool.name != "Intermediate Answer":
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
)
|
|
202
|
+
msg = "This agent expects the tool to be named `Intermediate Answer`"
|
|
203
|
+
raise ValueError(msg)
|
|
195
204
|
|
|
196
205
|
llm_with_stop = llm.bind(stop=["\nIntermediate answer:"])
|
|
197
|
-
|
|
206
|
+
return (
|
|
198
207
|
RunnablePassthrough.assign(
|
|
199
208
|
agent_scratchpad=lambda x: format_log_to_str(
|
|
200
209
|
x["intermediate_steps"],
|
|
@@ -208,4 +217,3 @@ def create_self_ask_with_search_agent(
|
|
|
208
217
|
| llm_with_stop
|
|
209
218
|
| SelfAskOutputParser()
|
|
210
219
|
)
|
|
211
|
-
return agent
|
|
@@ -16,6 +16,7 @@ from langchain_core.runnables import Runnable, RunnablePassthrough
|
|
|
16
16
|
from langchain_core.tools import BaseTool
|
|
17
17
|
from langchain_core.tools.render import ToolsRenderer
|
|
18
18
|
from pydantic import Field
|
|
19
|
+
from typing_extensions import override
|
|
19
20
|
|
|
20
21
|
from langchain.agents.agent import Agent, AgentOutputParser
|
|
21
22
|
from langchain.agents.format_scratchpad import format_log_to_str
|
|
@@ -35,7 +36,7 @@ class StructuredChatAgent(Agent):
|
|
|
35
36
|
"""Structured Chat Agent."""
|
|
36
37
|
|
|
37
38
|
output_parser: AgentOutputParser = Field(
|
|
38
|
-
default_factory=StructuredChatOutputParserWithRetries
|
|
39
|
+
default_factory=StructuredChatOutputParserWithRetries,
|
|
39
40
|
)
|
|
40
41
|
"""Output parser for the agent."""
|
|
41
42
|
|
|
@@ -50,35 +51,41 @@ class StructuredChatAgent(Agent):
|
|
|
50
51
|
return "Thought:"
|
|
51
52
|
|
|
52
53
|
def _construct_scratchpad(
|
|
53
|
-
self,
|
|
54
|
+
self,
|
|
55
|
+
intermediate_steps: list[tuple[AgentAction, str]],
|
|
54
56
|
) -> str:
|
|
55
57
|
agent_scratchpad = super()._construct_scratchpad(intermediate_steps)
|
|
56
58
|
if not isinstance(agent_scratchpad, str):
|
|
57
|
-
|
|
59
|
+
msg = "agent_scratchpad should be of type string."
|
|
60
|
+
raise ValueError(msg) # noqa: TRY004
|
|
58
61
|
if agent_scratchpad:
|
|
59
62
|
return (
|
|
60
63
|
f"This was your previous work "
|
|
61
64
|
f"(but I haven't seen any of it! I only see what "
|
|
62
65
|
f"you return as final answer):\n{agent_scratchpad}"
|
|
63
66
|
)
|
|
64
|
-
|
|
65
|
-
return agent_scratchpad
|
|
67
|
+
return agent_scratchpad
|
|
66
68
|
|
|
67
69
|
@classmethod
|
|
68
70
|
def _validate_tools(cls, tools: Sequence[BaseTool]) -> None:
|
|
69
71
|
pass
|
|
70
72
|
|
|
71
73
|
@classmethod
|
|
74
|
+
@override
|
|
72
75
|
def _get_default_output_parser(
|
|
73
|
-
cls,
|
|
76
|
+
cls,
|
|
77
|
+
llm: Optional[BaseLanguageModel] = None,
|
|
78
|
+
**kwargs: Any,
|
|
74
79
|
) -> AgentOutputParser:
|
|
75
80
|
return StructuredChatOutputParserWithRetries.from_llm(llm=llm)
|
|
76
81
|
|
|
77
82
|
@property
|
|
83
|
+
@override
|
|
78
84
|
def _stop(self) -> list[str]:
|
|
79
85
|
return ["Observation:"]
|
|
80
86
|
|
|
81
87
|
@classmethod
|
|
88
|
+
@override
|
|
82
89
|
def create_prompt(
|
|
83
90
|
cls,
|
|
84
91
|
tools: Sequence[BaseTool],
|
|
@@ -96,7 +103,7 @@ class StructuredChatAgent(Agent):
|
|
|
96
103
|
formatted_tools = "\n".join(tool_strings)
|
|
97
104
|
tool_names = ", ".join([tool.name for tool in tools])
|
|
98
105
|
format_instructions = format_instructions.format(tool_names=tool_names)
|
|
99
|
-
template = "\n\n
|
|
106
|
+
template = f"{prefix}\n\n{formatted_tools}\n\n{format_instructions}\n\n{suffix}"
|
|
100
107
|
if input_variables is None:
|
|
101
108
|
input_variables = ["input", "agent_scratchpad"]
|
|
102
109
|
_memory_prompts = memory_prompts or []
|
|
@@ -273,12 +280,14 @@ def create_structured_chat_agent(
|
|
|
273
280
|
("human", human),
|
|
274
281
|
]
|
|
275
282
|
)
|
|
283
|
+
|
|
276
284
|
""" # noqa: E501
|
|
277
285
|
missing_vars = {"tools", "tool_names", "agent_scratchpad"}.difference(
|
|
278
|
-
prompt.input_variables + list(prompt.partial_variables)
|
|
286
|
+
prompt.input_variables + list(prompt.partial_variables),
|
|
279
287
|
)
|
|
280
288
|
if missing_vars:
|
|
281
|
-
|
|
289
|
+
msg = f"Prompt missing required variables: {missing_vars}"
|
|
290
|
+
raise ValueError(msg)
|
|
282
291
|
|
|
283
292
|
prompt = prompt.partial(
|
|
284
293
|
tools=tools_renderer(list(tools)),
|
|
@@ -290,7 +299,7 @@ def create_structured_chat_agent(
|
|
|
290
299
|
else:
|
|
291
300
|
llm_with_stop = llm
|
|
292
301
|
|
|
293
|
-
|
|
302
|
+
return (
|
|
294
303
|
RunnablePassthrough.assign(
|
|
295
304
|
agent_scratchpad=lambda x: format_log_to_str(x["intermediate_steps"]),
|
|
296
305
|
)
|
|
@@ -298,4 +307,3 @@ def create_structured_chat_agent(
|
|
|
298
307
|
| llm_with_stop
|
|
299
308
|
| JSONAgentOutputParser()
|
|
300
309
|
)
|
|
301
|
-
return agent
|