langchain 1.0.2__tar.gz → 1.1.0__tar.gz
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-1.0.2 → langchain-1.1.0}/.gitignore +5 -0
- {langchain-1.0.2 → langchain-1.1.0}/Makefile +12 -2
- {langchain-1.0.2 → langchain-1.1.0}/PKG-INFO +6 -4
- {langchain-1.0.2 → langchain-1.1.0}/README.md +1 -1
- {langchain-1.0.2 → langchain-1.1.0}/langchain/__init__.py +1 -1
- langchain-1.1.0/langchain/agents/__init__.py +9 -0
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/factory.py +171 -67
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/__init__.py +5 -7
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/_execution.py +21 -20
- langchain-1.1.0/langchain/agents/middleware/_retry.py +123 -0
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/context_editing.py +24 -22
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/file_search.py +18 -13
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/human_in_the_loop.py +52 -48
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/model_call_limit.py +58 -14
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/model_fallback.py +5 -7
- langchain-1.1.0/langchain/agents/middleware/model_retry.py +300 -0
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/pii.py +72 -25
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/shell_tool.py +96 -91
- langchain-1.1.0/langchain/agents/middleware/summarization.py +478 -0
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/todo.py +30 -24
- langchain-1.1.0/langchain/agents/middleware/tool_call_limit.py +487 -0
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/tool_emulator.py +45 -36
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/tool_retry.py +170 -158
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/tool_selection.py +34 -24
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/types.py +651 -375
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/structured_output.py +8 -2
- langchain-1.1.0/langchain/chat_models/__init__.py +7 -0
- {langchain-1.0.2 → langchain-1.1.0}/langchain/chat_models/base.py +83 -53
- {langchain-1.0.2 → langchain-1.1.0}/langchain/embeddings/__init__.py +1 -6
- {langchain-1.0.2 → langchain-1.1.0}/langchain/embeddings/base.py +22 -16
- {langchain-1.0.2 → langchain-1.1.0}/langchain/messages/__init__.py +7 -6
- {langchain-1.0.2 → langchain-1.1.0}/langchain/tools/__init__.py +1 -7
- langchain-1.1.0/langchain/tools/tool_node.py +20 -0
- {langchain-1.0.2 → langchain-1.1.0}/pyproject.toml +10 -9
- langchain-1.1.0/tests/cassettes/test_inference_to_native_output[False].yaml.gz +0 -0
- langchain-1.1.0/tests/cassettes/test_inference_to_native_output[True].yaml.gz +0 -0
- langchain-1.1.0/tests/cassettes/test_inference_to_tool_output[False].yaml.gz +0 -0
- langchain-1.1.0/tests/cassettes/test_inference_to_tool_output[True].yaml.gz +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/integration_tests/agents/middleware/test_shell_tool_integration.py +1 -1
- {langchain-1.0.2 → langchain-1.1.0}/tests/integration_tests/chat_models/test_base.py +1 -1
- langchain-1.1.0/tests/unit_tests/agents/__snapshots__/test_middleware_framework.ambr +212 -0
- langchain-1.1.0/tests/unit_tests/agents/middleware/__snapshots__/test_middleware_decorators.ambr +95 -0
- langchain-1.1.0/tests/unit_tests/agents/middleware/__snapshots__/test_middleware_diagram.ambr +289 -0
- langchain-1.1.0/tests/unit_tests/agents/middleware/__snapshots__/test_middleware_framework.ambr +212 -0
- langchain-1.1.0/tests/unit_tests/agents/middleware/core/__snapshots__/test_decorators.ambr +95 -0
- langchain-1.1.0/tests/unit_tests/agents/middleware/core/__snapshots__/test_diagram.ambr +289 -0
- langchain-1.1.0/tests/unit_tests/agents/middleware/core/__snapshots__/test_framework.ambr +212 -0
- langchain-1.0.2/tests/unit_tests/agents/test_handler_composition.py → langchain-1.1.0/tests/unit_tests/agents/middleware/core/test_composition.py +1 -3
- langchain-1.0.2/tests/unit_tests/agents/test_middleware_decorators.py → langchain-1.1.0/tests/unit_tests/agents/middleware/core/test_decorators.py +3 -5
- langchain-1.1.0/tests/unit_tests/agents/middleware/core/test_diagram.py +193 -0
- langchain-1.1.0/tests/unit_tests/agents/middleware/core/test_framework.py +1051 -0
- langchain-1.0.2/tests/unit_tests/agents/middleware/test_override_methods.py → langchain-1.1.0/tests/unit_tests/agents/middleware/core/test_overrides.py +1 -1
- langchain-1.0.2/tests/unit_tests/agents/test_sync_async_tool_wrapper_composition.py → langchain-1.1.0/tests/unit_tests/agents/middleware/core/test_sync_async_wrappers.py +2 -2
- langchain-1.0.2/tests/unit_tests/agents/test_middleware_tools.py → langchain-1.1.0/tests/unit_tests/agents/middleware/core/test_tools.py +14 -12
- langchain-1.0.2/tests/unit_tests/agents/middleware/test_wrap_model_call_middleware.py → langchain-1.1.0/tests/unit_tests/agents/middleware/core/test_wrap_model_call.py +550 -74
- langchain-1.0.2/tests/unit_tests/agents/middleware/test_wrap_tool_call_decorator.py → langchain-1.1.0/tests/unit_tests/agents/middleware/core/test_wrap_tool_call.py +2 -2
- langchain-1.0.2/tests/unit_tests/agents/test_context_editing_middleware.py → langchain-1.1.0/tests/unit_tests/agents/middleware/implementations/test_context_editing.py +76 -28
- {langchain-1.0.2/tests/unit_tests/agents/middleware → langchain-1.1.0/tests/unit_tests/agents/middleware/implementations}/test_file_search.py +105 -0
- langchain-1.1.0/tests/unit_tests/agents/middleware/implementations/test_human_in_the_loop.py +737 -0
- langchain-1.1.0/tests/unit_tests/agents/middleware/implementations/test_model_call_limit.py +224 -0
- langchain-1.0.2/tests/unit_tests/agents/test_model_fallback_middleware.py → langchain-1.1.0/tests/unit_tests/agents/middleware/implementations/test_model_fallback.py +145 -9
- langchain-1.1.0/tests/unit_tests/agents/middleware/implementations/test_model_retry.py +689 -0
- langchain-1.0.2/tests/unit_tests/agents/test_pii_middleware.py → langchain-1.1.0/tests/unit_tests/agents/middleware/implementations/test_pii.py +1 -1
- langchain-1.1.0/tests/unit_tests/agents/middleware/implementations/test_shell_tool.py +556 -0
- langchain-1.1.0/tests/unit_tests/agents/middleware/implementations/test_structured_output_retry.py +369 -0
- langchain-1.1.0/tests/unit_tests/agents/middleware/implementations/test_summarization.py +894 -0
- langchain-1.1.0/tests/unit_tests/agents/middleware/implementations/test_todo.py +516 -0
- langchain-1.1.0/tests/unit_tests/agents/middleware/implementations/test_tool_call_limit.py +789 -0
- {langchain-1.0.2/tests/unit_tests/agents/middleware → langchain-1.1.0/tests/unit_tests/agents/middleware/implementations}/test_tool_emulator.py +1 -1
- {langchain-1.0.2/tests/unit_tests/agents/middleware → langchain-1.1.0/tests/unit_tests/agents/middleware/implementations}/test_tool_retry.py +143 -32
- langchain-1.0.2/tests/unit_tests/agents/middleware/test_llm_tool_selection.py → langchain-1.1.0/tests/unit_tests/agents/middleware/implementations/test_tool_selection.py +17 -8
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/model.py +2 -3
- langchain-1.1.0/tests/unit_tests/agents/test_create_agent_tool_validation.py +370 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/test_injected_runtime_create_agent.py +244 -1
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/test_response_format.py +53 -3
- langchain-1.1.0/tests/unit_tests/agents/test_response_format_integration.py +142 -0
- langchain-1.1.0/tests/unit_tests/agents/test_system_message.py +1013 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/chat_models/test_chat_models.py +4 -4
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/conftest.py +44 -0
- langchain-1.1.0/tests/unit_tests/embeddings/__init__.py +0 -0
- langchain-1.1.0/tests/unit_tests/tools/__init__.py +0 -0
- langchain-1.1.0/uv.lock +5408 -0
- langchain-1.0.2/langchain/agents/__init__.py +0 -15
- langchain-1.0.2/langchain/agents/middleware/summarization.py +0 -249
- langchain-1.0.2/langchain/agents/middleware/tool_call_limit.py +0 -333
- langchain-1.0.2/langchain/chat_models/__init__.py +0 -13
- langchain-1.0.2/langchain/tools/tool_node.py +0 -1786
- langchain-1.0.2/tests/integration_tests/agents/test_response_format.py +0 -79
- langchain-1.0.2/tests/unit_tests/agents/middleware/test_before_after_agent.py +0 -286
- langchain-1.0.2/tests/unit_tests/agents/middleware/test_shell_tool.py +0 -175
- langchain-1.0.2/tests/unit_tests/agents/middleware/test_wrap_model_call_decorator.py +0 -355
- langchain-1.0.2/tests/unit_tests/agents/test_middleware_agent.py +0 -2600
- langchain-1.0.2/tests/unit_tests/agents/test_on_tool_call_middleware.py +0 -828
- langchain-1.0.2/tests/unit_tests/agents/test_todo_middleware.py +0 -172
- langchain-1.0.2/tests/unit_tests/agents/test_tool_call_limit.py +0 -454
- langchain-1.0.2/tests/unit_tests/agents/test_tool_node.py +0 -1716
- langchain-1.0.2/tests/unit_tests/agents/test_tool_node_interceptor_unregistered.py +0 -571
- langchain-1.0.2/tests/unit_tests/agents/test_tool_node_validation_error_filtering.py +0 -678
- langchain-1.0.2/tests/unit_tests/tools/test_on_tool_call.py +0 -1287
- langchain-1.0.2/uv.lock +0 -4781
- {langchain-1.0.2 → langchain-1.1.0}/LICENSE +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/extended_testing_deps.txt +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/langchain/agents/middleware/_redaction.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/langchain/py.typed +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/langchain/rate_limiters/__init__.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/scripts/check_imports.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/__init__.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/integration_tests/__init__.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/integration_tests/agents/__init__.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/integration_tests/agents/middleware/__init__.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/integration_tests/cache/__init__.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/integration_tests/cache/fake_embeddings.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/integration_tests/chat_models/__init__.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/integration_tests/conftest.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/integration_tests/embeddings/__init__.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/integration_tests/embeddings/test_base.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/integration_tests/test_compile.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/__init__.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/__init__.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/__snapshots__/test_middleware_agent.ambr +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/__snapshots__/test_middleware_decorators.ambr +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/__snapshots__/test_return_direct_graph.ambr +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/any_str.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/compose-postgres.yml +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/compose-redis.yml +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/conftest.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/conftest_checkpointer.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/conftest_store.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/memory_assert.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/messages.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/middleware/__init__.py +0 -0
- {langchain-1.0.2/tests/unit_tests/chat_models → langchain-1.1.0/tests/unit_tests/agents/middleware/core}/__init__.py +0 -0
- {langchain-1.0.2/tests/unit_tests/embeddings → langchain-1.1.0/tests/unit_tests/agents/middleware/implementations}/__init__.py +0 -0
- {langchain-1.0.2/tests/unit_tests/agents/middleware → langchain-1.1.0/tests/unit_tests/agents/middleware/implementations}/test_shell_execution_policies.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/specifications/responses.json +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/specifications/return_direct.json +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/test_react_agent.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/test_responses.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/test_responses_spec.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/test_return_direct_graph.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/test_return_direct_spec.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/test_state_schema.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/agents/utils.py +0 -0
- {langchain-1.0.2/tests/unit_tests/tools → langchain-1.1.0/tests/unit_tests/chat_models}/__init__.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/embeddings/test_base.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/embeddings/test_imports.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/stubs.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/test_dependencies.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/test_imports.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/test_pytest_config.py +0 -0
- {langchain-1.0.2 → langchain-1.1.0}/tests/unit_tests/tools/test_imports.py +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.PHONY: all start_services stop_services coverage test test_fast extended_tests test_watch test_watch_extended integration_tests check_imports lint format lint_diff format_diff lint_package lint_tests help
|
|
1
|
+
.PHONY: all start_services stop_services coverage coverage_agents test test_fast extended_tests test_watch test_watch_extended integration_tests check_imports lint format lint_diff format_diff lint_package lint_tests help
|
|
2
2
|
|
|
3
3
|
# Default target executed when no arguments are given to make.
|
|
4
4
|
all: help
|
|
@@ -27,8 +27,17 @@ coverage:
|
|
|
27
27
|
--cov-report term-missing:skip-covered \
|
|
28
28
|
$(TEST_FILE)
|
|
29
29
|
|
|
30
|
+
# Run middleware and agent tests with coverage report.
|
|
31
|
+
coverage_agents:
|
|
32
|
+
uv run --group test pytest \
|
|
33
|
+
tests/unit_tests/agents/middleware/ \
|
|
34
|
+
tests/unit_tests/agents/test_*.py \
|
|
35
|
+
--cov=langchain.agents \
|
|
36
|
+
--cov-report=term-missing \
|
|
37
|
+
--cov-report=html:htmlcov \
|
|
38
|
+
|
|
30
39
|
test:
|
|
31
|
-
make start_services && LANGGRAPH_TEST_FAST=0 uv run --group test pytest -n auto --disable-socket --allow-unix-socket $(TEST_FILE) --cov-report term-missing:skip-covered; \
|
|
40
|
+
make start_services && LANGGRAPH_TEST_FAST=0 uv run --no-sync --active --group test pytest -n auto --disable-socket --allow-unix-socket $(TEST_FILE) --cov-report term-missing:skip-covered --snapshot-update; \
|
|
32
41
|
EXIT_CODE=$$?; \
|
|
33
42
|
make stop_services; \
|
|
34
43
|
exit $$EXIT_CODE
|
|
@@ -93,6 +102,7 @@ help:
|
|
|
93
102
|
@echo 'lint - run linters'
|
|
94
103
|
@echo '-- TESTS --'
|
|
95
104
|
@echo 'coverage - run unit tests and generate coverage report'
|
|
105
|
+
@echo 'coverage_agents - run middleware and agent tests with coverage report'
|
|
96
106
|
@echo 'test - run unit tests with all services'
|
|
97
107
|
@echo 'test_fast - run unit tests with in-memory services only'
|
|
98
108
|
@echo 'tests - run unit tests (alias for "make test")'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langchain
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: Building applications with LLMs through composability
|
|
5
5
|
Project-URL: Homepage, https://docs.langchain.com/
|
|
6
6
|
Project-URL: Documentation, https://reference.langchain.com/python/langchain/langchain/
|
|
@@ -12,13 +12,15 @@ Project-URL: Reddit, https://www.reddit.com/r/LangChain/
|
|
|
12
12
|
License: MIT
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Requires-Python: <4.0.0,>=3.10.0
|
|
15
|
-
Requires-Dist: langchain-core<2.0.0,>=1.
|
|
16
|
-
Requires-Dist: langgraph<1.1.0,>=1.0.
|
|
15
|
+
Requires-Dist: langchain-core<2.0.0,>=1.1.0
|
|
16
|
+
Requires-Dist: langgraph<1.1.0,>=1.0.2
|
|
17
17
|
Requires-Dist: pydantic<3.0.0,>=2.7.4
|
|
18
18
|
Provides-Extra: anthropic
|
|
19
19
|
Requires-Dist: langchain-anthropic; extra == 'anthropic'
|
|
20
20
|
Provides-Extra: aws
|
|
21
21
|
Requires-Dist: langchain-aws; extra == 'aws'
|
|
22
|
+
Provides-Extra: azure-ai
|
|
23
|
+
Requires-Dist: langchain-azure-ai; extra == 'azure-ai'
|
|
22
24
|
Provides-Extra: community
|
|
23
25
|
Requires-Dist: langchain-community; extra == 'community'
|
|
24
26
|
Provides-Extra: deepseek
|
|
@@ -75,7 +77,7 @@ LangChain [agents](https://docs.langchain.com/oss/python/langchain/agents) are b
|
|
|
75
77
|
|
|
76
78
|
## 📖 Documentation
|
|
77
79
|
|
|
78
|
-
For full documentation, see the [API reference](https://reference.langchain.com/python/
|
|
80
|
+
For full documentation, see the [API reference](https://reference.langchain.com/python/langchain/langchain/). For conceptual guides, tutorials, and examples on using LangChain, see the [LangChain Docs](https://docs.langchain.com/oss/python/langchain/overview).
|
|
79
81
|
|
|
80
82
|
## 📕 Releases & Versioning
|
|
81
83
|
|
|
@@ -26,7 +26,7 @@ LangChain [agents](https://docs.langchain.com/oss/python/langchain/agents) are b
|
|
|
26
26
|
|
|
27
27
|
## 📖 Documentation
|
|
28
28
|
|
|
29
|
-
For full documentation, see the [API reference](https://reference.langchain.com/python/
|
|
29
|
+
For full documentation, see the [API reference](https://reference.langchain.com/python/langchain/langchain/). For conceptual guides, tutorials, and examples on using LangChain, see the [LangChain Docs](https://docs.langchain.com/oss/python/langchain/overview).
|
|
30
30
|
|
|
31
31
|
## 📕 Releases & Versioning
|
|
32
32
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""Entrypoint to building [Agents](https://docs.langchain.com/oss/python/langchain/agents) with LangChain.""" # noqa: E501
|
|
2
|
+
|
|
3
|
+
from langchain.agents.factory import create_agent
|
|
4
|
+
from langchain.agents.middleware.types import AgentState
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"AgentState",
|
|
8
|
+
"create_agent",
|
|
9
|
+
]
|
|
@@ -3,7 +3,15 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import itertools
|
|
6
|
-
from typing import
|
|
6
|
+
from typing import (
|
|
7
|
+
TYPE_CHECKING,
|
|
8
|
+
Annotated,
|
|
9
|
+
Any,
|
|
10
|
+
cast,
|
|
11
|
+
get_args,
|
|
12
|
+
get_origin,
|
|
13
|
+
get_type_hints,
|
|
14
|
+
)
|
|
7
15
|
|
|
8
16
|
from langchain_core.language_models.chat_models import BaseChatModel
|
|
9
17
|
from langchain_core.messages import AIMessage, AnyMessage, SystemMessage, ToolMessage
|
|
@@ -11,10 +19,11 @@ from langchain_core.tools import BaseTool
|
|
|
11
19
|
from langgraph._internal._runnable import RunnableCallable
|
|
12
20
|
from langgraph.constants import END, START
|
|
13
21
|
from langgraph.graph.state import StateGraph
|
|
22
|
+
from langgraph.prebuilt.tool_node import ToolCallWithContext, ToolNode
|
|
14
23
|
from langgraph.runtime import Runtime # noqa: TC002
|
|
15
24
|
from langgraph.types import Command, Send
|
|
16
25
|
from langgraph.typing import ContextT # noqa: TC002
|
|
17
|
-
from typing_extensions import NotRequired, Required, TypedDict
|
|
26
|
+
from typing_extensions import NotRequired, Required, TypedDict
|
|
18
27
|
|
|
19
28
|
from langchain.agents.middleware.types import (
|
|
20
29
|
AgentMiddleware,
|
|
@@ -23,6 +32,8 @@ from langchain.agents.middleware.types import (
|
|
|
23
32
|
ModelRequest,
|
|
24
33
|
ModelResponse,
|
|
25
34
|
OmitFromSchema,
|
|
35
|
+
ResponseT,
|
|
36
|
+
StateT_co,
|
|
26
37
|
_InputAgentState,
|
|
27
38
|
_OutputAgentState,
|
|
28
39
|
)
|
|
@@ -33,11 +44,11 @@ from langchain.agents.structured_output import (
|
|
|
33
44
|
ProviderStrategy,
|
|
34
45
|
ProviderStrategyBinding,
|
|
35
46
|
ResponseFormat,
|
|
47
|
+
StructuredOutputError,
|
|
36
48
|
StructuredOutputValidationError,
|
|
37
49
|
ToolStrategy,
|
|
38
50
|
)
|
|
39
51
|
from langchain.chat_models import init_chat_model
|
|
40
|
-
from langchain.tools.tool_node import ToolCallWithContext, _ToolNode
|
|
41
52
|
|
|
42
53
|
if TYPE_CHECKING:
|
|
43
54
|
from collections.abc import Awaitable, Callable, Sequence
|
|
@@ -48,11 +59,21 @@ if TYPE_CHECKING:
|
|
|
48
59
|
from langgraph.store.base import BaseStore
|
|
49
60
|
from langgraph.types import Checkpointer
|
|
50
61
|
|
|
51
|
-
from langchain.
|
|
62
|
+
from langchain.agents.middleware.types import ToolCallRequest, ToolCallWrapper
|
|
52
63
|
|
|
53
64
|
STRUCTURED_OUTPUT_ERROR_TEMPLATE = "Error: {error}\n Please fix your mistakes."
|
|
54
65
|
|
|
55
|
-
|
|
66
|
+
FALLBACK_MODELS_WITH_STRUCTURED_OUTPUT = [
|
|
67
|
+
# if model profile data are not available, these models are assumed to support
|
|
68
|
+
# structured output
|
|
69
|
+
"grok",
|
|
70
|
+
"gpt-5",
|
|
71
|
+
"gpt-4.1",
|
|
72
|
+
"gpt-4o",
|
|
73
|
+
"gpt-oss",
|
|
74
|
+
"o3-pro",
|
|
75
|
+
"o3-mini",
|
|
76
|
+
]
|
|
56
77
|
|
|
57
78
|
|
|
58
79
|
def _normalize_to_model_response(result: ModelResponse | AIMessage) -> ModelResponse:
|
|
@@ -340,11 +361,13 @@ def _get_can_jump_to(middleware: AgentMiddleware[Any, Any], hook_name: str) -> l
|
|
|
340
361
|
return []
|
|
341
362
|
|
|
342
363
|
|
|
343
|
-
def _supports_provider_strategy(model: str | BaseChatModel) -> bool:
|
|
364
|
+
def _supports_provider_strategy(model: str | BaseChatModel, tools: list | None = None) -> bool:
|
|
344
365
|
"""Check if a model supports provider-specific structured output.
|
|
345
366
|
|
|
346
367
|
Args:
|
|
347
368
|
model: Model name string or `BaseChatModel` instance.
|
|
369
|
+
tools: Optional list of tools provided to the agent. Needed because some models
|
|
370
|
+
don't support structured output together with tool calling.
|
|
348
371
|
|
|
349
372
|
Returns:
|
|
350
373
|
`True` if the model supports provider-specific structured output, `False` otherwise.
|
|
@@ -353,11 +376,23 @@ def _supports_provider_strategy(model: str | BaseChatModel) -> bool:
|
|
|
353
376
|
if isinstance(model, str):
|
|
354
377
|
model_name = model
|
|
355
378
|
elif isinstance(model, BaseChatModel):
|
|
356
|
-
model_name =
|
|
379
|
+
model_name = (
|
|
380
|
+
getattr(model, "model_name", None)
|
|
381
|
+
or getattr(model, "model", None)
|
|
382
|
+
or getattr(model, "model_id", "")
|
|
383
|
+
)
|
|
384
|
+
model_profile = model.profile
|
|
385
|
+
if (
|
|
386
|
+
model_profile is not None
|
|
387
|
+
and model_profile.get("structured_output")
|
|
388
|
+
# We make an exception for Gemini models, which currently do not support
|
|
389
|
+
# simultaneous tool use with structured output
|
|
390
|
+
and not (tools and isinstance(model_name, str) and "gemini" in model_name.lower())
|
|
391
|
+
):
|
|
392
|
+
return True
|
|
357
393
|
|
|
358
394
|
return (
|
|
359
|
-
|
|
360
|
-
or any(part in model_name for part in ["gpt-5", "gpt-4.1", "gpt-oss", "o3-pro", "o3-mini"])
|
|
395
|
+
any(part in model_name.lower() for part in FALLBACK_MODELS_WITH_STRUCTURED_OUTPUT)
|
|
361
396
|
if model_name
|
|
362
397
|
else False
|
|
363
398
|
)
|
|
@@ -507,8 +542,8 @@ def create_agent( # noqa: PLR0915
|
|
|
507
542
|
model: str | BaseChatModel,
|
|
508
543
|
tools: Sequence[BaseTool | Callable | dict[str, Any]] | None = None,
|
|
509
544
|
*,
|
|
510
|
-
system_prompt: str | None = None,
|
|
511
|
-
middleware: Sequence[AgentMiddleware[
|
|
545
|
+
system_prompt: str | SystemMessage | None = None,
|
|
546
|
+
middleware: Sequence[AgentMiddleware[StateT_co, ContextT]] = (),
|
|
512
547
|
response_format: ResponseFormat[ResponseT] | type[ResponseT] | None = None,
|
|
513
548
|
state_schema: type[AgentState[ResponseT]] | None = None,
|
|
514
549
|
context_schema: type[ContextT] | None = None,
|
|
@@ -528,45 +563,88 @@ def create_agent( # noqa: PLR0915
|
|
|
528
563
|
visit the [Agents](https://docs.langchain.com/oss/python/langchain/agents) docs.
|
|
529
564
|
|
|
530
565
|
Args:
|
|
531
|
-
model: The language model for the agent.
|
|
532
|
-
|
|
566
|
+
model: The language model for the agent.
|
|
567
|
+
|
|
568
|
+
Can be a string identifier (e.g., `"openai:gpt-4"`) or a direct chat model
|
|
569
|
+
instance (e.g., [`ChatOpenAI`][langchain_openai.ChatOpenAI] or other another
|
|
570
|
+
[LangChain chat model](https://docs.langchain.com/oss/python/integrations/chat)).
|
|
571
|
+
|
|
533
572
|
For a full list of supported model strings, see
|
|
534
573
|
[`init_chat_model`][langchain.chat_models.init_chat_model(model_provider)].
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
574
|
+
|
|
575
|
+
!!! tip ""
|
|
576
|
+
|
|
577
|
+
See the [Models](https://docs.langchain.com/oss/python/langchain/models)
|
|
578
|
+
docs for more information.
|
|
579
|
+
tools: A list of tools, `dict`, or `Callable`.
|
|
580
|
+
|
|
581
|
+
If `None` or an empty list, the agent will consist of a model node without a
|
|
582
|
+
tool calling loop.
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
!!! tip ""
|
|
586
|
+
|
|
587
|
+
See the [Tools](https://docs.langchain.com/oss/python/langchain/tools)
|
|
588
|
+
docs for more information.
|
|
589
|
+
system_prompt: An optional system prompt for the LLM.
|
|
590
|
+
|
|
591
|
+
Can be a `str` (which will be converted to a `SystemMessage`) or a
|
|
592
|
+
`SystemMessage` instance directly. The system message is added to the
|
|
593
|
+
beginning of the message list when calling the model.
|
|
539
594
|
middleware: A sequence of middleware instances to apply to the agent.
|
|
595
|
+
|
|
540
596
|
Middleware can intercept and modify agent behavior at various stages.
|
|
597
|
+
|
|
598
|
+
!!! tip ""
|
|
599
|
+
|
|
600
|
+
See the [Middleware](https://docs.langchain.com/oss/python/langchain/middleware)
|
|
601
|
+
docs for more information.
|
|
541
602
|
response_format: An optional configuration for structured responses.
|
|
603
|
+
|
|
542
604
|
Can be a `ToolStrategy`, `ProviderStrategy`, or a Pydantic model class.
|
|
605
|
+
|
|
543
606
|
If provided, the agent will handle structured output during the
|
|
544
|
-
conversation flow.
|
|
545
|
-
|
|
607
|
+
conversation flow.
|
|
608
|
+
|
|
609
|
+
Raw schemas will be wrapped in an appropriate strategy based on model
|
|
610
|
+
capabilities.
|
|
611
|
+
|
|
612
|
+
!!! tip ""
|
|
613
|
+
|
|
614
|
+
See the [Structured output](https://docs.langchain.com/oss/python/langchain/structured-output)
|
|
615
|
+
docs for more information.
|
|
546
616
|
state_schema: An optional `TypedDict` schema that extends `AgentState`.
|
|
617
|
+
|
|
547
618
|
When provided, this schema is used instead of `AgentState` as the base
|
|
548
619
|
schema for merging with middleware state schemas. This allows users to
|
|
549
620
|
add custom state fields without needing to create custom middleware.
|
|
550
|
-
|
|
621
|
+
|
|
622
|
+
Generally, it's recommended to use `state_schema` extensions via middleware
|
|
551
623
|
to keep relevant extensions scoped to corresponding hooks / tools.
|
|
552
|
-
The schema must be a subclass of `AgentState[ResponseT]`.
|
|
553
624
|
context_schema: An optional schema for runtime context.
|
|
554
|
-
checkpointer: An optional checkpoint saver object.
|
|
555
|
-
|
|
556
|
-
(e.g.,
|
|
557
|
-
|
|
558
|
-
|
|
625
|
+
checkpointer: An optional checkpoint saver object.
|
|
626
|
+
|
|
627
|
+
Used for persisting the state of the graph (e.g., as chat memory) for a
|
|
628
|
+
single thread (e.g., a single conversation).
|
|
629
|
+
store: An optional store object.
|
|
630
|
+
|
|
631
|
+
Used for persisting data across multiple threads (e.g., multiple
|
|
632
|
+
conversations / users).
|
|
559
633
|
interrupt_before: An optional list of node names to interrupt before.
|
|
634
|
+
|
|
560
635
|
Useful if you want to add a user confirmation or other interrupt
|
|
561
636
|
before taking an action.
|
|
562
637
|
interrupt_after: An optional list of node names to interrupt after.
|
|
638
|
+
|
|
563
639
|
Useful if you want to return directly or run additional processing
|
|
564
640
|
on an output.
|
|
565
|
-
debug: Whether to enable verbose logging for graph execution.
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
641
|
+
debug: Whether to enable verbose logging for graph execution.
|
|
642
|
+
|
|
643
|
+
When enabled, prints detailed information about each node execution, state
|
|
644
|
+
updates, and transitions during agent runtime. Useful for debugging
|
|
645
|
+
middleware behavior and understanding agent execution flow.
|
|
569
646
|
name: An optional name for the `CompiledStateGraph`.
|
|
647
|
+
|
|
570
648
|
This name will be automatically used when adding the agent graph to
|
|
571
649
|
another graph as a subgraph node - particularly useful for building
|
|
572
650
|
multi-agent systems.
|
|
@@ -576,11 +654,12 @@ def create_agent( # noqa: PLR0915
|
|
|
576
654
|
A compiled `StateGraph` that can be used for chat interactions.
|
|
577
655
|
|
|
578
656
|
The agent node calls the language model with the messages list (after applying
|
|
579
|
-
the system prompt). If the resulting `AIMessage`
|
|
580
|
-
will then call the tools. The tools node executes
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
657
|
+
the system prompt). If the resulting [`AIMessage`][langchain.messages.AIMessage]
|
|
658
|
+
contains `tool_calls`, the graph will then call the tools. The tools node executes
|
|
659
|
+
the tools and adds the responses to the messages list as
|
|
660
|
+
[`ToolMessage`][langchain.messages.ToolMessage] objects. The agent node then calls
|
|
661
|
+
the language model again. The process repeats until no more `tool_calls` are present
|
|
662
|
+
in the response. The agent then returns the full list of messages.
|
|
584
663
|
|
|
585
664
|
Example:
|
|
586
665
|
```python
|
|
@@ -593,7 +672,7 @@ def create_agent( # noqa: PLR0915
|
|
|
593
672
|
|
|
594
673
|
|
|
595
674
|
graph = create_agent(
|
|
596
|
-
model="anthropic:claude-sonnet-4-5",
|
|
675
|
+
model="anthropic:claude-sonnet-4-5-20250929",
|
|
597
676
|
tools=[check_weather],
|
|
598
677
|
system_prompt="You are a helpful assistant",
|
|
599
678
|
)
|
|
@@ -606,6 +685,14 @@ def create_agent( # noqa: PLR0915
|
|
|
606
685
|
if isinstance(model, str):
|
|
607
686
|
model = init_chat_model(model)
|
|
608
687
|
|
|
688
|
+
# Convert system_prompt to SystemMessage if needed
|
|
689
|
+
system_message: SystemMessage | None = None
|
|
690
|
+
if system_prompt is not None:
|
|
691
|
+
if isinstance(system_prompt, SystemMessage):
|
|
692
|
+
system_message = system_prompt
|
|
693
|
+
else:
|
|
694
|
+
system_message = SystemMessage(content=system_prompt)
|
|
695
|
+
|
|
609
696
|
# Handle tools being None or empty
|
|
610
697
|
if tools is None:
|
|
611
698
|
tools = []
|
|
@@ -675,7 +762,7 @@ def create_agent( # noqa: PLR0915
|
|
|
675
762
|
awrap_tool_call_wrapper = _chain_async_tool_call_wrappers(async_wrappers)
|
|
676
763
|
|
|
677
764
|
# Setup tools
|
|
678
|
-
tool_node:
|
|
765
|
+
tool_node: ToolNode | None = None
|
|
679
766
|
# Extract built-in provider tools (dict format) and regular tools (BaseTool/callables)
|
|
680
767
|
built_in_tools = [t for t in tools if isinstance(t, dict)]
|
|
681
768
|
regular_tools = [t for t in tools if not isinstance(t, dict)]
|
|
@@ -685,7 +772,7 @@ def create_agent( # noqa: PLR0915
|
|
|
685
772
|
|
|
686
773
|
# Only create ToolNode if we have client-side tools
|
|
687
774
|
tool_node = (
|
|
688
|
-
|
|
775
|
+
ToolNode(
|
|
689
776
|
tools=available_tools,
|
|
690
777
|
wrap_tool_call=wrap_tool_call_wrapper,
|
|
691
778
|
awrap_tool_call=awrap_tool_call_wrapper,
|
|
@@ -762,7 +849,7 @@ def create_agent( # noqa: PLR0915
|
|
|
762
849
|
async_handlers = [m.awrap_model_call for m in middleware_w_awrap_model_call]
|
|
763
850
|
awrap_model_call_handler = _chain_async_model_call_handlers(async_handlers)
|
|
764
851
|
|
|
765
|
-
state_schemas = {m.state_schema for m in middleware}
|
|
852
|
+
state_schemas: set[type] = {m.state_schema for m in middleware}
|
|
766
853
|
# Use provided state_schema if available, otherwise use base AgentState
|
|
767
854
|
base_state = state_schema if state_schema is not None else AgentState
|
|
768
855
|
state_schemas.add(base_state)
|
|
@@ -797,8 +884,16 @@ def create_agent( # noqa: PLR0915
|
|
|
797
884
|
provider_strategy_binding = ProviderStrategyBinding.from_schema_spec(
|
|
798
885
|
effective_response_format.schema_spec
|
|
799
886
|
)
|
|
800
|
-
|
|
801
|
-
|
|
887
|
+
try:
|
|
888
|
+
structured_response = provider_strategy_binding.parse(output)
|
|
889
|
+
except Exception as exc: # noqa: BLE001
|
|
890
|
+
schema_name = getattr(
|
|
891
|
+
effective_response_format.schema_spec.schema, "__name__", "response_format"
|
|
892
|
+
)
|
|
893
|
+
validation_error = StructuredOutputValidationError(schema_name, exc, output)
|
|
894
|
+
raise validation_error
|
|
895
|
+
else:
|
|
896
|
+
return {"messages": [output], "structured_response": structured_response}
|
|
802
897
|
return {"messages": [output]}
|
|
803
898
|
|
|
804
899
|
# Handle structured output with tool strategy
|
|
@@ -812,11 +907,11 @@ def create_agent( # noqa: PLR0915
|
|
|
812
907
|
]
|
|
813
908
|
|
|
814
909
|
if structured_tool_calls:
|
|
815
|
-
exception:
|
|
910
|
+
exception: StructuredOutputError | None = None
|
|
816
911
|
if len(structured_tool_calls) > 1:
|
|
817
912
|
# Handle multiple structured outputs error
|
|
818
913
|
tool_names = [tc["name"] for tc in structured_tool_calls]
|
|
819
|
-
exception = MultipleStructuredOutputsError(tool_names)
|
|
914
|
+
exception = MultipleStructuredOutputsError(tool_names, output)
|
|
820
915
|
should_retry, error_message = _handle_structured_output_error(
|
|
821
916
|
exception, effective_response_format
|
|
822
917
|
)
|
|
@@ -858,7 +953,7 @@ def create_agent( # noqa: PLR0915
|
|
|
858
953
|
"structured_response": structured_response,
|
|
859
954
|
}
|
|
860
955
|
except Exception as exc: # noqa: BLE001
|
|
861
|
-
exception = StructuredOutputValidationError(tool_call["name"], exc)
|
|
956
|
+
exception = StructuredOutputValidationError(tool_call["name"], exc, output)
|
|
862
957
|
should_retry, error_message = _handle_structured_output_error(
|
|
863
958
|
exception, effective_response_format
|
|
864
959
|
)
|
|
@@ -927,7 +1022,7 @@ def create_agent( # noqa: PLR0915
|
|
|
927
1022
|
effective_response_format: ResponseFormat | None
|
|
928
1023
|
if isinstance(request.response_format, AutoStrategy):
|
|
929
1024
|
# User provided raw schema via AutoStrategy - auto-detect best strategy based on model
|
|
930
|
-
if _supports_provider_strategy(request.model):
|
|
1025
|
+
if _supports_provider_strategy(request.model, tools=request.tools):
|
|
931
1026
|
# Model supports provider strategy - use it
|
|
932
1027
|
effective_response_format = ProviderStrategy(schema=request.response_format.schema)
|
|
933
1028
|
else:
|
|
@@ -948,7 +1043,7 @@ def create_agent( # noqa: PLR0915
|
|
|
948
1043
|
|
|
949
1044
|
# Bind model based on effective response format
|
|
950
1045
|
if isinstance(effective_response_format, ProviderStrategy):
|
|
951
|
-
# Use
|
|
1046
|
+
# (Backward compatibility) Use OpenAI format structured output
|
|
952
1047
|
kwargs = effective_response_format.to_model_kwargs()
|
|
953
1048
|
return (
|
|
954
1049
|
request.model.bind_tools(
|
|
@@ -1001,8 +1096,8 @@ def create_agent( # noqa: PLR0915
|
|
|
1001
1096
|
# Get the bound model (with auto-detection if needed)
|
|
1002
1097
|
model_, effective_response_format = _get_bound_model(request)
|
|
1003
1098
|
messages = request.messages
|
|
1004
|
-
if request.
|
|
1005
|
-
messages = [
|
|
1099
|
+
if request.system_message:
|
|
1100
|
+
messages = [request.system_message, *messages]
|
|
1006
1101
|
|
|
1007
1102
|
output = model_.invoke(messages)
|
|
1008
1103
|
|
|
@@ -1021,7 +1116,7 @@ def create_agent( # noqa: PLR0915
|
|
|
1021
1116
|
request = ModelRequest(
|
|
1022
1117
|
model=model,
|
|
1023
1118
|
tools=default_tools,
|
|
1024
|
-
|
|
1119
|
+
system_message=system_message,
|
|
1025
1120
|
response_format=initial_response_format,
|
|
1026
1121
|
messages=state["messages"],
|
|
1027
1122
|
tool_choice=None,
|
|
@@ -1054,8 +1149,8 @@ def create_agent( # noqa: PLR0915
|
|
|
1054
1149
|
# Get the bound model (with auto-detection if needed)
|
|
1055
1150
|
model_, effective_response_format = _get_bound_model(request)
|
|
1056
1151
|
messages = request.messages
|
|
1057
|
-
if request.
|
|
1058
|
-
messages = [
|
|
1152
|
+
if request.system_message:
|
|
1153
|
+
messages = [request.system_message, *messages]
|
|
1059
1154
|
|
|
1060
1155
|
output = await model_.ainvoke(messages)
|
|
1061
1156
|
|
|
@@ -1074,7 +1169,7 @@ def create_agent( # noqa: PLR0915
|
|
|
1074
1169
|
request = ModelRequest(
|
|
1075
1170
|
model=model,
|
|
1076
1171
|
tools=default_tools,
|
|
1077
|
-
|
|
1172
|
+
system_message=system_message,
|
|
1078
1173
|
response_format=initial_response_format,
|
|
1079
1174
|
messages=state["messages"],
|
|
1080
1175
|
tool_choice=None,
|
|
@@ -1229,11 +1324,14 @@ def create_agent( # noqa: PLR0915
|
|
|
1229
1324
|
|
|
1230
1325
|
graph.add_conditional_edges(
|
|
1231
1326
|
"tools",
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1327
|
+
RunnableCallable(
|
|
1328
|
+
_make_tools_to_model_edge(
|
|
1329
|
+
tool_node=tool_node,
|
|
1330
|
+
model_destination=loop_entry_node,
|
|
1331
|
+
structured_output_tools=structured_output_tools,
|
|
1332
|
+
end_destination=exit_node,
|
|
1333
|
+
),
|
|
1334
|
+
trace=False,
|
|
1237
1335
|
),
|
|
1238
1336
|
tools_to_model_destinations,
|
|
1239
1337
|
)
|
|
@@ -1250,19 +1348,25 @@ def create_agent( # noqa: PLR0915
|
|
|
1250
1348
|
|
|
1251
1349
|
graph.add_conditional_edges(
|
|
1252
1350
|
loop_exit_node,
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1351
|
+
RunnableCallable(
|
|
1352
|
+
_make_model_to_tools_edge(
|
|
1353
|
+
model_destination=loop_entry_node,
|
|
1354
|
+
structured_output_tools=structured_output_tools,
|
|
1355
|
+
end_destination=exit_node,
|
|
1356
|
+
),
|
|
1357
|
+
trace=False,
|
|
1257
1358
|
),
|
|
1258
1359
|
model_to_tools_destinations,
|
|
1259
1360
|
)
|
|
1260
1361
|
elif len(structured_output_tools) > 0:
|
|
1261
1362
|
graph.add_conditional_edges(
|
|
1262
1363
|
loop_exit_node,
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1364
|
+
RunnableCallable(
|
|
1365
|
+
_make_model_to_model_edge(
|
|
1366
|
+
model_destination=loop_entry_node,
|
|
1367
|
+
end_destination=exit_node,
|
|
1368
|
+
),
|
|
1369
|
+
trace=False,
|
|
1266
1370
|
),
|
|
1267
1371
|
[loop_entry_node, exit_node],
|
|
1268
1372
|
)
|
|
@@ -1372,7 +1476,7 @@ def create_agent( # noqa: PLR0915
|
|
|
1372
1476
|
debug=debug,
|
|
1373
1477
|
name=name,
|
|
1374
1478
|
cache=cache,
|
|
1375
|
-
)
|
|
1479
|
+
).with_config({"recursion_limit": 10_000})
|
|
1376
1480
|
|
|
1377
1481
|
|
|
1378
1482
|
def _resolve_jump(
|
|
@@ -1491,7 +1595,7 @@ def _make_model_to_model_edge(
|
|
|
1491
1595
|
|
|
1492
1596
|
def _make_tools_to_model_edge(
|
|
1493
1597
|
*,
|
|
1494
|
-
tool_node:
|
|
1598
|
+
tool_node: ToolNode,
|
|
1495
1599
|
model_destination: str,
|
|
1496
1600
|
structured_output_tools: dict[str, OutputToolBinding],
|
|
1497
1601
|
end_destination: str,
|
|
@@ -1563,7 +1667,7 @@ def _add_middleware_edge(
|
|
|
1563
1667
|
if "model" in can_jump_to and name != model_destination:
|
|
1564
1668
|
destinations.append(model_destination)
|
|
1565
1669
|
|
|
1566
|
-
graph.add_conditional_edges(name, jump_edge, destinations)
|
|
1670
|
+
graph.add_conditional_edges(name, RunnableCallable(jump_edge, trace=False), destinations)
|
|
1567
1671
|
|
|
1568
1672
|
else:
|
|
1569
1673
|
graph.add_edge(name, default_destination)
|
|
@@ -1,21 +1,17 @@
|
|
|
1
|
-
"""Entrypoint to using [
|
|
2
|
-
|
|
3
|
-
!!! warning "Reference docs"
|
|
4
|
-
This page contains **reference documentation** for Middleware. See
|
|
5
|
-
[the docs](https://docs.langchain.com/oss/python/langchain/middleware) for conceptual
|
|
6
|
-
guides, tutorials, and examples on using Middleware.
|
|
7
|
-
""" # noqa: E501
|
|
1
|
+
"""Entrypoint to using [middleware](https://docs.langchain.com/oss/python/langchain/middleware) plugins with [Agents](https://docs.langchain.com/oss/python/langchain/agents).""" # noqa: E501
|
|
8
2
|
|
|
9
3
|
from .context_editing import (
|
|
10
4
|
ClearToolUsesEdit,
|
|
11
5
|
ContextEditingMiddleware,
|
|
12
6
|
)
|
|
7
|
+
from .file_search import FilesystemFileSearchMiddleware
|
|
13
8
|
from .human_in_the_loop import (
|
|
14
9
|
HumanInTheLoopMiddleware,
|
|
15
10
|
InterruptOnConfig,
|
|
16
11
|
)
|
|
17
12
|
from .model_call_limit import ModelCallLimitMiddleware
|
|
18
13
|
from .model_fallback import ModelFallbackMiddleware
|
|
14
|
+
from .model_retry import ModelRetryMiddleware
|
|
19
15
|
from .pii import PIIDetectionError, PIIMiddleware
|
|
20
16
|
from .shell_tool import (
|
|
21
17
|
CodexSandboxExecutionPolicy,
|
|
@@ -52,6 +48,7 @@ __all__ = [
|
|
|
52
48
|
"CodexSandboxExecutionPolicy",
|
|
53
49
|
"ContextEditingMiddleware",
|
|
54
50
|
"DockerExecutionPolicy",
|
|
51
|
+
"FilesystemFileSearchMiddleware",
|
|
55
52
|
"HostExecutionPolicy",
|
|
56
53
|
"HumanInTheLoopMiddleware",
|
|
57
54
|
"InterruptOnConfig",
|
|
@@ -61,6 +58,7 @@ __all__ = [
|
|
|
61
58
|
"ModelFallbackMiddleware",
|
|
62
59
|
"ModelRequest",
|
|
63
60
|
"ModelResponse",
|
|
61
|
+
"ModelRetryMiddleware",
|
|
64
62
|
"PIIDetectionError",
|
|
65
63
|
"PIIMiddleware",
|
|
66
64
|
"RedactionRule",
|