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
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import inspect
|
|
6
|
-
import warnings
|
|
7
6
|
from abc import abstractmethod
|
|
8
7
|
from typing import Any, Optional
|
|
9
8
|
|
|
@@ -19,6 +18,7 @@ from langchain_core.prompts import PromptTemplate
|
|
|
19
18
|
from langchain_core.retrievers import BaseRetriever
|
|
20
19
|
from langchain_core.vectorstores import VectorStore
|
|
21
20
|
from pydantic import ConfigDict, Field, model_validator
|
|
21
|
+
from typing_extensions import override
|
|
22
22
|
|
|
23
23
|
from langchain.chains.base import Chain
|
|
24
24
|
from langchain.chains.combine_documents.base import BaseCombineDocumentsChain
|
|
@@ -69,7 +69,7 @@ class BaseRetrievalQA(Chain):
|
|
|
69
69
|
"""
|
|
70
70
|
_output_keys = [self.output_key]
|
|
71
71
|
if self.return_source_documents:
|
|
72
|
-
_output_keys = _output_keys
|
|
72
|
+
_output_keys = [*_output_keys, "source_documents"]
|
|
73
73
|
return _output_keys
|
|
74
74
|
|
|
75
75
|
@classmethod
|
|
@@ -84,10 +84,14 @@ class BaseRetrievalQA(Chain):
|
|
|
84
84
|
"""Initialize from LLM."""
|
|
85
85
|
_prompt = prompt or PROMPT_SELECTOR.get_prompt(llm)
|
|
86
86
|
llm_chain = LLMChain(
|
|
87
|
-
llm=llm,
|
|
87
|
+
llm=llm,
|
|
88
|
+
prompt=_prompt,
|
|
89
|
+
callbacks=callbacks,
|
|
90
|
+
**(llm_chain_kwargs or {}),
|
|
88
91
|
)
|
|
89
92
|
document_prompt = PromptTemplate(
|
|
90
|
-
input_variables=["page_content"],
|
|
93
|
+
input_variables=["page_content"],
|
|
94
|
+
template="Context:\n{page_content}",
|
|
91
95
|
)
|
|
92
96
|
combine_documents_chain = StuffDocumentsChain(
|
|
93
97
|
llm_chain=llm_chain,
|
|
@@ -113,7 +117,9 @@ class BaseRetrievalQA(Chain):
|
|
|
113
117
|
"""Load chain from chain type."""
|
|
114
118
|
_chain_type_kwargs = chain_type_kwargs or {}
|
|
115
119
|
combine_documents_chain = load_qa_chain(
|
|
116
|
-
llm,
|
|
120
|
+
llm,
|
|
121
|
+
chain_type=chain_type,
|
|
122
|
+
**_chain_type_kwargs,
|
|
117
123
|
)
|
|
118
124
|
return cls(combine_documents_chain=combine_documents_chain, **kwargs)
|
|
119
125
|
|
|
@@ -141,6 +147,7 @@ class BaseRetrievalQA(Chain):
|
|
|
141
147
|
|
|
142
148
|
res = indexqa({'query': 'This is my query'})
|
|
143
149
|
answer, docs = res['result'], res['source_documents']
|
|
150
|
+
|
|
144
151
|
"""
|
|
145
152
|
_run_manager = run_manager or CallbackManagerForChainRun.get_noop_manager()
|
|
146
153
|
question = inputs[self.input_key]
|
|
@@ -152,13 +159,14 @@ class BaseRetrievalQA(Chain):
|
|
|
152
159
|
else:
|
|
153
160
|
docs = self._get_docs(question) # type: ignore[call-arg]
|
|
154
161
|
answer = self.combine_documents_chain.run(
|
|
155
|
-
input_documents=docs,
|
|
162
|
+
input_documents=docs,
|
|
163
|
+
question=question,
|
|
164
|
+
callbacks=_run_manager.get_child(),
|
|
156
165
|
)
|
|
157
166
|
|
|
158
167
|
if self.return_source_documents:
|
|
159
168
|
return {self.output_key: answer, "source_documents": docs}
|
|
160
|
-
|
|
161
|
-
return {self.output_key: answer}
|
|
169
|
+
return {self.output_key: answer}
|
|
162
170
|
|
|
163
171
|
@abstractmethod
|
|
164
172
|
async def _aget_docs(
|
|
@@ -184,6 +192,7 @@ class BaseRetrievalQA(Chain):
|
|
|
184
192
|
|
|
185
193
|
res = indexqa({'query': 'This is my query'})
|
|
186
194
|
answer, docs = res['result'], res['source_documents']
|
|
195
|
+
|
|
187
196
|
"""
|
|
188
197
|
_run_manager = run_manager or AsyncCallbackManagerForChainRun.get_noop_manager()
|
|
189
198
|
question = inputs[self.input_key]
|
|
@@ -195,13 +204,14 @@ class BaseRetrievalQA(Chain):
|
|
|
195
204
|
else:
|
|
196
205
|
docs = await self._aget_docs(question) # type: ignore[call-arg]
|
|
197
206
|
answer = await self.combine_documents_chain.arun(
|
|
198
|
-
input_documents=docs,
|
|
207
|
+
input_documents=docs,
|
|
208
|
+
question=question,
|
|
209
|
+
callbacks=_run_manager.get_child(),
|
|
199
210
|
)
|
|
200
211
|
|
|
201
212
|
if self.return_source_documents:
|
|
202
213
|
return {self.output_key: answer, "source_documents": docs}
|
|
203
|
-
|
|
204
|
-
return {self.output_key: answer}
|
|
214
|
+
return {self.output_key: answer}
|
|
205
215
|
|
|
206
216
|
|
|
207
217
|
@deprecated(
|
|
@@ -269,7 +279,8 @@ class RetrievalQA(BaseRetrievalQA):
|
|
|
269
279
|
) -> list[Document]:
|
|
270
280
|
"""Get docs."""
|
|
271
281
|
return self.retriever.invoke(
|
|
272
|
-
question,
|
|
282
|
+
question,
|
|
283
|
+
config={"callbacks": run_manager.get_child()},
|
|
273
284
|
)
|
|
274
285
|
|
|
275
286
|
async def _aget_docs(
|
|
@@ -280,7 +291,8 @@ class RetrievalQA(BaseRetrievalQA):
|
|
|
280
291
|
) -> list[Document]:
|
|
281
292
|
"""Get docs."""
|
|
282
293
|
return await self.retriever.ainvoke(
|
|
283
|
-
question,
|
|
294
|
+
question,
|
|
295
|
+
config={"callbacks": run_manager.get_child()},
|
|
284
296
|
)
|
|
285
297
|
|
|
286
298
|
@property
|
|
@@ -310,15 +322,6 @@ class VectorDBQA(BaseRetrievalQA):
|
|
|
310
322
|
search_kwargs: dict[str, Any] = Field(default_factory=dict)
|
|
311
323
|
"""Extra search args."""
|
|
312
324
|
|
|
313
|
-
@model_validator(mode="before")
|
|
314
|
-
@classmethod
|
|
315
|
-
def raise_deprecation(cls, values: dict) -> Any:
|
|
316
|
-
warnings.warn(
|
|
317
|
-
"`VectorDBQA` is deprecated - "
|
|
318
|
-
"please use `from langchain.chains import RetrievalQA`"
|
|
319
|
-
)
|
|
320
|
-
return values
|
|
321
|
-
|
|
322
325
|
@model_validator(mode="before")
|
|
323
326
|
@classmethod
|
|
324
327
|
def validate_search_type(cls, values: dict) -> Any:
|
|
@@ -326,9 +329,11 @@ class VectorDBQA(BaseRetrievalQA):
|
|
|
326
329
|
if "search_type" in values:
|
|
327
330
|
search_type = values["search_type"]
|
|
328
331
|
if search_type not in ("similarity", "mmr"):
|
|
329
|
-
|
|
332
|
+
msg = f"search_type of {search_type} not allowed."
|
|
333
|
+
raise ValueError(msg)
|
|
330
334
|
return values
|
|
331
335
|
|
|
336
|
+
@override
|
|
332
337
|
def _get_docs(
|
|
333
338
|
self,
|
|
334
339
|
question: str,
|
|
@@ -338,14 +343,19 @@ class VectorDBQA(BaseRetrievalQA):
|
|
|
338
343
|
"""Get docs."""
|
|
339
344
|
if self.search_type == "similarity":
|
|
340
345
|
docs = self.vectorstore.similarity_search(
|
|
341
|
-
question,
|
|
346
|
+
question,
|
|
347
|
+
k=self.k,
|
|
348
|
+
**self.search_kwargs,
|
|
342
349
|
)
|
|
343
350
|
elif self.search_type == "mmr":
|
|
344
351
|
docs = self.vectorstore.max_marginal_relevance_search(
|
|
345
|
-
question,
|
|
352
|
+
question,
|
|
353
|
+
k=self.k,
|
|
354
|
+
**self.search_kwargs,
|
|
346
355
|
)
|
|
347
356
|
else:
|
|
348
|
-
|
|
357
|
+
msg = f"search_type of {self.search_type} not allowed."
|
|
358
|
+
raise ValueError(msg)
|
|
349
359
|
return docs
|
|
350
360
|
|
|
351
361
|
async def _aget_docs(
|
|
@@ -355,7 +365,8 @@ class VectorDBQA(BaseRetrievalQA):
|
|
|
355
365
|
run_manager: AsyncCallbackManagerForChainRun,
|
|
356
366
|
) -> list[Document]:
|
|
357
367
|
"""Get docs."""
|
|
358
|
-
|
|
368
|
+
msg = "VectorDBQA does not support async"
|
|
369
|
+
raise NotImplementedError(msg)
|
|
359
370
|
|
|
360
371
|
@property
|
|
361
372
|
def _chain_type(self) -> str:
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# flake8: noqa
|
|
2
1
|
from langchain_core.prompts import PromptTemplate
|
|
3
2
|
|
|
4
3
|
prompt_template = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.
|
|
@@ -6,7 +5,7 @@ prompt_template = """Use the following pieces of context to answer the question
|
|
|
6
5
|
{context}
|
|
7
6
|
|
|
8
7
|
Question: {question}
|
|
9
|
-
Helpful Answer:"""
|
|
8
|
+
Helpful Answer:""" # noqa: E501
|
|
10
9
|
PROMPT = PromptTemplate(
|
|
11
10
|
template=prompt_template, input_variables=["context", "question"]
|
|
12
11
|
)
|
|
@@ -4,9 +4,9 @@ from langchain.chains.router.multi_prompt import MultiPromptChain
|
|
|
4
4
|
from langchain.chains.router.multi_retrieval_qa import MultiRetrievalQAChain
|
|
5
5
|
|
|
6
6
|
__all__ = [
|
|
7
|
-
"
|
|
8
|
-
"MultiRouteChain",
|
|
7
|
+
"LLMRouterChain",
|
|
9
8
|
"MultiPromptChain",
|
|
10
9
|
"MultiRetrievalQAChain",
|
|
11
|
-
"
|
|
10
|
+
"MultiRouteChain",
|
|
11
|
+
"RouterChain",
|
|
12
12
|
]
|
langchain/chains/router/base.py
CHANGED
|
@@ -12,11 +12,14 @@ from langchain_core.callbacks import (
|
|
|
12
12
|
Callbacks,
|
|
13
13
|
)
|
|
14
14
|
from pydantic import ConfigDict
|
|
15
|
+
from typing_extensions import override
|
|
15
16
|
|
|
16
17
|
from langchain.chains.base import Chain
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class Route(NamedTuple):
|
|
21
|
+
"""A route to a destination chain."""
|
|
22
|
+
|
|
20
23
|
destination: Optional[str]
|
|
21
24
|
next_inputs: dict[str, Any]
|
|
22
25
|
|
|
@@ -25,12 +28,12 @@ class RouterChain(Chain, ABC):
|
|
|
25
28
|
"""Chain that outputs the name of a destination chain and the inputs to it."""
|
|
26
29
|
|
|
27
30
|
@property
|
|
31
|
+
@override
|
|
28
32
|
def output_keys(self) -> list[str]:
|
|
29
33
|
return ["destination", "next_inputs"]
|
|
30
34
|
|
|
31
35
|
def route(self, inputs: dict[str, Any], callbacks: Callbacks = None) -> Route:
|
|
32
|
-
"""
|
|
33
|
-
Route inputs to a destination chain.
|
|
36
|
+
"""Route inputs to a destination chain.
|
|
34
37
|
|
|
35
38
|
Args:
|
|
36
39
|
inputs: inputs to the chain
|
|
@@ -43,8 +46,19 @@ class RouterChain(Chain, ABC):
|
|
|
43
46
|
return Route(result["destination"], result["next_inputs"])
|
|
44
47
|
|
|
45
48
|
async def aroute(
|
|
46
|
-
self,
|
|
49
|
+
self,
|
|
50
|
+
inputs: dict[str, Any],
|
|
51
|
+
callbacks: Callbacks = None,
|
|
47
52
|
) -> Route:
|
|
53
|
+
"""Route inputs to a destination chain.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
inputs: inputs to the chain
|
|
57
|
+
callbacks: callbacks to use for the chain
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
a Route object
|
|
61
|
+
"""
|
|
48
62
|
result = await self.acall(inputs, callbacks=callbacks)
|
|
49
63
|
return Route(result["destination"], result["next_inputs"])
|
|
50
64
|
|
|
@@ -59,7 +73,7 @@ class MultiRouteChain(Chain):
|
|
|
59
73
|
default_chain: Chain
|
|
60
74
|
"""Default chain to use when none of the destination chains are suitable."""
|
|
61
75
|
silent_errors: bool = False
|
|
62
|
-
"""If True, use default_chain when an invalid destination name is provided.
|
|
76
|
+
"""If True, use default_chain when an invalid destination name is provided.
|
|
63
77
|
Defaults to False."""
|
|
64
78
|
|
|
65
79
|
model_config = ConfigDict(
|
|
@@ -93,20 +107,20 @@ class MultiRouteChain(Chain):
|
|
|
93
107
|
route = self.router_chain.route(inputs, callbacks=callbacks)
|
|
94
108
|
|
|
95
109
|
_run_manager.on_text(
|
|
96
|
-
str(route.destination) + ": " + str(route.next_inputs),
|
|
110
|
+
str(route.destination) + ": " + str(route.next_inputs),
|
|
111
|
+
verbose=self.verbose,
|
|
97
112
|
)
|
|
98
113
|
if not route.destination:
|
|
99
114
|
return self.default_chain(route.next_inputs, callbacks=callbacks)
|
|
100
|
-
|
|
115
|
+
if route.destination in self.destination_chains:
|
|
101
116
|
return self.destination_chains[route.destination](
|
|
102
|
-
route.next_inputs,
|
|
117
|
+
route.next_inputs,
|
|
118
|
+
callbacks=callbacks,
|
|
103
119
|
)
|
|
104
|
-
|
|
120
|
+
if self.silent_errors:
|
|
105
121
|
return self.default_chain(route.next_inputs, callbacks=callbacks)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
f"Received invalid destination chain name '{route.destination}'"
|
|
109
|
-
)
|
|
122
|
+
msg = f"Received invalid destination chain name '{route.destination}'"
|
|
123
|
+
raise ValueError(msg)
|
|
110
124
|
|
|
111
125
|
async def _acall(
|
|
112
126
|
self,
|
|
@@ -118,21 +132,23 @@ class MultiRouteChain(Chain):
|
|
|
118
132
|
route = await self.router_chain.aroute(inputs, callbacks=callbacks)
|
|
119
133
|
|
|
120
134
|
await _run_manager.on_text(
|
|
121
|
-
str(route.destination) + ": " + str(route.next_inputs),
|
|
135
|
+
str(route.destination) + ": " + str(route.next_inputs),
|
|
136
|
+
verbose=self.verbose,
|
|
122
137
|
)
|
|
123
138
|
if not route.destination:
|
|
124
139
|
return await self.default_chain.acall(
|
|
125
|
-
route.next_inputs,
|
|
140
|
+
route.next_inputs,
|
|
141
|
+
callbacks=callbacks,
|
|
126
142
|
)
|
|
127
|
-
|
|
143
|
+
if route.destination in self.destination_chains:
|
|
128
144
|
return await self.destination_chains[route.destination].acall(
|
|
129
|
-
route.next_inputs,
|
|
145
|
+
route.next_inputs,
|
|
146
|
+
callbacks=callbacks,
|
|
130
147
|
)
|
|
131
|
-
|
|
148
|
+
if self.silent_errors:
|
|
132
149
|
return await self.default_chain.acall(
|
|
133
|
-
route.next_inputs,
|
|
134
|
-
|
|
135
|
-
else:
|
|
136
|
-
raise ValueError(
|
|
137
|
-
f"Received invalid destination chain name '{route.destination}'"
|
|
150
|
+
route.next_inputs,
|
|
151
|
+
callbacks=callbacks,
|
|
138
152
|
)
|
|
153
|
+
msg = f"Received invalid destination chain name '{route.destination}'"
|
|
154
|
+
raise ValueError(msg)
|
|
@@ -11,6 +11,7 @@ from langchain_core.documents import Document
|
|
|
11
11
|
from langchain_core.embeddings import Embeddings
|
|
12
12
|
from langchain_core.vectorstores import VectorStore
|
|
13
13
|
from pydantic import ConfigDict
|
|
14
|
+
from typing_extensions import override
|
|
14
15
|
|
|
15
16
|
from langchain.chains.router.base import RouterChain
|
|
16
17
|
|
|
@@ -34,6 +35,7 @@ class EmbeddingRouterChain(RouterChain):
|
|
|
34
35
|
"""
|
|
35
36
|
return self.routing_keys
|
|
36
37
|
|
|
38
|
+
@override
|
|
37
39
|
def _call(
|
|
38
40
|
self,
|
|
39
41
|
inputs: dict[str, Any],
|
|
@@ -43,6 +45,7 @@ class EmbeddingRouterChain(RouterChain):
|
|
|
43
45
|
results = self.vectorstore.similarity_search(_input, k=1)
|
|
44
46
|
return {"next_inputs": inputs, "destination": results[0].metadata["name"]}
|
|
45
47
|
|
|
48
|
+
@override
|
|
46
49
|
async def _acall(
|
|
47
50
|
self,
|
|
48
51
|
inputs: dict[str, Any],
|
|
@@ -63,10 +66,12 @@ class EmbeddingRouterChain(RouterChain):
|
|
|
63
66
|
"""Convenience constructor."""
|
|
64
67
|
documents = []
|
|
65
68
|
for name, descriptions in names_and_descriptions:
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
documents.extend(
|
|
70
|
+
[
|
|
68
71
|
Document(page_content=description, metadata={"name": name})
|
|
69
|
-
|
|
72
|
+
for description in descriptions
|
|
73
|
+
]
|
|
74
|
+
)
|
|
70
75
|
vectorstore = vectorstore_cls.from_documents(documents, embeddings)
|
|
71
76
|
return cls(vectorstore=vectorstore, **kwargs)
|
|
72
77
|
|
|
@@ -80,10 +85,12 @@ class EmbeddingRouterChain(RouterChain):
|
|
|
80
85
|
) -> EmbeddingRouterChain:
|
|
81
86
|
"""Convenience constructor."""
|
|
82
87
|
documents = []
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
documents.extend(
|
|
89
|
+
[
|
|
90
|
+
Document(page_content=description, metadata={"name": name})
|
|
91
|
+
for name, descriptions in names_and_descriptions
|
|
92
|
+
for description in descriptions
|
|
93
|
+
]
|
|
94
|
+
)
|
|
88
95
|
vectorstore = await vectorstore_cls.afrom_documents(documents, embeddings)
|
|
89
96
|
return cls(vectorstore=vectorstore, **kwargs)
|
|
@@ -15,7 +15,7 @@ from langchain_core.output_parsers import BaseOutputParser
|
|
|
15
15
|
from langchain_core.prompts import BasePromptTemplate
|
|
16
16
|
from langchain_core.utils.json import parse_and_check_json_markdown
|
|
17
17
|
from pydantic import model_validator
|
|
18
|
-
from typing_extensions import Self
|
|
18
|
+
from typing_extensions import Self, override
|
|
19
19
|
|
|
20
20
|
from langchain.chains import LLMChain
|
|
21
21
|
from langchain.chains.router.base import RouterChain
|
|
@@ -27,7 +27,7 @@ from langchain.chains.router.base import RouterChain
|
|
|
27
27
|
message=(
|
|
28
28
|
"Use RunnableLambda to select from multiple prompt templates. See example "
|
|
29
29
|
"in API reference: "
|
|
30
|
-
"https://api.python.langchain.com/en/latest/chains/langchain.chains.router.llm_router.LLMRouterChain.html"
|
|
30
|
+
"https://api.python.langchain.com/en/latest/chains/langchain.chains.router.llm_router.LLMRouterChain.html"
|
|
31
31
|
),
|
|
32
32
|
)
|
|
33
33
|
class LLMRouterChain(RouterChain):
|
|
@@ -96,21 +96,23 @@ class LLMRouterChain(RouterChain):
|
|
|
96
96
|
)
|
|
97
97
|
|
|
98
98
|
chain.invoke({"query": "what color are carrots"})
|
|
99
|
+
|
|
99
100
|
""" # noqa: E501
|
|
100
101
|
|
|
101
102
|
llm_chain: LLMChain
|
|
102
103
|
"""LLM chain used to perform routing"""
|
|
103
104
|
|
|
104
105
|
@model_validator(mode="after")
|
|
105
|
-
def
|
|
106
|
+
def _validate_prompt(self) -> Self:
|
|
106
107
|
prompt = self.llm_chain.prompt
|
|
107
108
|
if prompt.output_parser is None:
|
|
108
|
-
|
|
109
|
+
msg = (
|
|
109
110
|
"LLMRouterChain requires base llm_chain prompt to have an output"
|
|
110
111
|
" parser that converts LLM text output to a dictionary with keys"
|
|
111
112
|
" 'destination' and 'next_inputs'. Received a prompt with no output"
|
|
112
113
|
" parser."
|
|
113
114
|
)
|
|
115
|
+
raise ValueError(msg)
|
|
114
116
|
return self
|
|
115
117
|
|
|
116
118
|
@property
|
|
@@ -124,7 +126,7 @@ class LLMRouterChain(RouterChain):
|
|
|
124
126
|
def _validate_outputs(self, outputs: dict[str, Any]) -> None:
|
|
125
127
|
super()._validate_outputs(outputs)
|
|
126
128
|
if not isinstance(outputs["next_inputs"], dict):
|
|
127
|
-
raise ValueError
|
|
129
|
+
raise ValueError # noqa: TRY004
|
|
128
130
|
|
|
129
131
|
def _call(
|
|
130
132
|
self,
|
|
@@ -135,11 +137,10 @@ class LLMRouterChain(RouterChain):
|
|
|
135
137
|
callbacks = _run_manager.get_child()
|
|
136
138
|
|
|
137
139
|
prediction = self.llm_chain.predict(callbacks=callbacks, **inputs)
|
|
138
|
-
|
|
139
|
-
dict[str, Any],
|
|
140
|
+
return cast(
|
|
141
|
+
"dict[str, Any]",
|
|
140
142
|
self.llm_chain.prompt.output_parser.parse(prediction),
|
|
141
143
|
)
|
|
142
|
-
return output
|
|
143
144
|
|
|
144
145
|
async def _acall(
|
|
145
146
|
self,
|
|
@@ -148,15 +149,17 @@ class LLMRouterChain(RouterChain):
|
|
|
148
149
|
) -> dict[str, Any]:
|
|
149
150
|
_run_manager = run_manager or CallbackManagerForChainRun.get_noop_manager()
|
|
150
151
|
callbacks = _run_manager.get_child()
|
|
151
|
-
|
|
152
|
-
dict[str, Any],
|
|
152
|
+
return cast(
|
|
153
|
+
"dict[str, Any]",
|
|
153
154
|
await self.llm_chain.apredict_and_parse(callbacks=callbacks, **inputs),
|
|
154
155
|
)
|
|
155
|
-
return output
|
|
156
156
|
|
|
157
157
|
@classmethod
|
|
158
158
|
def from_llm(
|
|
159
|
-
cls,
|
|
159
|
+
cls,
|
|
160
|
+
llm: BaseLanguageModel,
|
|
161
|
+
prompt: BasePromptTemplate,
|
|
162
|
+
**kwargs: Any,
|
|
160
163
|
) -> LLMRouterChain:
|
|
161
164
|
"""Convenience constructor."""
|
|
162
165
|
llm_chain = LLMChain(llm=llm, prompt=prompt)
|
|
@@ -170,16 +173,17 @@ class RouterOutputParser(BaseOutputParser[dict[str, str]]):
|
|
|
170
173
|
next_inputs_type: type = str
|
|
171
174
|
next_inputs_inner_key: str = "input"
|
|
172
175
|
|
|
176
|
+
@override
|
|
173
177
|
def parse(self, text: str) -> dict[str, Any]:
|
|
174
178
|
try:
|
|
175
179
|
expected_keys = ["destination", "next_inputs"]
|
|
176
180
|
parsed = parse_and_check_json_markdown(text, expected_keys)
|
|
177
181
|
if not isinstance(parsed["destination"], str):
|
|
178
|
-
|
|
182
|
+
msg = "Expected 'destination' to be a string."
|
|
183
|
+
raise TypeError(msg)
|
|
179
184
|
if not isinstance(parsed["next_inputs"], self.next_inputs_type):
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
)
|
|
185
|
+
msg = f"Expected 'next_inputs' to be {self.next_inputs_type}."
|
|
186
|
+
raise TypeError(msg)
|
|
183
187
|
parsed["next_inputs"] = {self.next_inputs_inner_key: parsed["next_inputs"]}
|
|
184
188
|
if (
|
|
185
189
|
parsed["destination"].strip().lower()
|
|
@@ -188,8 +192,7 @@ class RouterOutputParser(BaseOutputParser[dict[str, str]]):
|
|
|
188
192
|
parsed["destination"] = None
|
|
189
193
|
else:
|
|
190
194
|
parsed["destination"] = parsed["destination"].strip()
|
|
191
|
-
return parsed
|
|
192
195
|
except Exception as e:
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
+
msg = f"Parsing text\n{text}\n raised following error:\n{e}"
|
|
197
|
+
raise OutputParserException(msg) from e
|
|
198
|
+
return parsed
|
|
@@ -7,6 +7,7 @@ from typing import Any, Optional
|
|
|
7
7
|
from langchain_core._api import deprecated
|
|
8
8
|
from langchain_core.language_models import BaseLanguageModel
|
|
9
9
|
from langchain_core.prompts import PromptTemplate
|
|
10
|
+
from typing_extensions import override
|
|
10
11
|
|
|
11
12
|
from langchain.chains import ConversationChain
|
|
12
13
|
from langchain.chains.base import Chain
|
|
@@ -21,7 +22,7 @@ from langchain.chains.router.multi_prompt_prompt import MULTI_PROMPT_ROUTER_TEMP
|
|
|
21
22
|
removal="1.0",
|
|
22
23
|
message=(
|
|
23
24
|
"Please see migration guide here for recommended implementation: "
|
|
24
|
-
"https://python.langchain.com/docs/versions/migrating_chains/multi_prompt_chain/"
|
|
25
|
+
"https://python.langchain.com/docs/versions/migrating_chains/multi_prompt_chain/"
|
|
25
26
|
),
|
|
26
27
|
)
|
|
27
28
|
class MultiPromptChain(MultiRouteChain):
|
|
@@ -139,9 +140,11 @@ class MultiPromptChain(MultiRouteChain):
|
|
|
139
140
|
result = await app.ainvoke({"query": "what color are carrots"})
|
|
140
141
|
print(result["destination"])
|
|
141
142
|
print(result["answer"])
|
|
143
|
+
|
|
142
144
|
""" # noqa: E501
|
|
143
145
|
|
|
144
146
|
@property
|
|
147
|
+
@override
|
|
145
148
|
def output_keys(self) -> list[str]:
|
|
146
149
|
return ["text"]
|
|
147
150
|
|
|
@@ -157,7 +160,7 @@ class MultiPromptChain(MultiRouteChain):
|
|
|
157
160
|
destinations = [f"{p['name']}: {p['description']}" for p in prompt_infos]
|
|
158
161
|
destinations_str = "\n".join(destinations)
|
|
159
162
|
router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(
|
|
160
|
-
destinations=destinations_str
|
|
163
|
+
destinations=destinations_str,
|
|
161
164
|
)
|
|
162
165
|
router_prompt = PromptTemplate(
|
|
163
166
|
template=router_template,
|
|
@@ -8,6 +8,7 @@ from typing import Any, Optional
|
|
|
8
8
|
from langchain_core.language_models import BaseLanguageModel
|
|
9
9
|
from langchain_core.prompts import PromptTemplate
|
|
10
10
|
from langchain_core.retrievers import BaseRetriever
|
|
11
|
+
from typing_extensions import override
|
|
11
12
|
|
|
12
13
|
from langchain.chains import ConversationChain
|
|
13
14
|
from langchain.chains.base import Chain
|
|
@@ -32,6 +33,7 @@ class MultiRetrievalQAChain(MultiRouteChain):
|
|
|
32
33
|
"""Default chain to use when router doesn't map input to one of the destinations."""
|
|
33
34
|
|
|
34
35
|
@property
|
|
36
|
+
@override
|
|
35
37
|
def output_keys(self) -> list[str]:
|
|
36
38
|
return ["result"]
|
|
37
39
|
|
|
@@ -47,15 +49,32 @@ class MultiRetrievalQAChain(MultiRouteChain):
|
|
|
47
49
|
default_chain_llm: Optional[BaseLanguageModel] = None,
|
|
48
50
|
**kwargs: Any,
|
|
49
51
|
) -> MultiRetrievalQAChain:
|
|
52
|
+
"""Create a multi retrieval qa chain from an LLM and a default chain.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
llm: The language model to use.
|
|
56
|
+
retriever_infos: Dictionaries containing retriever information.
|
|
57
|
+
default_retriever: Optional default retriever to use if no default chain
|
|
58
|
+
is provided.
|
|
59
|
+
default_prompt: Optional prompt template to use for the default retriever.
|
|
60
|
+
default_chain: Optional default chain to use when router doesn't map input
|
|
61
|
+
to one of the destinations.
|
|
62
|
+
default_chain_llm: Optional language model to use if no default chain and
|
|
63
|
+
no default retriever are provided.
|
|
64
|
+
**kwargs: Additional keyword arguments to pass to the chain.
|
|
65
|
+
Returns:
|
|
66
|
+
An instance of the multi retrieval qa chain.
|
|
67
|
+
"""
|
|
50
68
|
if default_prompt and not default_retriever:
|
|
51
|
-
|
|
69
|
+
msg = (
|
|
52
70
|
"`default_retriever` must be specified if `default_prompt` is "
|
|
53
71
|
"provided. Received only `default_prompt`."
|
|
54
72
|
)
|
|
73
|
+
raise ValueError(msg)
|
|
55
74
|
destinations = [f"{r['name']}: {r['description']}" for r in retriever_infos]
|
|
56
75
|
destinations_str = "\n".join(destinations)
|
|
57
76
|
router_template = MULTI_RETRIEVAL_ROUTER_TEMPLATE.format(
|
|
58
|
-
destinations=destinations_str
|
|
77
|
+
destinations=destinations_str,
|
|
59
78
|
)
|
|
60
79
|
router_prompt = PromptTemplate(
|
|
61
80
|
template=router_template,
|
|
@@ -74,15 +93,18 @@ class MultiRetrievalQAChain(MultiRouteChain):
|
|
|
74
93
|
_default_chain = default_chain
|
|
75
94
|
elif default_retriever:
|
|
76
95
|
_default_chain = RetrievalQA.from_llm(
|
|
77
|
-
llm,
|
|
96
|
+
llm,
|
|
97
|
+
prompt=default_prompt,
|
|
98
|
+
retriever=default_retriever,
|
|
78
99
|
)
|
|
79
100
|
else:
|
|
80
101
|
prompt_template = DEFAULT_TEMPLATE.replace("input", "query")
|
|
81
102
|
prompt = PromptTemplate(
|
|
82
|
-
template=prompt_template,
|
|
103
|
+
template=prompt_template,
|
|
104
|
+
input_variables=["history", "query"],
|
|
83
105
|
)
|
|
84
106
|
if default_chain_llm is None:
|
|
85
|
-
|
|
107
|
+
msg = (
|
|
86
108
|
"conversation_llm must be provided if default_chain is not "
|
|
87
109
|
"specified. This API has been changed to avoid instantiating "
|
|
88
110
|
"default LLMs on behalf of users."
|
|
@@ -90,6 +112,7 @@ class MultiRetrievalQAChain(MultiRouteChain):
|
|
|
90
112
|
"from langchain_openai import ChatOpenAI\n"
|
|
91
113
|
"llm = ChatOpenAI()"
|
|
92
114
|
)
|
|
115
|
+
raise NotImplementedError(msg)
|
|
93
116
|
_default_chain = ConversationChain(
|
|
94
117
|
llm=default_chain_llm,
|
|
95
118
|
prompt=prompt,
|