deepagents 0.3.2__py3-none-any.whl → 0.3.4__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/graph.py +34 -34
- deepagents/middleware/memory.py +81 -42
- {deepagents-0.3.2.dist-info → deepagents-0.3.4.dist-info}/METADATA +5 -5
- {deepagents-0.3.2.dist-info → deepagents-0.3.4.dist-info}/RECORD +6 -6
- {deepagents-0.3.2.dist-info → deepagents-0.3.4.dist-info}/WHEEL +0 -0
- {deepagents-0.3.2.dist-info → deepagents-0.3.4.dist-info}/top_level.txt +0 -0
deepagents/graph.py
CHANGED
|
@@ -33,7 +33,7 @@ def get_default_model() -> ChatAnthropic:
|
|
|
33
33
|
"""Get the default model for deep agents.
|
|
34
34
|
|
|
35
35
|
Returns:
|
|
36
|
-
ChatAnthropic instance configured with Claude Sonnet 4.
|
|
36
|
+
`ChatAnthropic` instance configured with Claude Sonnet 4.5.
|
|
37
37
|
"""
|
|
38
38
|
return ChatAnthropic(
|
|
39
39
|
model_name="claude-sonnet-4-5-20250929",
|
|
@@ -62,51 +62,51 @@ def create_deep_agent(
|
|
|
62
62
|
) -> CompiledStateGraph:
|
|
63
63
|
"""Create a deep agent.
|
|
64
64
|
|
|
65
|
-
This agent will by default have access to a tool to write todos (write_todos),
|
|
66
|
-
seven file and execution tools: ls
|
|
65
|
+
This agent will by default have access to a tool to write todos (`write_todos`),
|
|
66
|
+
seven file and execution tools: `ls`, `read_file`, `write_file`, `edit_file`, `glob`, `grep`, `execute`,
|
|
67
67
|
and a tool to call subagents.
|
|
68
68
|
|
|
69
|
-
The execute tool allows running shell commands if the backend implements SandboxBackendProtocol
|
|
70
|
-
For non-sandbox backends, the execute tool will return an error message.
|
|
69
|
+
The `execute` tool allows running shell commands if the backend implements `SandboxBackendProtocol`.
|
|
70
|
+
For non-sandbox backends, the `execute` tool will return an error message.
|
|
71
71
|
|
|
72
72
|
Args:
|
|
73
|
-
model: The model to use. Defaults to
|
|
73
|
+
model: The model to use. Defaults to `claude-sonnet-4-5-20250929`.
|
|
74
74
|
tools: The tools the agent should have access to.
|
|
75
75
|
system_prompt: The additional instructions the agent should have. Will go in
|
|
76
76
|
the system prompt.
|
|
77
77
|
middleware: Additional middleware to apply after standard middleware.
|
|
78
|
-
subagents: The subagents to use.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
skills: Optional list of skill source paths (e.g., ["/skills/user/", "/skills/project/"]).
|
|
78
|
+
subagents: The subagents to use.
|
|
79
|
+
|
|
80
|
+
Each subagent should be a `dict` with the following keys:
|
|
81
|
+
|
|
82
|
+
- `name`
|
|
83
|
+
- `description` (used by the main agent to decide whether to call the sub agent)
|
|
84
|
+
- `prompt` (used as the system prompt in the subagent)
|
|
85
|
+
- (optional) `tools`
|
|
86
|
+
- (optional) `model` (either a `LanguageModelLike` instance or `dict` settings)
|
|
87
|
+
- (optional) `middleware` (list of `AgentMiddleware`)
|
|
88
|
+
skills: Optional list of skill source paths (e.g., `["/skills/user/", "/skills/project/"]`).
|
|
89
|
+
|
|
89
90
|
Paths must be specified using POSIX conventions (forward slashes) and are relative
|
|
90
|
-
to the backend's root. When using StateBackend (default), provide skill files via
|
|
91
|
-
`invoke(files={...})`. With FilesystemBackend
|
|
92
|
-
to the backend's root_dir
|
|
91
|
+
to the backend's root. When using `StateBackend` (default), provide skill files via
|
|
92
|
+
`invoke(files={...})`. With `FilesystemBackend`, skills are loaded from disk relative
|
|
93
|
+
to the backend's `root_dir`. Later sources override earlier ones for skills with the
|
|
93
94
|
same name (last one wins).
|
|
94
|
-
memory: Optional list of memory file paths (AGENTS.md files) to load
|
|
95
|
-
(e.g., ["/memory/AGENTS.md"]). Display names
|
|
96
|
-
|
|
97
|
-
added into the system prompt.
|
|
95
|
+
memory: Optional list of memory file paths (`AGENTS.md` files) to load
|
|
96
|
+
(e.g., `["/memory/AGENTS.md"]`). Display names are automatically derived from paths.
|
|
97
|
+
Memory is loaded at agent startup and added into the system prompt.
|
|
98
98
|
response_format: A structured output response format to use for the agent.
|
|
99
99
|
context_schema: The schema of the deep agent.
|
|
100
|
-
checkpointer: Optional
|
|
101
|
-
store: Optional store for persistent storage (required if backend uses StoreBackend).
|
|
102
|
-
backend: Optional backend for file storage and execution.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
debug: Whether to enable debug mode. Passed through to create_agent
|
|
108
|
-
name: The name of the agent. Passed through to create_agent
|
|
109
|
-
cache: The cache to use for the agent. Passed through to create_agent
|
|
100
|
+
checkpointer: Optional `Checkpointer` for persisting agent state between runs.
|
|
101
|
+
store: Optional store for persistent storage (required if backend uses `StoreBackend`).
|
|
102
|
+
backend: Optional backend for file storage and execution.
|
|
103
|
+
|
|
104
|
+
Pass either a `Backend` instance or a callable factory like `lambda rt: StateBackend(rt)`.
|
|
105
|
+
For execution support, use a backend that implements `SandboxBackendProtocol`.
|
|
106
|
+
interrupt_on: Mapping of tool names to interrupt configs.
|
|
107
|
+
debug: Whether to enable debug mode. Passed through to `create_agent`.
|
|
108
|
+
name: The name of the agent. Passed through to `create_agent`.
|
|
109
|
+
cache: The cache to use for the agent. Passed through to `create_agent`.
|
|
110
110
|
|
|
111
111
|
Returns:
|
|
112
112
|
A configured deep agent.
|
deepagents/middleware/memory.py
CHANGED
|
@@ -89,21 +89,65 @@ class MemoryStateUpdate(TypedDict):
|
|
|
89
89
|
memory_contents: dict[str, str]
|
|
90
90
|
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
-
|
|
92
|
+
MEMORY_SYSTEM_PROMPT = """<agent_memory>
|
|
93
|
+
{agent_memory}
|
|
94
|
+
</agent_memory>
|
|
95
|
+
|
|
96
|
+
<memory_guidelines>
|
|
97
|
+
The above <agent_memory> was loaded in from files in your filesystem. As you learn from your interactions with the user, you can save new knowledge by calling the `edit_file` tool.
|
|
98
|
+
|
|
99
|
+
**Learning from feedback:**
|
|
100
|
+
- One of your MAIN PRIORITIES is to learn from your interactions with the user. These learnings can be implicit or explicit. This means that in the future, you will remember this important information.
|
|
101
|
+
- When you need to remember something, updating memory must be your FIRST, IMMEDIATE action - before responding to the user, before calling other tools, before doing anything else. Just update memory immediately.
|
|
102
|
+
- When user says something is better/worse, capture WHY and encode it as a pattern.
|
|
103
|
+
- Each correction is a chance to improve permanently - don't just fix the immediate issue, update your instructions.
|
|
104
|
+
- A great opportunity to update your memories is when the user interrupts a tool call and provides feedback. You should update your memories immediately before revising the tool call.
|
|
105
|
+
- Look for the underlying principle behind corrections, not just the specific mistake.
|
|
106
|
+
- The user might not explicitly ask you to remember something, but if they provide information that is useful for future use, you should update your memories immediately.
|
|
107
|
+
|
|
108
|
+
**Asking for information:**
|
|
109
|
+
- If you lack context to perform an action (e.g. send a Slack DM, requires a user ID/email) you should explicitly ask the user for this information.
|
|
110
|
+
- It is preferred for you to ask for information, don't assume anything that you do not know!
|
|
111
|
+
- When the user provides information that is useful for future use, you should update your memories immediately.
|
|
112
|
+
|
|
113
|
+
**When to update memories:**
|
|
114
|
+
- When the user explicitly asks you to remember something (e.g., "remember my email", "save this preference")
|
|
115
|
+
- When the user describes your role or how you should behave (e.g., "you are a web researcher", "always do X")
|
|
116
|
+
- When the user gives feedback on your work - capture what was wrong and how to improve
|
|
117
|
+
- When the user provides information required for tool use (e.g., slack channel ID, email addresses)
|
|
118
|
+
- When the user provides context useful for future tasks, such as how to use tools, or which actions to take in a particular situation
|
|
119
|
+
- When you discover new patterns or preferences (coding styles, conventions, workflows)
|
|
120
|
+
|
|
121
|
+
**When to NOT update memories:**
|
|
122
|
+
- When the information is temporary or transient (e.g., "I'm running late", "I'm on my phone right now")
|
|
123
|
+
- When the information is a one-time task request (e.g., "Find me a recipe", "What's 25 * 4?")
|
|
124
|
+
- When the information is a simple question that doesn't reveal lasting preferences (e.g., "What day is it?", "Can you explain X?")
|
|
125
|
+
- When the information is an acknowledgment or small talk (e.g., "Sounds good!", "Hello", "Thanks for that")
|
|
126
|
+
- When the information is stale or irrelevant in future conversations
|
|
127
|
+
- Never store API keys, access tokens, passwords, or any other credentials in any file, memory, or system prompt.
|
|
128
|
+
- If the user asks where to put API keys or provides an API key, do NOT echo or save it.
|
|
129
|
+
|
|
130
|
+
**Examples:**
|
|
131
|
+
Example 1 (remembering user information):
|
|
132
|
+
User: Can you connect to my google account?
|
|
133
|
+
Agent: Sure, I'll connect to your google account, what's your google account email?
|
|
134
|
+
User: john@example.com
|
|
135
|
+
Agent: Let me save this to my memory.
|
|
136
|
+
Tool Call: edit_file(...) -> remembers that the user's google account email is john@example.com
|
|
137
|
+
|
|
138
|
+
Example 2 (remembering implicit user preferences):
|
|
139
|
+
User: Can you write me an example for creating a deep agent in LangChain?
|
|
140
|
+
Agent: Sure, I'll write you an example for creating a deep agent in LangChain <example code in Python>
|
|
141
|
+
User: Can you do this in JavaScript
|
|
142
|
+
Agent: Let me save this to my memory.
|
|
143
|
+
Tool Call: edit_file(...) -> remembers that the user prefers to get LangChaincode examples in JavaScript
|
|
144
|
+
Agent: Sure, here is the JavaScript example<example code in JavaScript>
|
|
145
|
+
|
|
146
|
+
Example 3 (do not remember transient information):
|
|
147
|
+
User: I'm going to play basketball tonight so I will be offline for a few hours.
|
|
148
|
+
Agent: Okay I'll add a black to your calendar.
|
|
149
|
+
Tool Call: create_calendar_event(...) -> just calls a tool, does not commit anything to memory, as it is transient information
|
|
150
|
+
</memory_guidelines>
|
|
107
151
|
"""
|
|
108
152
|
|
|
109
153
|
|
|
@@ -137,7 +181,6 @@ class MemoryMiddleware(AgentMiddleware):
|
|
|
137
181
|
"""
|
|
138
182
|
self._backend = backend
|
|
139
183
|
self.sources = sources
|
|
140
|
-
self.system_prompt_template = MEMORY_SYSTEM_PROMPT
|
|
141
184
|
|
|
142
185
|
def _get_backend(self, state: MemoryState, runtime: Runtime, config: RunnableConfig) -> BackendProtocol:
|
|
143
186
|
"""Resolve backend from instance or factory.
|
|
@@ -163,37 +206,28 @@ class MemoryMiddleware(AgentMiddleware):
|
|
|
163
206
|
return self._backend(tool_runtime)
|
|
164
207
|
return self._backend
|
|
165
208
|
|
|
166
|
-
def
|
|
167
|
-
"""Format memory
|
|
168
|
-
if not self.sources:
|
|
169
|
-
return "**Memory Sources:** None configured"
|
|
170
|
-
|
|
171
|
-
lines = ["**Memory Sources:**"]
|
|
172
|
-
for path in self.sources:
|
|
173
|
-
lines.append(f"- `{path}`")
|
|
174
|
-
return "\n".join(lines)
|
|
175
|
-
|
|
176
|
-
def _format_memory_contents(self, contents: dict[str, str]) -> str:
|
|
177
|
-
"""Format loaded memory contents for injection into prompt.
|
|
209
|
+
def _format_agent_memory(self, contents: dict[str, str]) -> str:
|
|
210
|
+
"""Format memory with locations and contents paired together.
|
|
178
211
|
|
|
179
212
|
Args:
|
|
180
213
|
contents: Dict mapping source paths to content.
|
|
181
214
|
|
|
182
215
|
Returns:
|
|
183
|
-
Formatted string with
|
|
216
|
+
Formatted string with location+content pairs wrapped in <agent_memory> tags.
|
|
184
217
|
"""
|
|
185
218
|
if not contents:
|
|
186
|
-
return "(No memory loaded)"
|
|
219
|
+
return MEMORY_SYSTEM_PROMPT.format(agent_memory="(No memory loaded)")
|
|
187
220
|
|
|
188
221
|
sections = []
|
|
189
222
|
for path in self.sources:
|
|
190
223
|
if contents.get(path):
|
|
191
|
-
sections.append(contents[path])
|
|
224
|
+
sections.append(f"{path}\n{contents[path]}")
|
|
192
225
|
|
|
193
226
|
if not sections:
|
|
194
|
-
return "(No memory loaded)"
|
|
227
|
+
return MEMORY_SYSTEM_PROMPT.format(agent_memory="(No memory loaded)")
|
|
195
228
|
|
|
196
|
-
|
|
229
|
+
memory_body = "\n\n".join(sections)
|
|
230
|
+
return MEMORY_SYSTEM_PROMPT.format(agent_memory=memory_body)
|
|
197
231
|
|
|
198
232
|
async def _load_memory_from_backend(
|
|
199
233
|
self,
|
|
@@ -216,6 +250,11 @@ class MemoryMiddleware(AgentMiddleware):
|
|
|
216
250
|
response = results[0]
|
|
217
251
|
|
|
218
252
|
if response.error is not None:
|
|
253
|
+
# For now, memory files are treated as optional. file_not_found is expected
|
|
254
|
+
# and we skip silently to allow graceful degradation.
|
|
255
|
+
if response.error == "file_not_found":
|
|
256
|
+
return None
|
|
257
|
+
# Other errors should be raised
|
|
219
258
|
raise ValueError(f"Failed to download {path}: {response.error}")
|
|
220
259
|
|
|
221
260
|
if response.content is not None:
|
|
@@ -244,6 +283,11 @@ class MemoryMiddleware(AgentMiddleware):
|
|
|
244
283
|
response = results[0]
|
|
245
284
|
|
|
246
285
|
if response.error is not None:
|
|
286
|
+
# For now, memory files are treated as optional. file_not_found is expected
|
|
287
|
+
# and we skip silently to allow graceful degradation.
|
|
288
|
+
if response.error == "file_not_found":
|
|
289
|
+
return None
|
|
290
|
+
# Other errors should be raised
|
|
247
291
|
raise ValueError(f"Failed to download {path}: {response.error}")
|
|
248
292
|
|
|
249
293
|
if response.content is not None:
|
|
@@ -298,6 +342,7 @@ class MemoryMiddleware(AgentMiddleware):
|
|
|
298
342
|
if "memory_contents" in state:
|
|
299
343
|
return None
|
|
300
344
|
|
|
345
|
+
print("HI")
|
|
301
346
|
backend = self._get_backend(state, runtime, config)
|
|
302
347
|
contents: dict[str, str] = {}
|
|
303
348
|
|
|
@@ -319,18 +364,12 @@ class MemoryMiddleware(AgentMiddleware):
|
|
|
319
364
|
Modified request with memory injected into system prompt.
|
|
320
365
|
"""
|
|
321
366
|
contents = request.state.get("memory_contents", {})
|
|
322
|
-
|
|
323
|
-
memory_contents = self._format_memory_contents(contents)
|
|
324
|
-
|
|
325
|
-
memory_section = self.system_prompt_template.format(
|
|
326
|
-
memory_locations=memory_locations,
|
|
327
|
-
memory_contents=memory_contents,
|
|
328
|
-
)
|
|
367
|
+
agent_memory = self._format_agent_memory(contents)
|
|
329
368
|
|
|
330
369
|
if request.system_prompt:
|
|
331
|
-
system_prompt =
|
|
370
|
+
system_prompt = agent_memory + "\n\n" + request.system_prompt
|
|
332
371
|
else:
|
|
333
|
-
system_prompt =
|
|
372
|
+
system_prompt = agent_memory
|
|
334
373
|
|
|
335
374
|
return request.override(system_message=SystemMessage(system_prompt))
|
|
336
375
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
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
|
|
@@ -11,10 +11,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
|
-
Requires-Dist: langchain-
|
|
15
|
-
Requires-Dist: langchain
|
|
16
|
-
Requires-Dist: langchain<2.0.0,>=1.1
|
|
17
|
-
Requires-Dist: langchain-
|
|
14
|
+
Requires-Dist: langchain-core<2.0.0,>=1.2.6
|
|
15
|
+
Requires-Dist: langchain<2.0.0,>=1.2.3
|
|
16
|
+
Requires-Dist: langchain-anthropic<2.0.0,>=1.3.1
|
|
17
|
+
Requires-Dist: langchain-google-genai<5.0.0,>=4.1.3
|
|
18
18
|
Requires-Dist: wcmatch
|
|
19
19
|
|
|
20
20
|
# 🧠🤖Deep Agents
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
deepagents/__init__.py,sha256=LHQm0v_7N9Gd4pmpRjhnlOCMIK2O0jQ4cEU8RiXEI8k,447
|
|
2
|
-
deepagents/graph.py,sha256=
|
|
2
|
+
deepagents/graph.py,sha256=TmMBtFZP9uT5KrzT6XRFIUCAD2_BCvfGLbd6zCMaWM8,8622
|
|
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
|
|
@@ -10,11 +10,11 @@ deepagents/backends/store.py,sha256=0mmeTsim4J8bjcf62dljwNrDv4PavT2KHdGbaBzVzRE,
|
|
|
10
10
|
deepagents/backends/utils.py,sha256=Iyk2jW-gfoLvMnz-W_2FRCoJW_j3r1zoumU9iww-jd0,13973
|
|
11
11
|
deepagents/middleware/__init__.py,sha256=2smUxjwghA3Eml_wp0kd4dAY-rwLyW-XQPBE3dAoo50,467
|
|
12
12
|
deepagents/middleware/filesystem.py,sha256=8_W5XNDYMN37BQjbqMyUAVWYv2KmRP87xwwomQ37K1w,44568
|
|
13
|
-
deepagents/middleware/memory.py,sha256=
|
|
13
|
+
deepagents/middleware/memory.py,sha256=6k9nq2-fxQ9tKjWg9-r3ZSfui-24yZgzQn3Zw7FNs0Y,15903
|
|
14
14
|
deepagents/middleware/patch_tool_calls.py,sha256=PdNhxPaQqwnFkhEAZEE2kEzadTNAOO3_iJRA30WqpGE,1981
|
|
15
15
|
deepagents/middleware/skills.py,sha256=EABvIq4ES_NHGFL9USUnlH1WwiZgnAacoOLz2kkkVkw,24043
|
|
16
16
|
deepagents/middleware/subagents.py,sha256=Gpky0NsQehZ-iyXIetczmu4CkBuxAnDQv6pZXIDHp8M,24427
|
|
17
|
-
deepagents-0.3.
|
|
18
|
-
deepagents-0.3.
|
|
19
|
-
deepagents-0.3.
|
|
20
|
-
deepagents-0.3.
|
|
17
|
+
deepagents-0.3.4.dist-info/METADATA,sha256=eo-ZRb18V_J2Pa3r8XsI0oyVXOFNydvAXFUg1Cfw5Tc,18823
|
|
18
|
+
deepagents-0.3.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
19
|
+
deepagents-0.3.4.dist-info/top_level.txt,sha256=drAzchOzPNePwpb3_pbPuvLuayXkN7SNqeIKMBWJoAo,11
|
|
20
|
+
deepagents-0.3.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|