From f9bae40475cbe54229570018935c2710ecfe1df4 Mon Sep 17 00:00:00 2001 From: ccurme Date: Mon, 29 Sep 2025 15:42:38 -0400 Subject: [PATCH 1/6] feat(anthropic): support memory and context management features (#33146) https://docs.claude.com/en/docs/build-with-claude/context-editing --------- Co-authored-by: Mason Daugherty --- .../langchain_anthropic/chat_models.py | 63 ++++++++++++++---- libs/partners/anthropic/pyproject.toml | 2 +- .../cassettes/test_context_management.yaml.gz | Bin 0 -> 111649 bytes .../integration_tests/test_chat_models.py | 44 ++++++++++++ .../tests/unit_tests/test_chat_models.py | 32 ++++++++- libs/partners/anthropic/uv.lock | 20 ++++-- 6 files changed, 140 insertions(+), 21 deletions(-) create mode 100644 libs/partners/anthropic/tests/cassettes/test_context_management.yaml.gz diff --git a/libs/partners/anthropic/langchain_anthropic/chat_models.py b/libs/partners/anthropic/langchain_anthropic/chat_models.py index 0ef5043406e..704733b8306 100644 --- a/libs/partners/anthropic/langchain_anthropic/chat_models.py +++ b/libs/partners/anthropic/langchain_anthropic/chat_models.py @@ -12,7 +12,7 @@ from operator import itemgetter from typing import Any, Callable, Literal, Optional, Union, cast import anthropic -from langchain_core._api import beta, deprecated +from langchain_core._api import deprecated from langchain_core.callbacks import ( AsyncCallbackManagerForLLMRun, CallbackManagerForLLMRun, @@ -91,6 +91,7 @@ def _is_builtin_tool(tool: Any) -> bool: "web_search_", "web_fetch_", "code_execution_", + "memory_", ] return any(tool_type.startswith(prefix) for prefix in _builtin_tool_prefixes) @@ -1193,6 +1194,25 @@ class ChatAnthropic(BaseChatModel): Total tokens: 408 + Context management: + Anthropic supports a context editing feature that will automatically manage the + model's context window (e.g., by clearing tool results). + + See `Anthropic documentation `__ + for details and configuration options. + + .. code-block:: python + + from langchain_anthropic import ChatAnthropic + + llm = ChatAnthropic( + model="claude-sonnet-4-5-20250929", + betas=["context-management-2025-06-27"], + context_management={"edits": [{"type": "clear_tool_uses_20250919"}]}, + ) + llm_with_tools = llm.bind_tools([{"type": "web_search_20250305", "name": "web_search"}]) + response = llm_with_tools.invoke("Search for recent developments in AI") + Built-in tools: See LangChain `docs `__ for more detail. @@ -1413,6 +1433,11 @@ class ChatAnthropic(BaseChatModel): "name": "example-mcp"}]`` """ + context_management: Optional[dict[str, Any]] = None + """Configuration for + `context management `__. + """ + @property def _llm_type(self) -> str: """Return type of chat model.""" @@ -1565,6 +1590,7 @@ class ChatAnthropic(BaseChatModel): "top_p": self.top_p, "stop_sequences": stop or self.stop_sequences, "betas": self.betas, + "context_management": self.context_management, "mcp_servers": self.mcp_servers, "system": system, **self.model_kwargs, @@ -2219,7 +2245,6 @@ class ChatAnthropic(BaseChatModel): return RunnableMap(raw=llm) | parser_with_fallback return llm | output_parser - @beta() def get_num_tokens_from_messages( self, messages: list[BaseMessage], @@ -2234,8 +2259,8 @@ class ChatAnthropic(BaseChatModel): messages: The message inputs to tokenize. tools: If provided, sequence of dict, BaseModel, function, or BaseTools to be converted to tool schemas. - kwargs: Additional keyword arguments are passed to the - :meth:`~langchain_anthropic.chat_models.ChatAnthropic.bind` method. + kwargs: Additional keyword arguments are passed to the Anthropic + ``messages.count_tokens`` method. Basic usage: @@ -2270,7 +2295,7 @@ class ChatAnthropic(BaseChatModel): def get_weather(location: str) -> str: \"\"\"Get the current weather in a given location - Args: + Args: location: The city and state, e.g. San Francisco, CA \"\"\" return "Sunny" @@ -2288,15 +2313,24 @@ class ChatAnthropic(BaseChatModel): Uses Anthropic's `token counting API `__ to count tokens in messages. - """ # noqa: E501 + """ # noqa: D214,E501 formatted_system, formatted_messages = _format_messages(messages) if isinstance(formatted_system, str): kwargs["system"] = formatted_system if tools: kwargs["tools"] = [convert_to_anthropic_tool(tool) for tool in tools] + if self.context_management is not None: + kwargs["context_management"] = self.context_management - response = self._client.beta.messages.count_tokens( - betas=["token-counting-2024-11-01"], + if self.betas is not None: + beta_response = self._client.beta.messages.count_tokens( + betas=self.betas, + model=self.model, + messages=formatted_messages, # type: ignore[arg-type] + **kwargs, + ) + return beta_response.input_tokens + response = self._client.messages.count_tokens( model=self.model, messages=formatted_messages, # type: ignore[arg-type] **kwargs, @@ -2409,7 +2443,7 @@ def _make_message_chunk_from_anthropic_event( # Capture model name, but don't include usage_metadata yet # as it will be properly reported in message_delta with complete info if hasattr(event.message, "model"): - response_metadata = {"model_name": event.message.model} + response_metadata: dict[str, Any] = {"model_name": event.message.model} else: response_metadata = {} @@ -2510,13 +2544,16 @@ def _make_message_chunk_from_anthropic_event( # Process final usage metadata and completion info elif event.type == "message_delta" and stream_usage: usage_metadata = _create_usage_metadata(event.usage) + response_metadata = { + "stop_reason": event.delta.stop_reason, + "stop_sequence": event.delta.stop_sequence, + } + if context_management := getattr(event, "context_management", None): + response_metadata["context_management"] = context_management.model_dump() message_chunk = AIMessageChunk( content="", usage_metadata=usage_metadata, - response_metadata={ - "stop_reason": event.delta.stop_reason, - "stop_sequence": event.delta.stop_sequence, - }, + response_metadata=response_metadata, ) # Unhandled event types (e.g., `content_block_stop`, `ping` events) # https://docs.anthropic.com/en/docs/build-with-claude/streaming#other-events diff --git a/libs/partners/anthropic/pyproject.toml b/libs/partners/anthropic/pyproject.toml index c2dffd98fe9..50ed966ea2e 100644 --- a/libs/partners/anthropic/pyproject.toml +++ b/libs/partners/anthropic/pyproject.toml @@ -7,7 +7,7 @@ authors = [] license = { text = "MIT" } requires-python = ">=3.9.0,<4.0.0" dependencies = [ - "anthropic>=0.67.0,<1.0.0", + "anthropic>=0.69.0,<1.0.0", "langchain-core>=0.3.76,<2.0.0", "pydantic>=2.7.4,<3.0.0", ] diff --git a/libs/partners/anthropic/tests/cassettes/test_context_management.yaml.gz b/libs/partners/anthropic/tests/cassettes/test_context_management.yaml.gz new file mode 100644 index 0000000000000000000000000000000000000000..096e6a0dd5308b76f3af0c30cc6360397fe2d58d GIT binary patch literal 111649 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

#NuR_Sxs}p!n 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%0AcHoa4a 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 None: assert any("citations" in block for block in result.content) +def test_memory_tool() -> None: + llm = ChatAnthropic( + model="claude-sonnet-4-5-20250929", # type: ignore[call-arg] + betas=["context-management-2025-06-27"], + ) + llm_with_tools = llm.bind_tools([{"type": "memory_20250818", "name": "memory"}]) + response = llm_with_tools.invoke("What are my interests?") + assert isinstance(response, AIMessage) + assert response.tool_calls + assert response.tool_calls[0]["name"] == "memory" + + +@pytest.mark.vcr +def test_context_management() -> None: + # TODO: update example to trigger action + llm = ChatAnthropic( + model="claude-sonnet-4-5-20250929", # type: ignore[call-arg] + betas=["context-management-2025-06-27"], + context_management={ + "edits": [ + { + "type": "clear_tool_uses_20250919", + "trigger": {"type": "input_tokens", "value": 10}, + "clear_at_least": {"type": "input_tokens", "value": 5}, + } + ] + }, + ) + llm_with_tools = llm.bind_tools( + [{"type": "web_search_20250305", "name": "web_search"}] + ) + input_message = {"role": "user", "content": "Search for recent developments in AI"} + response = llm_with_tools.invoke([input_message]) + assert response.response_metadata.get("context_management") + + # Test streaming + full: Optional[BaseMessageChunk] = None + for chunk in llm_with_tools.stream([input_message]): + assert isinstance(chunk, AIMessageChunk) + full = chunk if full is None else full + chunk + assert isinstance(full, AIMessageChunk) + assert full.response_metadata.get("context_management") + + def test_async_shared_client() -> None: llm = ChatAnthropic(model="claude-3-5-haiku-latest") # type: ignore[call-arg] _ = asyncio.run(llm.ainvoke("Hello")) diff --git a/libs/partners/anthropic/tests/unit_tests/test_chat_models.py b/libs/partners/anthropic/tests/unit_tests/test_chat_models.py index b07c158cc1d..90d60482b23 100644 --- a/libs/partners/anthropic/tests/unit_tests/test_chat_models.py +++ b/libs/partners/anthropic/tests/unit_tests/test_chat_models.py @@ -1065,9 +1065,21 @@ def test_get_num_tokens_from_messages_passes_kwargs() -> None: with patch.object(anthropic, "Client") as _client: llm.get_num_tokens_from_messages([HumanMessage("foo")], foo="bar") - assert ( - _client.return_value.beta.messages.count_tokens.call_args.kwargs["foo"] == "bar" + assert _client.return_value.messages.count_tokens.call_args.kwargs["foo"] == "bar" + + llm = ChatAnthropic( + model="claude-sonnet-4-5-20250929", + betas=["context-management-2025-06-27"], + context_management={"edits": [{"type": "clear_tool_uses_20250919"}]}, ) + with patch.object(anthropic, "Client") as _client: + llm.get_num_tokens_from_messages([HumanMessage("foo")]) + + call_args = _client.return_value.beta.messages.count_tokens.call_args.kwargs + assert call_args["betas"] == ["context-management-2025-06-27"] + assert call_args["context_management"] == { + "edits": [{"type": "clear_tool_uses_20250919"}] + } def test_usage_metadata_standardization() -> None: @@ -1217,6 +1229,22 @@ def test_cache_control_kwarg() -> None: ] +def test_context_management_in_payload() -> None: + llm = ChatAnthropic( + model="claude-sonnet-4-5-20250929", # type: ignore[call-arg] + betas=["context-management-2025-06-27"], + context_management={"edits": [{"type": "clear_tool_uses_20250919"}]}, + ) + llm_with_tools = llm.bind_tools( + [{"type": "web_search_20250305", "name": "web_search"}] + ) + input_message = HumanMessage("Search for recent developments in AI") + payload = llm_with_tools._get_request_payload([input_message]) # type: ignore[attr-defined] + assert payload["context_management"] == { + "edits": [{"type": "clear_tool_uses_20250919"}] + } + + def test_anthropic_model_params() -> None: llm = ChatAnthropic(model="claude-3-5-haiku-latest") diff --git a/libs/partners/anthropic/uv.lock b/libs/partners/anthropic/uv.lock index 13e013803b6..12d138b67e3 100644 --- a/libs/partners/anthropic/uv.lock +++ b/libs/partners/anthropic/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 2 requires-python = ">=3.9.0, <4.0.0" resolution-markers = [ "python_full_version >= '3.13' and platform_python_implementation == 'PyPy'", @@ -21,20 +21,21 @@ wheels = [ [[package]] name = "anthropic" -version = "0.67.0" +version = "0.69.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, { name = "distro" }, + { name = "docstring-parser" }, { name = "httpx" }, { name = "jiter" }, { name = "pydantic" }, { name = "sniffio" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/09/08/ee91464cd821e6fca52d9a23be44815c95edd3c1cf1e844b2c5e85f0d57f/anthropic-0.67.0.tar.gz", hash = "sha256:d1531b210ea300c73423141d29bcee20fcd24ef9f426f6437c0a5d93fc98fb8e", size = 441639, upload-time = "2025-09-10T14:47:18.137Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c8/9d/9ad1778b95f15c5b04e7d328c1b5f558f1e893857b7c33cd288c19c0057a/anthropic-0.69.0.tar.gz", hash = "sha256:c604d287f4d73640f40bd2c0f3265a2eb6ce034217ead0608f6b07a8bc5ae5f2", size = 480622, upload-time = "2025-09-29T16:53:45.282Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/9d/9adbda372710918cc8271d089a2ceae4d977a125f90bc3c4b456bca4f281/anthropic-0.67.0-py3-none-any.whl", hash = "sha256:f80a81ec1132c514215f33d25edeeab1c4691ad5361b391ebb70d528b0605b55", size = 317126, upload-time = "2025-09-10T14:47:16.351Z" }, + { url = "https://files.pythonhosted.org/packages/9b/38/75129688de5637eb5b383e5f2b1570a5cc3aecafa4de422da8eea4b90a6c/anthropic-0.69.0-py3-none-any.whl", hash = "sha256:1f73193040f33f11e27c2cd6ec25f24fe7c3f193dc1c5cde6b7a08b18a16bcc5", size = 337265, upload-time = "2025-09-29T16:53:43.686Z" }, ] [[package]] @@ -257,6 +258,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, ] +[[package]] +name = "docstring-parser" +version = "0.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/9d/c3b43da9515bd270df0f80548d9944e389870713cc1fe2b8fb35fe2bcefd/docstring_parser-0.17.0.tar.gz", hash = "sha256:583de4a309722b3315439bb31d64ba3eebada841f2e2cee23b99df001434c912", size = 27442, upload-time = "2025-07-21T07:35:01.868Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/e2/2537ebcff11c1ee1ff17d8d0b6f4db75873e3b0fb32c2d4a2ee31ecb310a/docstring_parser-0.17.0-py3-none-any.whl", hash = "sha256:cf2569abd23dce8099b300f9b4fa8191e9582dda731fd533daf54c4551658708", size = 36896, upload-time = "2025-07-21T07:35:00.684Z" }, +] + [[package]] name = "exceptiongroup" version = "1.3.0" @@ -497,7 +507,7 @@ typing = [ [package.metadata] requires-dist = [ - { name = "anthropic", specifier = ">=0.67.0,<1.0.0" }, + { name = "anthropic", specifier = ">=0.69.0,<1.0.0" }, { name = "langchain-core", editable = "../../core" }, { name = "pydantic", specifier = ">=2.7.4,<3.0.0" }, ] From ca9217c02d041e2b352275900714fc7237d114de Mon Sep 17 00:00:00 2001 From: ccurme Date: Mon, 29 Sep 2025 15:56:28 -0400 Subject: [PATCH 2/6] release(anthropic): 0.3.21 (#33147) --- .../anthropic/langchain_anthropic/chat_models.py | 13 +++++++++++++ libs/partners/anthropic/pyproject.toml | 2 +- libs/partners/anthropic/uv.lock | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/libs/partners/anthropic/langchain_anthropic/chat_models.py b/libs/partners/anthropic/langchain_anthropic/chat_models.py index 704733b8306..446045fff83 100644 --- a/libs/partners/anthropic/langchain_anthropic/chat_models.py +++ b/libs/partners/anthropic/langchain_anthropic/chat_models.py @@ -1326,6 +1326,19 @@ class ChatAnthropic(BaseChatModel): 'id': 'toolu_01VdNgt1YV7kGfj9LFLm6HyQ', 'type': 'tool_call'}] + .. dropdown:: Memory tool + + .. code-block:: python + + from langchain_anthropic import ChatAnthropic + + llm = ChatAnthropic( + model="claude-sonnet-4-5-20250929", + betas=["context-management-2025-06-27"], + ) + llm_with_tools = llm.bind_tools([{"type": "memory_20250818", "name": "memory"}]) + response = llm_with_tools.invoke("What are my interests?") + Response metadata .. code-block:: python diff --git a/libs/partners/anthropic/pyproject.toml b/libs/partners/anthropic/pyproject.toml index 50ed966ea2e..456ecf7d034 100644 --- a/libs/partners/anthropic/pyproject.toml +++ b/libs/partners/anthropic/pyproject.toml @@ -12,7 +12,7 @@ dependencies = [ "pydantic>=2.7.4,<3.0.0", ] name = "langchain-anthropic" -version = "0.3.20" +version = "0.3.21" description = "An integration package connecting Anthropic and LangChain" readme = "README.md" diff --git a/libs/partners/anthropic/uv.lock b/libs/partners/anthropic/uv.lock index 12d138b67e3..3402a790c5f 100644 --- a/libs/partners/anthropic/uv.lock +++ b/libs/partners/anthropic/uv.lock @@ -465,7 +465,7 @@ wheels = [ [[package]] name = "langchain-anthropic" -version = "0.3.20" +version = "0.3.21" source = { editable = "." } dependencies = [ { name = "anthropic" }, From f402fdcea388397f373d6b28168f5b1c67b9c114 Mon Sep 17 00:00:00 2001 From: Mason Daugherty Date: Mon, 29 Sep 2025 16:13:47 -0400 Subject: [PATCH 3/6] fix(langchain): add `context_management` to Anthropic chat model init (#33150) --- libs/langchain/tests/unit_tests/chat_models/test_base.py | 1 + .../tests/unit_tests/chat_models/test_chat_models.py | 1 + 2 files changed, 2 insertions(+) diff --git a/libs/langchain/tests/unit_tests/chat_models/test_base.py b/libs/langchain/tests/unit_tests/chat_models/test_base.py index 5f1a06f52fa..4a1c6b7c7fb 100644 --- a/libs/langchain/tests/unit_tests/chat_models/test_base.py +++ b/libs/langchain/tests/unit_tests/chat_models/test_base.py @@ -270,6 +270,7 @@ def test_configurable_with_default() -> None: "stop_sequences": None, "anthropic_api_url": "https://api.anthropic.com", "anthropic_proxy": None, + "context_management": None, "anthropic_api_key": SecretStr("bar"), "betas": None, "default_headers": None, diff --git a/libs/langchain_v1/tests/unit_tests/chat_models/test_chat_models.py b/libs/langchain_v1/tests/unit_tests/chat_models/test_chat_models.py index cfcd419bf29..74ed8b17dbf 100644 --- a/libs/langchain_v1/tests/unit_tests/chat_models/test_chat_models.py +++ b/libs/langchain_v1/tests/unit_tests/chat_models/test_chat_models.py @@ -267,6 +267,7 @@ def test_configurable_with_default() -> None: "stop_sequences": None, "anthropic_api_url": "https://api.anthropic.com", "anthropic_proxy": None, + "context_management": None, "anthropic_api_key": SecretStr("bar"), "betas": None, "default_headers": None, From 3325196be17b9b138c9851c5b0df6e895aa55936 Mon Sep 17 00:00:00 2001 From: Mason Daugherty Date: Mon, 29 Sep 2025 16:16:17 -0400 Subject: [PATCH 4/6] fix(langchain): handle `gpt-5` model name in `init_chat_model` (#33148) expand to match any `gpt-*` model to openai --- libs/langchain/langchain/chat_models/base.py | 4 ++-- libs/langchain_v1/langchain/chat_models/base.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/langchain/langchain/chat_models/base.py b/libs/langchain/langchain/chat_models/base.py index 22f51747110..4de96a1a269 100644 --- a/libs/langchain/langchain/chat_models/base.py +++ b/libs/langchain/langchain/chat_models/base.py @@ -118,7 +118,7 @@ def init_chat_model( Will attempt to infer model_provider from model if not specified. The following providers will be inferred based on these model prefixes: - - ``gpt-3...`` | ``gpt-4...`` | ``o1...`` -> ``openai`` + - ``gpt-...`` | ``o1...`` | ``o3...`` -> ``openai`` - ``claude...`` -> ``anthropic`` - ``amazon...`` -> ``bedrock`` - ``gemini...`` -> ``google_vertexai`` @@ -497,7 +497,7 @@ _SUPPORTED_PROVIDERS = { def _attempt_infer_model_provider(model_name: str) -> Optional[str]: - if any(model_name.startswith(pre) for pre in ("gpt-3", "gpt-4", "o1", "o3")): + if any(model_name.startswith(pre) for pre in ("gpt-", "o1", "o3")): return "openai" if model_name.startswith("claude"): return "anthropic" diff --git a/libs/langchain_v1/langchain/chat_models/base.py b/libs/langchain_v1/langchain/chat_models/base.py index a062d348230..765cffb4d10 100644 --- a/libs/langchain_v1/langchain/chat_models/base.py +++ b/libs/langchain_v1/langchain/chat_models/base.py @@ -109,7 +109,7 @@ def init_chat_model( Will attempt to infer model_provider from model if not specified. The following providers will be inferred based on these model prefixes: - - 'gpt-3...' | 'gpt-4...' | 'o1...' -> 'openai' + - 'gpt-...' | 'o1...' | 'o3...' -> 'openai' - 'claude...' -> 'anthropic' - 'amazon....' -> 'bedrock' - 'gemini...' -> 'google_vertexai' @@ -474,7 +474,7 @@ _SUPPORTED_PROVIDERS = { def _attempt_infer_model_provider(model_name: str) -> str | None: - if any(model_name.startswith(pre) for pre in ("gpt-3", "gpt-4", "o1", "o3")): + if any(model_name.startswith(pre) for pre in ("gpt-", "o1", "o3")): return "openai" if model_name.startswith("claude"): return "anthropic" From 729637a347cceac75201f3f89ea48f135d9d75ba Mon Sep 17 00:00:00 2001 From: ccurme Date: Mon, 29 Sep 2025 16:38:01 -0400 Subject: [PATCH 5/6] docs(anthropic): document support for memory tool and context management (#33149) --- docs/docs/integrations/chat/anthropic.ipynb | 66 +++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/docs/docs/integrations/chat/anthropic.ipynb b/docs/docs/integrations/chat/anthropic.ipynb index 091ba69fd5f..215eeeb756d 100644 --- a/docs/docs/integrations/chat/anthropic.ipynb +++ b/docs/docs/integrations/chat/anthropic.ipynb @@ -1191,6 +1191,40 @@ "response.content" ] }, + { + "cell_type": "markdown", + "id": "74247a07-b153-444f-9c56-77659aeefc88", + "metadata": {}, + "source": [ + "## Context management\n", + "\n", + "Anthropic supports a context editing feature that will automatically manage the model's context window (e.g., by clearing tool results).\n", + "\n", + "See [Anthropic documentation](https://docs.claude.com/en/docs/build-with-claude/context-editing) for details and configuration options.\n", + "\n", + ":::info\n", + "Requires ``langchain-anthropic>=0.3.21``\n", + ":::" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cbb79c5d-37b5-4212-b36f-f27366192cf9", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_anthropic import ChatAnthropic\n", + "\n", + "llm = ChatAnthropic(\n", + " model=\"claude-sonnet-4-5-20250929\",\n", + " betas=[\"context-management-2025-06-27\"],\n", + " context_management={\"edits\": [{\"type\": \"clear_tool_uses_20250919\"}]},\n", + ")\n", + "llm_with_tools = llm.bind_tools([{\"type\": \"web_search_20250305\", \"name\": \"web_search\"}])\n", + "response = llm_with_tools.invoke(\"Search for recent developments in AI\")" + ] + }, { "cell_type": "markdown", "id": "cbfec7a9-d9df-4d12-844e-d922456dd9bf", @@ -1457,6 +1491,38 @@ "" ] }, + { + "cell_type": "markdown", + "id": "29405da2-d2ef-415c-b674-6e29073cd05e", + "metadata": {}, + "source": [ + "### Memory tool\n", + "\n", + "Claude supports a memory tool for client-side storage and retrieval of context across conversational threads. See docs [here](https://docs.claude.com/en/docs/agents-and-tools/tool-use/memory-tool) for details.\n", + "\n", + ":::info\n", + "Requires ``langchain-anthropic>=0.3.21``\n", + ":::" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bbd76eaa-041f-4fb8-8346-ca8fe0001c01", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_anthropic import ChatAnthropic\n", + "\n", + "llm = ChatAnthropic(\n", + " model=\"claude-sonnet-4-5-20250929\",\n", + " betas=[\"context-management-2025-06-27\"],\n", + ")\n", + "llm_with_tools = llm.bind_tools([{\"type\": \"memory_20250818\", \"name\": \"memory\"}])\n", + "\n", + "response = llm_with_tools.invoke(\"What are my interests?\")" + ] + }, { "cell_type": "markdown", "id": "040f381a-1768-479a-9a5e-aa2d7d77e0d5", From eed0f6c2894d680a1e997828adcedbb604a8dcdc Mon Sep 17 00:00:00 2001 From: Sydney Runkle <54324534+sydney-runkle@users.noreply.github.com> Date: Mon, 29 Sep 2025 19:23:26 -0700 Subject: [PATCH 6/6] feat(langchain): todo middleware (#33152) Porting the [planning middleware](https://github.com/langchain-ai/deepagents/blob/39c0138d0fdb2f8dc6a02606931cac2ffb777aff/src/deepagents/middleware.py#L21) over from deepagents. Also adding the ability to configure: * System prompt * Tool description ```py from langchain.agents.middleware.planning import PlanningMiddleware from langchain.agents import create_agent agent = create_agent("openai:gpt-4o", middleware=[PlanningMiddleware()]) result = await agent.invoke({"messages": [HumanMessage("Help me refactor my codebase")]}) print(result["todos"]) # Array of todo items with status tracking ``` --- .../langchain/agents/middleware/__init__.py | 2 + .../langchain/agents/middleware/planning.py | 197 ++++++++++++ .../agents/test_middleware_agent.py | 302 ++++++++++++++++-- 3 files changed, 469 insertions(+), 32 deletions(-) create mode 100644 libs/langchain_v1/langchain/agents/middleware/planning.py diff --git a/libs/langchain_v1/langchain/agents/middleware/__init__.py b/libs/langchain_v1/langchain/agents/middleware/__init__.py index 014989516ae..64d06e85445 100644 --- a/libs/langchain_v1/langchain/agents/middleware/__init__.py +++ b/libs/langchain_v1/langchain/agents/middleware/__init__.py @@ -1,6 +1,7 @@ """Middleware plugins for agents.""" from .human_in_the_loop import HumanInTheLoopMiddleware +from .planning import PlanningMiddleware from .prompt_caching import AnthropicPromptCachingMiddleware from .summarization import SummarizationMiddleware from .types import AgentMiddleware, AgentState, ModelRequest @@ -12,5 +13,6 @@ __all__ = [ "AnthropicPromptCachingMiddleware", "HumanInTheLoopMiddleware", "ModelRequest", + "PlanningMiddleware", "SummarizationMiddleware", ] diff --git a/libs/langchain_v1/langchain/agents/middleware/planning.py b/libs/langchain_v1/langchain/agents/middleware/planning.py new file mode 100644 index 00000000000..5fb451dcf55 --- /dev/null +++ b/libs/langchain_v1/langchain/agents/middleware/planning.py @@ -0,0 +1,197 @@ +"""Planning and task management middleware for agents.""" +# ruff: noqa: E501 + +from __future__ import annotations + +from typing import Annotated, Literal + +from langchain_core.messages import ToolMessage +from langchain_core.tools import tool +from langgraph.types import Command +from typing_extensions import NotRequired, TypedDict + +from langchain.agents.middleware.types import AgentMiddleware, AgentState, ModelRequest +from langchain.tools import InjectedToolCallId + + +class Todo(TypedDict): + """A single todo item with content and status.""" + + content: str + """The content/description of the todo item.""" + + status: Literal["pending", "in_progress", "completed"] + """The current status of the todo item.""" + + +class PlanningState(AgentState): + """State schema for the todo middleware.""" + + todos: NotRequired[list[Todo]] + """List of todo items for tracking task progress.""" + + +WRITE_TODOS_TOOL_DESCRIPTION = """Use this tool to create and manage a structured task list for your current work session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user. + +Only use this tool if you think it will be helpful in staying organized. If the user's request is trivial and takes less than 3 steps, it is better to NOT use this tool and just do the task directly. + +## When to Use This Tool +Use this tool in these scenarios: + +1. Complex multi-step tasks - When a task requires 3 or more distinct steps or actions +2. Non-trivial and complex tasks - Tasks that require careful planning or multiple operations +3. User explicitly requests todo list - When the user directly asks you to use the todo list +4. User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated) +5. The plan may need future revisions or updates based on results from the first few steps + +## How to Use This Tool +1. When you start working on a task - Mark it as in_progress BEFORE beginning work. +2. After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation. +3. You can also update future tasks, such as deleting them if they are no longer necessary, or adding new tasks that are necessary. Don't change previously completed tasks. +4. You can make several updates to the todo list at once. For example, when you complete a task, you can mark the next task you need to start as in_progress. + +## When NOT to Use This Tool +It is important to skip using this tool when: +1. There is only a single, straightforward task +2. The task is trivial and tracking it provides no benefit +3. The task can be completed in less than 3 trivial steps +4. The task is purely conversational or informational + +## Task States and Management + +1. **Task States**: Use these states to track progress: + - pending: Task not yet started + - in_progress: Currently working on (you can have multiple tasks in_progress at a time if they are not related to each other and can be run in parallel) + - completed: Task finished successfully + +2. **Task Management**: + - Update task status in real-time as you work + - Mark tasks complete IMMEDIATELY after finishing (don't batch completions) + - Complete current tasks before starting new ones + - Remove tasks that are no longer relevant from the list entirely + - IMPORTANT: When you write this todo list, you should mark your first task (or tasks) as in_progress immediately!. + - IMPORTANT: Unless all tasks are completed, you should always have at least one task in_progress to show the user that you are working on something. + +3. **Task Completion Requirements**: + - ONLY mark a task as completed when you have FULLY accomplished it + - If you encounter errors, blockers, or cannot finish, keep the task as in_progress + - When blocked, create a new task describing what needs to be resolved + - Never mark a task as completed if: + - There are unresolved issues or errors + - Work is partial or incomplete + - You encountered blockers that prevent completion + - You couldn't find necessary resources or dependencies + - Quality standards haven't been met + +4. **Task Breakdown**: + - Create specific, actionable items + - Break complex tasks into smaller, manageable steps + - Use clear, descriptive task names + +Being proactive with task management demonstrates attentiveness and ensures you complete all requirements successfully +Remember: If you only need to make a few tool calls to complete a task, and it is clear what you need to do, it is better to just do the task directly and NOT call this tool at all.""" + +WRITE_TODOS_SYSTEM_PROMPT = """## `write_todos` + +You have access to the `write_todos` tool to help you manage and plan complex objectives. +Use this tool for complex objectives to ensure that you are tracking each necessary step and giving the user visibility into your progress. +This tool is very helpful for planning complex objectives, and for breaking down these larger complex objectives into smaller steps. + +It is critical that you mark todos as completed as soon as you are done with a step. Do not batch up multiple steps before marking them as completed. +For simple objectives that only require a few steps, it is better to just complete the objective directly and NOT use this tool. +Writing todos takes time and tokens, use it when it is helpful for managing complex many-step problems! But not for simple few-step requests. + +## Important To-Do List Usage Notes to Remember +- The `write_todos` tool should never be called multiple times in parallel. +- Don't be afraid to revise the To-Do list as you go. New information may reveal new tasks that need to be done, or old tasks that are irrelevant.""" + + +@tool(description=WRITE_TODOS_TOOL_DESCRIPTION) +def write_todos(todos: list[Todo], tool_call_id: Annotated[str, InjectedToolCallId]) -> Command: + """Create and manage a structured task list for your current work session.""" + return Command( + update={ + "todos": todos, + "messages": [ToolMessage(f"Updated todo list to {todos}", tool_call_id=tool_call_id)], + } + ) + + +class PlanningMiddleware(AgentMiddleware): + """Middleware that provides todo list management capabilities to agents. + + This middleware adds a `write_todos` tool that allows agents to create and manage + structured task lists for complex multi-step operations. It's designed to help + agents track progress, organize complex tasks, and provide users with visibility + into task completion status. + + The middleware automatically injects system prompts that guide the agent on when + and how to use the todo functionality effectively. + + Example: + ```python + from langchain.agents.middleware.planning import PlanningMiddleware + from langchain.agents import create_agent + + agent = create_agent("openai:gpt-4o", middleware=[PlanningMiddleware()]) + + # Agent now has access to write_todos tool and todo state tracking + result = await agent.invoke({"messages": [HumanMessage("Help me refactor my codebase")]}) + + print(result["todos"]) # Array of todo items with status tracking + ``` + + Args: + system_prompt: Custom system prompt to guide the agent on using the todo tool. + If not provided, uses the default ``WRITE_TODOS_SYSTEM_PROMPT``. + tool_description: Custom description for the write_todos tool. + If not provided, uses the default ``WRITE_TODOS_TOOL_DESCRIPTION``. + """ + + state_schema = PlanningState + + def __init__( + self, + *, + system_prompt: str = WRITE_TODOS_SYSTEM_PROMPT, + tool_description: str = WRITE_TODOS_TOOL_DESCRIPTION, + ) -> None: + """Initialize the PlanningMiddleware with optional custom prompts. + + Args: + system_prompt: Custom system prompt to guide the agent on using the todo tool. + tool_description: Custom description for the write_todos tool. + """ + super().__init__() + self.system_prompt = system_prompt + self.tool_description = tool_description + + # Dynamically create the write_todos tool with the custom description + @tool(description=self.tool_description) + def write_todos( + todos: list[Todo], tool_call_id: Annotated[str, InjectedToolCallId] + ) -> Command: + """Create and manage a structured task list for your current work session.""" + return Command( + update={ + "todos": todos, + "messages": [ + ToolMessage(f"Updated todo list to {todos}", tool_call_id=tool_call_id) + ], + } + ) + + self.tools = [write_todos] + + def modify_model_request( # type: ignore[override] + self, + request: ModelRequest, + state: PlanningState, # noqa: ARG002 + ) -> ModelRequest: + """Update the system prompt to include the todo system prompt.""" + request.system_prompt = ( + request.system_prompt + "\n\n" + self.system_prompt + if request.system_prompt + else self.system_prompt + ) + return request diff --git a/libs/langchain_v1/tests/unit_tests/agents/test_middleware_agent.py b/libs/langchain_v1/tests/unit_tests/agents/test_middleware_agent.py index 519c99e9a0d..62d4addccb2 100644 --- a/libs/langchain_v1/tests/unit_tests/agents/test_middleware_agent.py +++ b/libs/langchain_v1/tests/unit_tests/agents/test_middleware_agent.py @@ -1,14 +1,9 @@ -import pytest +import warnings +from types import ModuleType from typing import Any from unittest.mock import patch -from types import ModuleType -from syrupy.assertion import SnapshotAssertion - -import warnings -from langgraph.runtime import Runtime -from typing_extensions import Annotated -from pydantic import BaseModel, Field +import pytest from langchain_core.language_models import BaseChatModel from langchain_core.language_models.chat_models import BaseChatModel from langchain_core.messages import ( @@ -18,31 +13,42 @@ from langchain_core.messages import ( ToolCall, ToolMessage, ) -from langchain_core.tools import tool, InjectedToolCallId +from langchain_core.outputs import ChatGeneration, ChatResult +from langchain_core.tools import InjectedToolCallId, tool +from langgraph.checkpoint.base import BaseCheckpointSaver +from langgraph.checkpoint.memory import InMemorySaver +from langgraph.constants import END +from langgraph.graph.message import REMOVE_ALL_MESSAGES +from langgraph.runtime import Runtime +from langgraph.types import Command +from pydantic import BaseModel, Field +from syrupy.assertion import SnapshotAssertion +from typing_extensions import Annotated -from langchain.agents.middleware_agent import create_agent -from langchain.tools import InjectedState from langchain.agents.middleware.human_in_the_loop import ( - HumanInTheLoopMiddleware, ActionRequest, + HumanInTheLoopMiddleware, +) +from langchain.agents.middleware.planning import ( + PlanningMiddleware, + PlanningState, + WRITE_TODOS_SYSTEM_PROMPT, + write_todos, + WRITE_TODOS_TOOL_DESCRIPTION, ) from langchain.agents.middleware.prompt_caching import AnthropicPromptCachingMiddleware from langchain.agents.middleware.summarization import SummarizationMiddleware from langchain.agents.middleware.types import ( AgentMiddleware, - ModelRequest, AgentState, + ModelRequest, OmitFromInput, OmitFromOutput, PrivateStateAttr, ) - -from langgraph.checkpoint.base import BaseCheckpointSaver -from langgraph.checkpoint.memory import InMemorySaver -from langgraph.constants import END -from langgraph.graph.message import REMOVE_ALL_MESSAGES -from langgraph.types import Command +from langchain.agents.middleware_agent import create_agent from langchain.agents.structured_output import ToolStrategy +from langchain.tools import InjectedState from .messages import _AnyIdHumanMessage, _AnyIdToolMessage from .model import FakeToolCallingModel @@ -1105,14 +1111,9 @@ def test_summarization_middleware_summary_creation() -> None: class MockModel(BaseChatModel): def invoke(self, prompt): - from langchain_core.messages import AIMessage - return AIMessage(content="Generated summary") def _generate(self, messages, **kwargs): - from langchain_core.outputs import ChatResult, ChatGeneration - from langchain_core.messages import AIMessage - return ChatResult(generations=[ChatGeneration(message=AIMessage(content="Summary"))]) @property @@ -1136,9 +1137,6 @@ def test_summarization_middleware_summary_creation() -> None: raise Exception("Model error") def _generate(self, messages, **kwargs): - from langchain_core.outputs import ChatResult, ChatGeneration - from langchain_core.messages import AIMessage - return ChatResult(generations=[ChatGeneration(message=AIMessage(content="Summary"))]) @property @@ -1155,14 +1153,9 @@ def test_summarization_middleware_full_workflow() -> None: class MockModel(BaseChatModel): def invoke(self, prompt): - from langchain_core.messages import AIMessage - return AIMessage(content="Generated summary") def _generate(self, messages, **kwargs): - from langchain_core.outputs import ChatResult, ChatGeneration - from langchain_core.messages import AIMessage - return ChatResult(generations=[ChatGeneration(message=AIMessage(content="Summary"))]) @property @@ -1423,3 +1416,248 @@ def test_jump_to_is_ephemeral() -> None: agent = agent.compile() result = agent.invoke({"messages": [HumanMessage("Hello")]}) assert "jump_to" not in result + + +# Tests for PlanningMiddleware +def test_planning_middleware_initialization() -> None: + """Test that PlanningMiddleware initializes correctly.""" + middleware = PlanningMiddleware() + assert middleware.state_schema == PlanningState + assert len(middleware.tools) == 1 + assert middleware.tools[0].name == "write_todos" + + +@pytest.mark.parametrize( + "original_prompt,expected_prompt_prefix", + [ + ("Original prompt", "Original prompt\n\n## `write_todos`"), + (None, "## `write_todos`"), + ], +) +def test_planning_middleware_modify_model_request(original_prompt, expected_prompt_prefix) -> None: + """Test that modify_model_request handles system prompts correctly.""" + middleware = PlanningMiddleware() + model = FakeToolCallingModel() + + request = ModelRequest( + model=model, + system_prompt=original_prompt, + messages=[HumanMessage(content="Hello")], + tool_choice=None, + tools=[], + response_format=None, + model_settings={}, + ) + + state: PlanningState = {"messages": [HumanMessage(content="Hello")]} + modified_request = middleware.modify_model_request(request, state) + assert modified_request.system_prompt.startswith(expected_prompt_prefix) + + +@pytest.mark.parametrize( + "todos,expected_message", + [ + ([], "Updated todo list to []"), + ( + [{"content": "Task 1", "status": "pending"}], + "Updated todo list to [{'content': 'Task 1', 'status': 'pending'}]", + ), + ( + [ + {"content": "Task 1", "status": "pending"}, + {"content": "Task 2", "status": "in_progress"}, + ], + "Updated todo list to [{'content': 'Task 1', 'status': 'pending'}, {'content': 'Task 2', 'status': 'in_progress'}]", + ), + ( + [ + {"content": "Task 1", "status": "pending"}, + {"content": "Task 2", "status": "in_progress"}, + {"content": "Task 3", "status": "completed"}, + ], + "Updated todo list to [{'content': 'Task 1', 'status': 'pending'}, {'content': 'Task 2', 'status': 'in_progress'}, {'content': 'Task 3', 'status': 'completed'}]", + ), + ], +) +def test_planning_middleware_write_todos_tool_execution(todos, expected_message) -> None: + """Test that the write_todos tool executes correctly.""" + tool_call = { + "args": {"todos": todos}, + "name": "write_todos", + "type": "tool_call", + "id": "test_call", + } + result = write_todos.invoke(tool_call) + assert result.update["todos"] == todos + assert result.update["messages"][0].content == expected_message + + +@pytest.mark.parametrize( + "invalid_todos", + [ + [{"content": "Task 1", "status": "invalid_status"}], + [{"status": "pending"}], + ], +) +def test_planning_middleware_write_todos_tool_validation_errors(invalid_todos) -> None: + """Test that the write_todos tool rejects invalid input.""" + tool_call = { + "args": {"todos": invalid_todos}, + "name": "write_todos", + "type": "tool_call", + "id": "test_call", + } + with pytest.raises(Exception): + write_todos.invoke(tool_call) + + +def test_planning_middleware_agent_creation_with_middleware() -> None: + """Test that an agent can be created with the planning middleware.""" + model = FakeToolCallingModel( + tool_calls=[ + [ + { + "args": {"todos": [{"content": "Task 1", "status": "pending"}]}, + "name": "write_todos", + "type": "tool_call", + "id": "test_call", + } + ], + [ + { + "args": {"todos": [{"content": "Task 1", "status": "in_progress"}]}, + "name": "write_todos", + "type": "tool_call", + "id": "test_call", + } + ], + [ + { + "args": {"todos": [{"content": "Task 1", "status": "completed"}]}, + "name": "write_todos", + "type": "tool_call", + "id": "test_call", + } + ], + [], + ] + ) + middleware = PlanningMiddleware() + agent = create_agent(model=model, middleware=[middleware]) + agent = agent.compile() + + result = agent.invoke({"messages": [HumanMessage("Hello")]}) + assert result["todos"] == [{"content": "Task 1", "status": "completed"}] + + # human message (1) + # ai message (2) - initial todo + # tool message (3) + # ai message (4) - updated todo + # tool message (5) + # ai message (6) - complete todo + # tool message (7) + # ai message (8) - no tool calls + assert len(result["messages"]) == 8 + + +def test_planning_middleware_custom_system_prompt() -> None: + """Test that PlanningMiddleware can be initialized with custom system prompt.""" + custom_system_prompt = "Custom todo system prompt for testing" + middleware = PlanningMiddleware(system_prompt=custom_system_prompt) + model = FakeToolCallingModel() + + request = ModelRequest( + model=model, + system_prompt="Original prompt", + messages=[HumanMessage(content="Hello")], + tool_choice=None, + tools=[], + response_format=None, + model_settings={}, + ) + + state: PlanningState = {"messages": [HumanMessage(content="Hello")]} + modified_request = middleware.modify_model_request(request, state) + assert modified_request.system_prompt == f"Original prompt\n\n{custom_system_prompt}" + + +def test_planning_middleware_custom_tool_description() -> None: + """Test that PlanningMiddleware can be initialized with custom tool description.""" + custom_tool_description = "Custom tool description for testing" + middleware = PlanningMiddleware(tool_description=custom_tool_description) + + assert len(middleware.tools) == 1 + tool = middleware.tools[0] + assert tool.description == custom_tool_description + + +def test_planning_middleware_custom_system_prompt_and_tool_description() -> None: + """Test that PlanningMiddleware can be initialized with both custom prompts.""" + custom_system_prompt = "Custom system prompt" + custom_tool_description = "Custom tool description" + middleware = PlanningMiddleware( + system_prompt=custom_system_prompt, + tool_description=custom_tool_description, + ) + + # Verify system prompt + model = FakeToolCallingModel() + request = ModelRequest( + model=model, + system_prompt=None, + messages=[HumanMessage(content="Hello")], + tool_choice=None, + tools=[], + response_format=None, + model_settings={}, + ) + + state: PlanningState = {"messages": [HumanMessage(content="Hello")]} + modified_request = middleware.modify_model_request(request, state) + assert modified_request.system_prompt == custom_system_prompt + + # Verify tool description + assert len(middleware.tools) == 1 + tool = middleware.tools[0] + assert tool.description == custom_tool_description + + +def test_planning_middleware_default_prompts() -> None: + """Test that PlanningMiddleware uses default prompts when none provided.""" + middleware = PlanningMiddleware() + + # Verify default system prompt + assert middleware.system_prompt == WRITE_TODOS_SYSTEM_PROMPT + + # Verify default tool description + assert middleware.tool_description == WRITE_TODOS_TOOL_DESCRIPTION + assert len(middleware.tools) == 1 + tool = middleware.tools[0] + assert tool.description == WRITE_TODOS_TOOL_DESCRIPTION + + +def test_planning_middleware_custom_system_prompt() -> None: + """Test that custom tool executes correctly in an agent.""" + middleware = PlanningMiddleware(system_prompt="call the write_todos tool") + + model = FakeToolCallingModel( + tool_calls=[ + [ + { + "args": {"todos": [{"content": "Custom task", "status": "pending"}]}, + "name": "write_todos", + "type": "tool_call", + "id": "test_call", + } + ], + [], + ] + ) + + agent = create_agent(model=model, middleware=[middleware]) + agent = agent.compile() + + result = agent.invoke({"messages": [HumanMessage("Hello")]}) + assert result["todos"] == [{"content": "Custom task", "status": "pending"}] + # assert custom system prompt is in the first AI message + assert "call the write_todos tool" in result["messages"][1].content