deepagents 0.3.5__py3-none-any.whl → 0.3.6__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.
- deepagents/backends/utils.py +1 -2
- deepagents/graph.py +22 -5
- deepagents/middleware/filesystem.py +22 -12
- deepagents/middleware/subagents.py +53 -13
- {deepagents-0.3.5.dist-info → deepagents-0.3.6.dist-info}/METADATA +50 -39
- {deepagents-0.3.5.dist-info → deepagents-0.3.6.dist-info}/RECORD +8 -8
- {deepagents-0.3.5.dist-info → deepagents-0.3.6.dist-info}/WHEEL +0 -0
- {deepagents-0.3.5.dist-info → deepagents-0.3.6.dist-info}/top_level.txt +0 -0
deepagents/backends/utils.py
CHANGED
|
@@ -12,8 +12,7 @@ from typing import Any, Literal
|
|
|
12
12
|
|
|
13
13
|
import wcmatch.glob as wcglob
|
|
14
14
|
|
|
15
|
-
from deepagents.backends.protocol import FileInfo as _FileInfo
|
|
16
|
-
from deepagents.backends.protocol import GrepMatch as _GrepMatch
|
|
15
|
+
from deepagents.backends.protocol import FileInfo as _FileInfo, GrepMatch as _GrepMatch
|
|
17
16
|
|
|
18
17
|
EMPTY_CONTENT_WARNING = "System reminder: File exists but has empty contents"
|
|
19
18
|
MAX_LINE_LENGTH = 10000
|
deepagents/graph.py
CHANGED
|
@@ -62,18 +62,28 @@ def create_deep_agent(
|
|
|
62
62
|
) -> CompiledStateGraph:
|
|
63
63
|
"""Create a deep agent.
|
|
64
64
|
|
|
65
|
+
Deep agents require a LLM that supports tool calling.
|
|
66
|
+
|
|
65
67
|
This agent will by default have access to a tool to write todos (`write_todos`),
|
|
66
68
|
seven file and execution tools: `ls`, `read_file`, `write_file`, `edit_file`, `glob`, `grep`, `execute`,
|
|
67
|
-
and a tool to call subagents.
|
|
69
|
+
and a tool to call subagents (`task`).
|
|
68
70
|
|
|
69
71
|
The `execute` tool allows running shell commands if the backend implements `SandboxBackendProtocol`.
|
|
70
72
|
For non-sandbox backends, the `execute` tool will return an error message.
|
|
71
73
|
|
|
72
74
|
Args:
|
|
73
|
-
model: The model to use.
|
|
75
|
+
model: The model to use.
|
|
76
|
+
|
|
77
|
+
Defaults to `claude-sonnet-4-5-20250929`.
|
|
78
|
+
|
|
79
|
+
Use the `provider:model` format (e.g., `openai:gpt-5`) to quickly switch between models.
|
|
74
80
|
tools: The tools the agent should have access to.
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
|
|
82
|
+
In addition to custom tools you provide, deep agents include built-in tools for planning,
|
|
83
|
+
file management, and subagent spawning.
|
|
84
|
+
system_prompt: The additional instructions the agent should have.
|
|
85
|
+
|
|
86
|
+
Will go in the system prompt.
|
|
77
87
|
middleware: Additional middleware to apply after standard middleware.
|
|
78
88
|
subagents: The subagents to use.
|
|
79
89
|
|
|
@@ -93,7 +103,10 @@ def create_deep_agent(
|
|
|
93
103
|
to the backend's `root_dir`. Later sources override earlier ones for skills with the
|
|
94
104
|
same name (last one wins).
|
|
95
105
|
memory: Optional list of memory file paths (`AGENTS.md` files) to load
|
|
96
|
-
(e.g., `["/memory/AGENTS.md"]`).
|
|
106
|
+
(e.g., `["/memory/AGENTS.md"]`).
|
|
107
|
+
|
|
108
|
+
Display names are automatically derived from paths.
|
|
109
|
+
|
|
97
110
|
Memory is loaded at agent startup and added into the system prompt.
|
|
98
111
|
response_format: A structured output response format to use for the agent.
|
|
99
112
|
context_schema: The schema of the deep agent.
|
|
@@ -104,6 +117,10 @@ def create_deep_agent(
|
|
|
104
117
|
Pass either a `Backend` instance or a callable factory like `lambda rt: StateBackend(rt)`.
|
|
105
118
|
For execution support, use a backend that implements `SandboxBackendProtocol`.
|
|
106
119
|
interrupt_on: Mapping of tool names to interrupt configs.
|
|
120
|
+
|
|
121
|
+
Pass to pause agent execution at specified tool calls for human approval or modification.
|
|
122
|
+
|
|
123
|
+
Example: `interrupt_on={"edit_file": True}` pauses before every edit.
|
|
107
124
|
debug: Whether to enable debug mode. Passed through to `create_agent`.
|
|
108
125
|
name: The name of the agent. Passed through to `create_agent`.
|
|
109
126
|
cache: The cache to use for the agent. Passed through to `create_agent`.
|
|
@@ -20,10 +20,8 @@ from langgraph.types import Command
|
|
|
20
20
|
from typing_extensions import TypedDict
|
|
21
21
|
|
|
22
22
|
from deepagents.backends import StateBackend
|
|
23
|
-
|
|
24
|
-
# Re-export type here for backwards compatibility
|
|
25
|
-
from deepagents.backends.protocol import BACKEND_TYPES as BACKEND_TYPES
|
|
26
23
|
from deepagents.backends.protocol import (
|
|
24
|
+
BACKEND_TYPES as BACKEND_TYPES, # Re-export for backwards compatibility
|
|
27
25
|
BackendProtocol,
|
|
28
26
|
EditResult,
|
|
29
27
|
SandboxBackendProtocol,
|
|
@@ -801,21 +799,33 @@ Here are the first 10 lines of the result:
|
|
|
801
799
|
class FilesystemMiddleware(AgentMiddleware):
|
|
802
800
|
"""Middleware for providing filesystem and optional execution tools to an agent.
|
|
803
801
|
|
|
804
|
-
This middleware adds filesystem tools to the agent: ls
|
|
805
|
-
edit_file
|
|
806
|
-
the BackendProtocol
|
|
802
|
+
This middleware adds filesystem tools to the agent: `ls`, `read_file`, `write_file`,
|
|
803
|
+
`edit_file`, `glob`, and `grep`. Files can be stored using any backend that implements
|
|
804
|
+
the `BackendProtocol`.
|
|
807
805
|
|
|
808
|
-
If the backend implements SandboxBackendProtocol
|
|
806
|
+
If the backend implements `SandboxBackendProtocol`, an `execute` tool is also added
|
|
809
807
|
for running shell commands.
|
|
810
808
|
|
|
809
|
+
This middleware also automatically evicts large tool results to the file system when
|
|
810
|
+
they exceed a token threshold, preventing context window saturation.
|
|
811
|
+
|
|
811
812
|
Args:
|
|
812
|
-
backend: Backend for file storage and optional execution.
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
813
|
+
backend: Backend for file storage and optional execution.
|
|
814
|
+
|
|
815
|
+
If not provided, defaults to `StateBackend` (ephemeral storage in agent state).
|
|
816
|
+
|
|
817
|
+
For persistent storage or hybrid setups, use `CompositeBackend` with custom routes.
|
|
818
|
+
|
|
819
|
+
For execution support, use a backend that implements `SandboxBackendProtocol`.
|
|
816
820
|
system_prompt: Optional custom system prompt override.
|
|
817
821
|
custom_tool_descriptions: Optional custom tool descriptions override.
|
|
818
|
-
tool_token_limit_before_evict:
|
|
822
|
+
tool_token_limit_before_evict: Token limit before evicting a tool result to the
|
|
823
|
+
filesystem.
|
|
824
|
+
|
|
825
|
+
Defaults to 20,000 tokens.
|
|
826
|
+
|
|
827
|
+
When exceeded, writes the result using the configured backend and replaces it
|
|
828
|
+
with a truncated preview and file reference.
|
|
819
829
|
|
|
820
830
|
Example:
|
|
821
831
|
```python
|
|
@@ -21,41 +21,70 @@ class SubAgent(TypedDict):
|
|
|
21
21
|
will be applied first, followed by any `middleware` specified in this spec.
|
|
22
22
|
To use only custom middleware without the defaults, pass `default_middleware=[]`
|
|
23
23
|
to `SubAgentMiddleware`.
|
|
24
|
+
|
|
25
|
+
Required fields:
|
|
26
|
+
name: Unique identifier for the subagent.
|
|
27
|
+
|
|
28
|
+
The main agent uses this name when calling the `task()` tool.
|
|
29
|
+
description: What this subagent does.
|
|
30
|
+
|
|
31
|
+
Be specific and action-oriented. The main agent uses this to decide when to delegate.
|
|
32
|
+
system_prompt: Instructions for the subagent.
|
|
33
|
+
|
|
34
|
+
Include tool usage guidance and output format requirements.
|
|
35
|
+
tools: Tools the subagent can use.
|
|
36
|
+
|
|
37
|
+
Keep this minimal and include only what's needed.
|
|
38
|
+
|
|
39
|
+
Optional fields:
|
|
40
|
+
model: Override the main agent's model.
|
|
41
|
+
|
|
42
|
+
Use the format `'provider:model-name'` (e.g., `'openai:gpt-4o'`).
|
|
43
|
+
middleware: Additional middleware for custom behavior, logging, or rate limiting.
|
|
44
|
+
interrupt_on: Configure human-in-the-loop for specific tools.
|
|
45
|
+
|
|
46
|
+
Requires a checkpointer.
|
|
24
47
|
"""
|
|
25
48
|
|
|
26
49
|
name: str
|
|
27
|
-
"""
|
|
50
|
+
"""Unique identifier for the subagent."""
|
|
28
51
|
|
|
29
52
|
description: str
|
|
30
|
-
"""The
|
|
53
|
+
"""What this subagent does. The main agent uses this to decide when to delegate."""
|
|
31
54
|
|
|
32
55
|
system_prompt: str
|
|
33
|
-
"""
|
|
56
|
+
"""Instructions for the subagent."""
|
|
34
57
|
|
|
35
58
|
tools: Sequence[BaseTool | Callable | dict[str, Any]]
|
|
36
|
-
"""
|
|
59
|
+
"""Tools the subagent can use."""
|
|
37
60
|
|
|
38
61
|
model: NotRequired[str | BaseChatModel]
|
|
39
|
-
"""
|
|
62
|
+
"""Override the main agent's model. Use `'provider:model-name'` format."""
|
|
40
63
|
|
|
41
64
|
middleware: NotRequired[list[AgentMiddleware]]
|
|
42
|
-
"""Additional middleware
|
|
65
|
+
"""Additional middleware for custom behavior."""
|
|
43
66
|
|
|
44
67
|
interrupt_on: NotRequired[dict[str, bool | InterruptOnConfig]]
|
|
45
|
-
"""
|
|
68
|
+
"""Configure human-in-the-loop for specific tools."""
|
|
46
69
|
|
|
47
70
|
|
|
48
71
|
class CompiledSubAgent(TypedDict):
|
|
49
|
-
"""A pre-compiled agent spec.
|
|
72
|
+
"""A pre-compiled agent spec.
|
|
73
|
+
|
|
74
|
+
Important: The runnable's state schema must include a 'messages' key.
|
|
75
|
+
This is required for the subagent to communicate results back to the main agent.
|
|
76
|
+
When the subagent completes, the final message in the 'messages' list will be
|
|
77
|
+
extracted and returned as a ToolMessage to the parent agent.
|
|
78
|
+
"""
|
|
50
79
|
|
|
51
80
|
name: str
|
|
52
|
-
"""
|
|
81
|
+
"""Unique identifier for the subagent."""
|
|
53
82
|
|
|
54
83
|
description: str
|
|
55
|
-
"""
|
|
84
|
+
"""What this subagent does."""
|
|
56
85
|
|
|
57
86
|
runnable: Runnable
|
|
58
|
-
"""The Runnable to use for the agent."""
|
|
87
|
+
"""The Runnable to use for the agent. Must return a state with a 'messages' key."""
|
|
59
88
|
|
|
60
89
|
|
|
61
90
|
DEFAULT_SUBAGENT_PROMPT = "In order to complete the objective that the user asks of you, you have access to a number of standard tools."
|
|
@@ -251,6 +280,7 @@ def _get_subagents(
|
|
|
251
280
|
system_prompt=DEFAULT_SUBAGENT_PROMPT,
|
|
252
281
|
tools=default_tools,
|
|
253
282
|
middleware=general_purpose_middleware,
|
|
283
|
+
name="general-purpose",
|
|
254
284
|
)
|
|
255
285
|
agents["general-purpose"] = general_purpose_subagent
|
|
256
286
|
subagent_descriptions.append(f"- general-purpose: {DEFAULT_GENERAL_PURPOSE_DESCRIPTION}")
|
|
@@ -277,6 +307,7 @@ def _get_subagents(
|
|
|
277
307
|
system_prompt=agent_["system_prompt"],
|
|
278
308
|
tools=_tools,
|
|
279
309
|
middleware=_middleware,
|
|
310
|
+
name=agent_["name"],
|
|
280
311
|
)
|
|
281
312
|
return agents, subagent_descriptions
|
|
282
313
|
|
|
@@ -318,6 +349,15 @@ def _create_task_tool(
|
|
|
318
349
|
subagent_description_str = "\n".join(subagent_descriptions)
|
|
319
350
|
|
|
320
351
|
def _return_command_with_state_update(result: dict, tool_call_id: str) -> Command:
|
|
352
|
+
# Validate that the result contains a 'messages' key
|
|
353
|
+
if "messages" not in result:
|
|
354
|
+
error_msg = (
|
|
355
|
+
"CompiledSubAgent must return a state containing a 'messages' key. "
|
|
356
|
+
"Custom StateGraphs used with CompiledSubAgent should include 'messages' "
|
|
357
|
+
"in their state schema to communicate results back to the main agent."
|
|
358
|
+
)
|
|
359
|
+
raise ValueError(error_msg)
|
|
360
|
+
|
|
321
361
|
state_update = {k: v for k, v in result.items() if k not in _EXCLUDED_STATE_KEYS}
|
|
322
362
|
# Strip trailing whitespace to prevent API errors with Anthropic
|
|
323
363
|
message_text = result["messages"][-1].text.rstrip() if result["messages"][-1].text else ""
|
|
@@ -352,7 +392,7 @@ def _create_task_tool(
|
|
|
352
392
|
allowed_types = ", ".join([f"`{k}`" for k in subagent_graphs])
|
|
353
393
|
return f"We cannot invoke subagent {subagent_type} because it does not exist, the only allowed types are {allowed_types}"
|
|
354
394
|
subagent, subagent_state = _validate_and_prepare_state(subagent_type, description, runtime)
|
|
355
|
-
result = subagent.invoke(subagent_state
|
|
395
|
+
result = subagent.invoke(subagent_state)
|
|
356
396
|
if not runtime.tool_call_id:
|
|
357
397
|
value_error_msg = "Tool call ID is required for subagent invocation"
|
|
358
398
|
raise ValueError(value_error_msg)
|
|
@@ -367,7 +407,7 @@ def _create_task_tool(
|
|
|
367
407
|
allowed_types = ", ".join([f"`{k}`" for k in subagent_graphs])
|
|
368
408
|
return f"We cannot invoke subagent {subagent_type} because it does not exist, the only allowed types are {allowed_types}"
|
|
369
409
|
subagent, subagent_state = _validate_and_prepare_state(subagent_type, description, runtime)
|
|
370
|
-
result = await subagent.ainvoke(subagent_state
|
|
410
|
+
result = await subagent.ainvoke(subagent_state)
|
|
371
411
|
if not runtime.tool_call_id:
|
|
372
412
|
value_error_msg = "Tool call ID is required for subagent invocation"
|
|
373
413
|
raise ValueError(value_error_msg)
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.6
|
|
4
4
|
Summary: General purpose 'deep agent' with sub-agent spawning, todo list capabilities, and mock file system. Built on LangGraph.
|
|
5
5
|
License: MIT
|
|
6
6
|
Project-URL: Homepage, https://docs.langchain.com/oss/python/deepagents/overview
|
|
7
7
|
Project-URL: Documentation, https://reference.langchain.com/python/deepagents/
|
|
8
8
|
Project-URL: Source, https://github.com/langchain-ai/deepagents
|
|
9
|
-
Project-URL: Twitter, https://x.com/
|
|
9
|
+
Project-URL: Twitter, https://x.com/LangChain
|
|
10
10
|
Project-URL: Slack, https://www.langchain.com/join-community
|
|
11
11
|
Project-URL: Reddit, https://www.reddit.com/r/LangChain/
|
|
12
12
|
Requires-Python: <4.0,>=3.11
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
Requires-Dist: langchain-core<2.0.0,>=1.2.6
|
|
15
|
-
Requires-Dist: langchain<2.0.0,>=1.2.
|
|
15
|
+
Requires-Dist: langchain<2.0.0,>=1.2.4
|
|
16
16
|
Requires-Dist: langchain-anthropic<2.0.0,>=1.3.1
|
|
17
17
|
Requires-Dist: langchain-google-genai<5.0.0,>=4.1.3
|
|
18
18
|
Requires-Dist: wcmatch
|
|
19
19
|
|
|
20
20
|
# 🧠🤖Deep Agents
|
|
21
21
|
|
|
22
|
-
Using an LLM to call tools in a loop is the simplest form of an agent.
|
|
23
|
-
This architecture, however, can yield agents that are “shallow” and fail to plan and act over longer, more complex tasks.
|
|
22
|
+
Using an LLM to call tools in a loop is the simplest form of an agent.
|
|
23
|
+
This architecture, however, can yield agents that are “shallow” and fail to plan and act over longer, more complex tasks.
|
|
24
24
|
|
|
25
25
|
Applications like “Deep Research”, "Manus", and “Claude Code” have gotten around this limitation by implementing a combination of four things:
|
|
26
26
|
a **planning tool**, **sub agents**, access to a **file system**, and a **detailed prompt**.
|
|
@@ -46,7 +46,9 @@ poetry add deepagents
|
|
|
46
46
|
|
|
47
47
|
## Usage
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
> **Note:** `deepagents` requires using a LLM that supports [tool calling](https://python.langchain.com/docs/concepts/tool_calling/).
|
|
50
|
+
|
|
51
|
+
This example uses [Tavily](https://tavily.com/) as an example search provider, but you can substitute any search API (e.g., DuckDuckGo, SerpAPI, Brave Search). To run the example below, you will need to `pip install tavily-python`.
|
|
50
52
|
|
|
51
53
|
Make sure to set `TAVILY_API_KEY` in your environment. You can generate one [here](https://www.tavily.com/).
|
|
52
54
|
|
|
@@ -100,21 +102,22 @@ The agent created with `create_deep_agent` is just a LangGraph graph - so you ca
|
|
|
100
102
|
in the same way you would any LangGraph agent.
|
|
101
103
|
|
|
102
104
|
## Core Capabilities
|
|
105
|
+
|
|
103
106
|
**Planning & Task Decomposition**
|
|
104
107
|
|
|
105
|
-
|
|
108
|
+
Deep Agents include a built-in `write_todos` tool that enables agents to break down complex tasks into discrete steps, track progress, and adapt plans as new information emerges.
|
|
106
109
|
|
|
107
110
|
**Context Management**
|
|
108
111
|
|
|
109
|
-
|
|
112
|
+
File system tools (`ls`, `read_file`, `write_file`, `edit_file`, `glob`, `grep`) allow agents to offload large context to memory, preventing context window overflow and enabling work with variable-length tool results.
|
|
110
113
|
|
|
111
114
|
**Subagent Spawning**
|
|
112
115
|
|
|
113
|
-
|
|
116
|
+
A built-in `task` tool enables agents to spawn specialized subagents for context isolation. This keeps the main agent's context clean while still going deep on specific subtasks.
|
|
114
117
|
|
|
115
118
|
**Long-term Memory**
|
|
116
119
|
|
|
117
|
-
|
|
120
|
+
Extend agents with persistent memory across threads using LangGraph's `BaseStore`. Agents can save and retrieve information from previous conversations.
|
|
118
121
|
|
|
119
122
|
## Customizing Deep Agents
|
|
120
123
|
|
|
@@ -122,19 +125,20 @@ There are several parameters you can pass to `create_deep_agent` to create your
|
|
|
122
125
|
|
|
123
126
|
### `model`
|
|
124
127
|
|
|
125
|
-
By default, `deepagents` uses `
|
|
128
|
+
By default, `deepagents` uses `claude-sonnet-4-5-20250929`. You can customize this by passing any [LangChain model object](https://python.langchain.com/docs/integrations/chat/).
|
|
129
|
+
|
|
130
|
+
> **Tip:** Use the `provider:model` format (e.g., `openai:gpt-5`) to quickly switch between models. See the [reference](https://reference.langchain.com/python/langchain/models/#langchain.chat_models.init_chat_model(model)) for more info.
|
|
126
131
|
|
|
127
132
|
```python
|
|
128
133
|
from langchain.chat_models import init_chat_model
|
|
129
134
|
from deepagents import create_deep_agent
|
|
130
135
|
|
|
131
|
-
model = init_chat_model("openai:gpt-
|
|
132
|
-
agent = create_deep_agent(
|
|
133
|
-
model=model,
|
|
134
|
-
)
|
|
136
|
+
model = init_chat_model(model="openai:gpt-5")
|
|
137
|
+
agent = create_deep_agent(model=model)
|
|
135
138
|
```
|
|
136
139
|
|
|
137
140
|
### `system_prompt`
|
|
141
|
+
|
|
138
142
|
Deep Agents come with a built-in system prompt. This is relatively detailed prompt that is heavily based on and inspired by [attempts](https://github.com/kn1026/cc/blob/main/claudecode.md) to [replicate](https://github.com/asgeirtj/system_prompts_leaks/blob/main/Anthropic/claude-code.md)
|
|
139
143
|
Claude Code's system prompt. It was made more general purpose than Claude Code's system prompt. The default prompt contains detailed instructions for how to use the built-in planning tool, file system tools, and sub agents.
|
|
140
144
|
|
|
@@ -153,7 +157,7 @@ agent = create_deep_agent(
|
|
|
153
157
|
|
|
154
158
|
### `tools`
|
|
155
159
|
|
|
156
|
-
|
|
160
|
+
In addition to custom tools you provide, `deepagents` include built-in tools for planning (`write_todos`), file management (`ls`, `read_file`, `write_file`, `edit_file`, `glob`, `grep`), and subagent spawning (`task`).
|
|
157
161
|
|
|
158
162
|
```python
|
|
159
163
|
import os
|
|
@@ -183,7 +187,8 @@ agent = create_deep_agent(
|
|
|
183
187
|
```
|
|
184
188
|
|
|
185
189
|
### `middleware`
|
|
186
|
-
|
|
190
|
+
|
|
191
|
+
`create_deep_agent` is implemented with middleware that can be customized. You can provide additional middleware to extend functionality, add tools, or implement custom hooks.
|
|
187
192
|
|
|
188
193
|
```python
|
|
189
194
|
from langchain_core.tools import tool
|
|
@@ -231,7 +236,7 @@ class CompiledSubAgent(TypedDict):
|
|
|
231
236
|
runnable: Runnable
|
|
232
237
|
```
|
|
233
238
|
|
|
234
|
-
|
|
239
|
+
**`SubAgent` fields:**
|
|
235
240
|
- **name**: This is the name of the subagent, and how the main agent will call the subagent
|
|
236
241
|
- **description**: This is the description of the subagent that is shown to the main agent
|
|
237
242
|
- **system_prompt**: This is the system prompt used for the subagent
|
|
@@ -243,9 +248,9 @@ class CompiledSubAgent(TypedDict):
|
|
|
243
248
|
**CompiledSubAgent fields:**
|
|
244
249
|
- **name**: This is the name of the subagent, and how the main agent will call the subagent
|
|
245
250
|
- **description**: This is the description of the subagent that is shown to the main agent
|
|
246
|
-
- **runnable**: A pre-built LangGraph graph/agent that will be used as the subagent
|
|
251
|
+
- **runnable**: A pre-built LangGraph graph/agent that will be used as the subagent. **Important:** The runnable's state schema must include a `messages` key. This is required for the subagent to communicate results back to the main agent.
|
|
247
252
|
|
|
248
|
-
#### Using SubAgent
|
|
253
|
+
#### Using `SubAgent`
|
|
249
254
|
|
|
250
255
|
```python
|
|
251
256
|
import os
|
|
@@ -284,9 +289,9 @@ agent = create_deep_agent(
|
|
|
284
289
|
)
|
|
285
290
|
```
|
|
286
291
|
|
|
287
|
-
#### Using
|
|
292
|
+
#### Using `CompiledSubAgent`
|
|
288
293
|
|
|
289
|
-
For
|
|
294
|
+
For complex workflows, use a pre-built LangGraph graph:
|
|
290
295
|
|
|
291
296
|
```python
|
|
292
297
|
# Create a custom agent graph
|
|
@@ -296,7 +301,7 @@ custom_graph = create_agent(
|
|
|
296
301
|
prompt="You are a specialized agent for data analysis..."
|
|
297
302
|
)
|
|
298
303
|
|
|
299
|
-
# Use it as a
|
|
304
|
+
# Use it as a compiled subagent
|
|
300
305
|
custom_subagent = CompiledSubAgent(
|
|
301
306
|
name="data-analyzer",
|
|
302
307
|
description="Specialized agent for complex data analysis tasks",
|
|
@@ -314,7 +319,10 @@ agent = create_deep_agent(
|
|
|
314
319
|
```
|
|
315
320
|
|
|
316
321
|
### `interrupt_on`
|
|
317
|
-
|
|
322
|
+
|
|
323
|
+
The harness can pause agent execution at specified tool calls to allow human approval or modification. This feature is opt-in via the `interrupt_on` parameter.
|
|
324
|
+
|
|
325
|
+
Pass `interrupt_on` to `create_deep_agent` with a mapping of tool names to interrupt configurations. Example: `interrupt_on={"edit_file": True}` pauses before every edit.
|
|
318
326
|
|
|
319
327
|
These tool configs are passed to our prebuilt [HITL middleware](https://docs.langchain.com/oss/python/langchain/middleware#human-in-the-loop) so that the agent pauses execution and waits for feedback from the user before executing configured tools.
|
|
320
328
|
|
|
@@ -342,6 +350,7 @@ agent = create_deep_agent(
|
|
|
342
350
|
## Deep Agents Middleware
|
|
343
351
|
|
|
344
352
|
Deep Agents are built with a modular middleware architecture. As a reminder, Deep Agents have access to:
|
|
353
|
+
|
|
345
354
|
- A planning tool
|
|
346
355
|
- A filesystem for storing context and long-term memories
|
|
347
356
|
- The ability to spawn subagents
|
|
@@ -350,11 +359,11 @@ Each of these features is implemented as separate middleware. When you create a
|
|
|
350
359
|
|
|
351
360
|
Middleware is a composable concept, and you can choose to add as many or as few middleware to an agent depending on your use case. That means that you can also use any of the aforementioned middleware independently!
|
|
352
361
|
|
|
353
|
-
### TodoListMiddleware
|
|
362
|
+
### `TodoListMiddleware`
|
|
354
363
|
|
|
355
|
-
Planning is integral to solving complex problems. If you
|
|
364
|
+
Planning is integral to solving complex problems. If you've used Claude Code recently, you'll notice how it writes out a to-do list before tackling complex, multi-part tasks. You'll also notice how it can adapt and update this to-do list on the fly as more information comes in.
|
|
356
365
|
|
|
357
|
-
|
|
366
|
+
`TodoListMiddleware` provides your agent with a tool specifically for updating this to-do list. Before, and while it executes a multi-part task, the agent is prompted to use the `write_todos` tool to keep track of what it's doing, and what still needs to be done.
|
|
358
367
|
|
|
359
368
|
```python
|
|
360
369
|
from langchain.agents import create_agent
|
|
@@ -373,14 +382,15 @@ agent = create_agent(
|
|
|
373
382
|
)
|
|
374
383
|
```
|
|
375
384
|
|
|
376
|
-
### FilesystemMiddleware
|
|
385
|
+
### `FilesystemMiddleware`
|
|
386
|
+
|
|
387
|
+
Context engineering is one of the main challenges in building effective agents. This can be particularly hard when using tools that can return variable length results (e.g., `web_search`, RAG), as long tool results can quickly fill up your context window.
|
|
388
|
+
`FilesystemMiddleware` provides four tools to your agent to interact with both short-term and long-term memory:
|
|
377
389
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
-
|
|
381
|
-
-
|
|
382
|
-
- **write_file**: Write a new file to your filesystem
|
|
383
|
-
- **edit_file**: Edit an existing file in your filesystem
|
|
390
|
+
- `ls`: List the files in your filesystem
|
|
391
|
+
- `read_file`: Read an entire file, or a certain number of lines from a file
|
|
392
|
+
- `write_file`: Write a new file to your filesystem
|
|
393
|
+
- `edit_file`: Edit an existing file in your filesystem
|
|
384
394
|
|
|
385
395
|
```python
|
|
386
396
|
from langchain.agents import create_agent
|
|
@@ -404,9 +414,9 @@ agent = create_agent(
|
|
|
404
414
|
)
|
|
405
415
|
```
|
|
406
416
|
|
|
407
|
-
### SubAgentMiddleware
|
|
417
|
+
### `SubAgentMiddleware`
|
|
408
418
|
|
|
409
|
-
Handing off tasks to subagents is a great way to isolate context, keeping the context window of the main (supervisor) agent clean while still going deep on a task.
|
|
419
|
+
Handing off tasks to subagents is a great way to isolate context, keeping the context window of the main (supervisor) agent clean while still going deep on a task. `SubAgentMiddleware` allows you to supply subagents through a `task` tool.
|
|
410
420
|
|
|
411
421
|
A subagent is defined with a name, description, system prompt, and tools. You can also provide a subagent with a custom model, or with additional middleware. This can be particularly useful when you want to give the subagent an additional state key to share with the main agent.
|
|
412
422
|
|
|
@@ -446,14 +456,16 @@ For more complex use cases, you can also provide your own pre-built LangGraph gr
|
|
|
446
456
|
|
|
447
457
|
```python
|
|
448
458
|
# Create a custom LangGraph graph
|
|
459
|
+
# Important: Your state must include a 'messages' key
|
|
449
460
|
def create_weather_graph():
|
|
450
461
|
workflow = StateGraph(...)
|
|
451
462
|
# Build your custom graph
|
|
463
|
+
# Make sure your state schema includes 'messages'
|
|
452
464
|
return workflow.compile()
|
|
453
465
|
|
|
454
466
|
weather_graph = create_weather_graph()
|
|
455
467
|
|
|
456
|
-
# Wrap it in a CompiledSubAgent
|
|
468
|
+
# Wrap it in a `CompiledSubAgent`
|
|
457
469
|
weather_subagent = CompiledSubAgent(
|
|
458
470
|
name="weather",
|
|
459
471
|
description="This subagent can get weather in cities.",
|
|
@@ -474,13 +486,12 @@ agent = create_agent(
|
|
|
474
486
|
|
|
475
487
|
## Sync vs Async
|
|
476
488
|
|
|
477
|
-
Prior versions of deepagents separated sync and async agent factories.
|
|
489
|
+
Prior versions of deepagents separated sync and async agent factories.
|
|
478
490
|
|
|
479
491
|
`async_create_deep_agent` has been folded in to `create_deep_agent`.
|
|
480
492
|
|
|
481
493
|
**You should use `create_deep_agent` as the factory for both sync and async agents**
|
|
482
494
|
|
|
483
|
-
|
|
484
495
|
## MCP
|
|
485
496
|
|
|
486
497
|
The `deepagents` library can be ran with MCP tools. This can be achieved by using the [Langchain MCP Adapter library](https://github.com/langchain-ai/langchain-mcp-adapters).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
deepagents/__init__.py,sha256=LHQm0v_7N9Gd4pmpRjhnlOCMIK2O0jQ4cEU8RiXEI8k,447
|
|
2
|
-
deepagents/graph.py,sha256=
|
|
2
|
+
deepagents/graph.py,sha256=oqcL-H14t-oYxc7RvMkNCge1twVjqogFcLCzH-4vSdc,9161
|
|
3
3
|
deepagents/backends/__init__.py,sha256=BOKu2cQ1OdMyO_l2rLqZQiXppYFmQbx7OIQb7WYwvZc,457
|
|
4
4
|
deepagents/backends/composite.py,sha256=WZ_dnn63BmrU19ZJ5-m728f99pSa0Uq_CnwZjwmxz1U,26198
|
|
5
5
|
deepagents/backends/filesystem.py,sha256=kGBFuW3ie0LLz4wXCPGJm3WAiYpimJTgEwodJSnXWCs,21477
|
|
@@ -7,14 +7,14 @@ deepagents/backends/protocol.py,sha256=HUmIrwYGduPfDcs_wtOzVU2QPA9kICZuGO-sUwxzz
|
|
|
7
7
|
deepagents/backends/sandbox.py,sha256=8Bi8itqjW2PpXORlIfT8thMN1aBXExgHz8cm8xwVaxI,10864
|
|
8
8
|
deepagents/backends/state.py,sha256=Qq4uRjKg6POEqLl4tNnWnXzbmLBpu3bZdMkcUROIgHw,7899
|
|
9
9
|
deepagents/backends/store.py,sha256=0mmeTsim4J8bjcf62dljwNrDv4PavT2KHdGbaBzVzRE,15197
|
|
10
|
-
deepagents/backends/utils.py,sha256=
|
|
10
|
+
deepagents/backends/utils.py,sha256=wXMzfrUxp-ZAKlbl3QFZXlSSPRmIXQIUEehqsy2Agy8,13933
|
|
11
11
|
deepagents/middleware/__init__.py,sha256=2smUxjwghA3Eml_wp0kd4dAY-rwLyW-XQPBE3dAoo50,467
|
|
12
|
-
deepagents/middleware/filesystem.py,sha256=
|
|
12
|
+
deepagents/middleware/filesystem.py,sha256=Qx9NuRZPNuK1NVYomPCRauDY0ZqZ5j_wro9MRYyvcx0,47563
|
|
13
13
|
deepagents/middleware/memory.py,sha256=E1UAtBAyIxkyNHuG2-j_X_fClMbbSwobdKa3e_P0FDk,15883
|
|
14
14
|
deepagents/middleware/patch_tool_calls.py,sha256=PdNhxPaQqwnFkhEAZEE2kEzadTNAOO3_iJRA30WqpGE,1981
|
|
15
15
|
deepagents/middleware/skills.py,sha256=EABvIq4ES_NHGFL9USUnlH1WwiZgnAacoOLz2kkkVkw,24043
|
|
16
|
-
deepagents/middleware/subagents.py,sha256=
|
|
17
|
-
deepagents-0.3.
|
|
18
|
-
deepagents-0.3.
|
|
19
|
-
deepagents-0.3.
|
|
20
|
-
deepagents-0.3.
|
|
16
|
+
deepagents/middleware/subagents.py,sha256=c_JxFb2Z3yBWEInqNEciC9Rlu4uGo1tpuN9tLXivWeY,26196
|
|
17
|
+
deepagents-0.3.6.dist-info/METADATA,sha256=KpjDBOFZXmVrZYfuec3UiFsm193LLjfkigSlFhULJE4,19743
|
|
18
|
+
deepagents-0.3.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
19
|
+
deepagents-0.3.6.dist-info/top_level.txt,sha256=drAzchOzPNePwpb3_pbPuvLuayXkN7SNqeIKMBWJoAo,11
|
|
20
|
+
deepagents-0.3.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|