deepagents 0.0.9__py3-none-any.whl → 0.0.11rc1__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/middleware.py +2 -2
- deepagents/prompts.py +11 -4
- deepagents/tools.py +59 -6
- {deepagents-0.0.9.dist-info → deepagents-0.0.11rc1.dist-info}/METADATA +5 -4
- {deepagents-0.0.9.dist-info → deepagents-0.0.11rc1.dist-info}/RECORD +8 -8
- {deepagents-0.0.9.dist-info → deepagents-0.0.11rc1.dist-info}/WHEEL +0 -0
- {deepagents-0.0.9.dist-info → deepagents-0.0.11rc1.dist-info}/licenses/LICENSE +0 -0
- {deepagents-0.0.9.dist-info → deepagents-0.0.11rc1.dist-info}/top_level.txt +0 -0
deepagents/middleware.py
CHANGED
|
@@ -7,8 +7,8 @@ from langchain_core.tools import BaseTool, tool, InjectedToolCallId
|
|
|
7
7
|
from langchain_core.messages import ToolMessage
|
|
8
8
|
from langchain.chat_models import init_chat_model
|
|
9
9
|
from langgraph.types import Command
|
|
10
|
-
from langchain.
|
|
11
|
-
from typing import Annotated
|
|
10
|
+
from langchain.tools.tool_node import InjectedState
|
|
11
|
+
from typing import Annotated
|
|
12
12
|
from deepagents.state import PlanningState, FilesystemState
|
|
13
13
|
from deepagents.tools import write_todos, ls, read_file, write_file, edit_file
|
|
14
14
|
from deepagents.prompts import WRITE_TODOS_SYSTEM_PROMPT, TASK_SYSTEM_PROMPT, FILESYSTEM_SYSTEM_PROMPT, TASK_TOOL_DESCRIPTION, BASE_AGENT_PROMPT
|
deepagents/prompts.py
CHANGED
|
@@ -406,10 +406,17 @@ When NOT to use the task tool:
|
|
|
406
406
|
FILESYSTEM_SYSTEM_PROMPT = """## Filesystem Tools `ls`, `read_file`, `write_file`, `edit_file`
|
|
407
407
|
|
|
408
408
|
You have access to a local, private filesystem which you can interact with using these tools.
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
409
|
+
|
|
410
|
+
You also have access to a longterm filesystem in which you can store files that you want to keep around for longer than the current conversation.
|
|
411
|
+
In order to interact with the longterm filesystem, you can use those same tools, but filenames must be prefixed with the memories/ path.
|
|
412
|
+
|
|
413
|
+
- ls: list all files in the filesystem (local and longterm)
|
|
414
|
+
- read_file: read a file from the filesystem (local and longterm)
|
|
415
|
+
- write_file: write to a file in the filesystem (local and longterm)
|
|
416
|
+
- edit_file: edit a file in the filesystem (local and longterm)
|
|
417
|
+
|
|
418
|
+
Remember, to interact with the longterm filesystem, you must prefix the filename with the memories/ path.
|
|
419
|
+
"""
|
|
413
420
|
|
|
414
421
|
BASE_AGENT_PROMPT = """
|
|
415
422
|
In order to complete the objective that the user asks of you, you have access to a number of standard tools.
|
deepagents/tools.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
from re import L
|
|
1
2
|
from langchain_core.tools import tool, InjectedToolCallId
|
|
2
3
|
from langchain_core.messages import ToolMessage
|
|
3
4
|
from langgraph.types import Command
|
|
4
|
-
from langchain.
|
|
5
|
+
from langchain.tools.tool_node import InjectedState
|
|
5
6
|
from typing import Annotated, Union
|
|
6
7
|
from deepagents.state import Todo, FilesystemState
|
|
7
8
|
from deepagents.prompts import (
|
|
@@ -11,7 +12,17 @@ from deepagents.prompts import (
|
|
|
11
12
|
WRITE_FILE_TOOL_DESCRIPTION,
|
|
12
13
|
EDIT_FILE_TOOL_DESCRIPTION,
|
|
13
14
|
)
|
|
15
|
+
from ai_filesystem import FilesystemClient
|
|
16
|
+
import os
|
|
14
17
|
|
|
18
|
+
def has_memories_prefix(file_path: str) -> bool:
|
|
19
|
+
return file_path.startswith("memories/")
|
|
20
|
+
|
|
21
|
+
def append_memories_prefix(file_path: str) -> str:
|
|
22
|
+
return f"memories/{file_path}"
|
|
23
|
+
|
|
24
|
+
def strip_memories_prefix(file_path: str) -> str:
|
|
25
|
+
return file_path.replace("memories/", "")
|
|
15
26
|
|
|
16
27
|
@tool(description=WRITE_TODOS_TOOL_DESCRIPTION)
|
|
17
28
|
def write_todos(
|
|
@@ -30,7 +41,17 @@ def write_todos(
|
|
|
30
41
|
@tool(description=LIST_FILES_TOOL_DESCRIPTION)
|
|
31
42
|
def ls(state: Annotated[FilesystemState, InjectedState]) -> list[str]:
|
|
32
43
|
"""List all files"""
|
|
33
|
-
|
|
44
|
+
files = []
|
|
45
|
+
files.extend(list(state.get("files", {}).keys()))
|
|
46
|
+
# Special handling for longterm filesystem
|
|
47
|
+
if os.getenv("LONGTERM_FILESYSTEM_NAME") and os.getenv("AGENT_FS_API_KEY"):
|
|
48
|
+
filesystem_client = FilesystemClient(
|
|
49
|
+
filesystem=os.getenv("LONGTERM_FILESYSTEM_NAME")
|
|
50
|
+
)
|
|
51
|
+
file_data_list = filesystem_client._list_files()
|
|
52
|
+
memories_files = [f"memories/{f.path}" for f in file_data_list]
|
|
53
|
+
files.extend(memories_files)
|
|
54
|
+
return files
|
|
34
55
|
|
|
35
56
|
|
|
36
57
|
@tool(description=READ_FILE_TOOL_DESCRIPTION)
|
|
@@ -40,6 +61,15 @@ def read_file(
|
|
|
40
61
|
offset: int = 0,
|
|
41
62
|
limit: int = 2000,
|
|
42
63
|
) -> str:
|
|
64
|
+
# Special handling for longterm filesystem
|
|
65
|
+
if os.getenv("LONGTERM_FILESYSTEM_NAME") and os.getenv("AGENT_FS_API_KEY") and has_memories_prefix(file_path):
|
|
66
|
+
filesystem_client = FilesystemClient(
|
|
67
|
+
filesystem=os.getenv("LONGTERM_FILESYSTEM_NAME")
|
|
68
|
+
)
|
|
69
|
+
file_path = strip_memories_prefix(file_path)
|
|
70
|
+
content = filesystem_client.read_file(file_path)
|
|
71
|
+
return content
|
|
72
|
+
|
|
43
73
|
mock_filesystem = state.get("files", {})
|
|
44
74
|
if file_path not in mock_filesystem:
|
|
45
75
|
return f"Error: File '{file_path}' not found"
|
|
@@ -85,14 +115,24 @@ def write_file(
|
|
|
85
115
|
state: Annotated[FilesystemState, InjectedState],
|
|
86
116
|
tool_call_id: Annotated[str, InjectedToolCallId],
|
|
87
117
|
) -> Command:
|
|
118
|
+
# Special handling for longterm filesystem
|
|
119
|
+
if os.getenv("LONGTERM_FILESYSTEM_NAME") and os.getenv("AGENT_FS_API_KEY") and has_memories_prefix(file_path):
|
|
120
|
+
filesystem_client = FilesystemClient(
|
|
121
|
+
filesystem=os.getenv("LONGTERM_FILESYSTEM_NAME")
|
|
122
|
+
)
|
|
123
|
+
short_file_path = strip_memories_prefix(file_path)
|
|
124
|
+
filesystem_client.create_file(short_file_path, content)
|
|
125
|
+
return Command(
|
|
126
|
+
update={
|
|
127
|
+
"messages": [ToolMessage(f"Updated longterm memories file {file_path}", tool_call_id=tool_call_id)]
|
|
128
|
+
}
|
|
129
|
+
)
|
|
130
|
+
|
|
88
131
|
files = state.get("files", {})
|
|
89
|
-
files[file_path] = content
|
|
90
132
|
return Command(
|
|
91
133
|
update={
|
|
92
134
|
"files": files,
|
|
93
|
-
"messages": [
|
|
94
|
-
ToolMessage(f"Updated file {file_path}", tool_call_id=tool_call_id)
|
|
95
|
-
],
|
|
135
|
+
"messages": [ToolMessage(f"Updated file {file_path}", tool_call_id=tool_call_id)]
|
|
96
136
|
}
|
|
97
137
|
)
|
|
98
138
|
|
|
@@ -107,6 +147,19 @@ def edit_file(
|
|
|
107
147
|
replace_all: bool = False,
|
|
108
148
|
) -> Union[Command, str]:
|
|
109
149
|
"""Write to a file."""
|
|
150
|
+
# Special handling for longterm filesystem
|
|
151
|
+
if os.getenv("LONGTERM_FILESYSTEM_NAME") and os.getenv("AGENT_FS_API_KEY") and has_memories_prefix(file_path):
|
|
152
|
+
filesystem_client = FilesystemClient(
|
|
153
|
+
filesystem=os.getenv("LONGTERM_FILESYSTEM_NAME")
|
|
154
|
+
)
|
|
155
|
+
short_file_path = strip_memories_prefix(file_path)
|
|
156
|
+
filesystem_client.edit_file(short_file_path, old_string, new_string, replace_all)
|
|
157
|
+
return Command(
|
|
158
|
+
update={
|
|
159
|
+
"messages": [ToolMessage(f"Successfully edited longterm memories file {file_path}", tool_call_id=tool_call_id)]
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
|
|
110
163
|
mock_filesystem = state.get("files", {})
|
|
111
164
|
# Check if file exists in mock filesystem
|
|
112
165
|
if file_path not in mock_filesystem:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.11rc1
|
|
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
|
Requires-Python: <4.0,>=3.11
|
|
@@ -8,8 +8,9 @@ Description-Content-Type: text/markdown
|
|
|
8
8
|
License-File: LICENSE
|
|
9
9
|
Requires-Dist: langgraph>=1.0.0a3
|
|
10
10
|
Requires-Dist: langchain-anthropic>=0.1.23
|
|
11
|
-
Requires-Dist: langchain>=1.0.
|
|
11
|
+
Requires-Dist: langchain>=1.0.0a10
|
|
12
12
|
Requires-Dist: langgraph-prebuilt>=0.7.0a2
|
|
13
|
+
Requires-Dist: ai-filesystem>=0.1.4
|
|
13
14
|
Provides-Extra: dev
|
|
14
15
|
Requires-Dist: pytest; extra == "dev"
|
|
15
16
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
@@ -163,10 +164,10 @@ agent = create_deep_agent(
|
|
|
163
164
|
For more complex use cases, you can provide your own pre-built LangGraph graph as a subagent:
|
|
164
165
|
|
|
165
166
|
```python
|
|
166
|
-
from
|
|
167
|
+
from langchain.agents import create_agent
|
|
167
168
|
|
|
168
169
|
# Create a custom agent graph
|
|
169
|
-
custom_graph =
|
|
170
|
+
custom_graph = create_agent(
|
|
170
171
|
model=your_model,
|
|
171
172
|
tools=specialized_tools,
|
|
172
173
|
prompt="You are a specialized agent for data analysis..."
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
deepagents/__init__.py,sha256=fA_91ByxPb3e8aPfci43zOXrWz8ylh_CFQALo7EUKi8,312
|
|
2
2
|
deepagents/graph.py,sha256=sLN0gWJma9dGgJI_RHDK-I1cEZMCo8nfxuF4a8vN7Po,6288
|
|
3
|
-
deepagents/middleware.py,sha256=
|
|
3
|
+
deepagents/middleware.py,sha256=P2y1crsedTH1uZlKS3fpc7pd4jwz8dR8jnw7repUjLk,7254
|
|
4
4
|
deepagents/model.py,sha256=VyRIkdeXJH8HqLrudTKucHpBTtrwMFTQGRlXBj0kUyo,155
|
|
5
|
-
deepagents/prompts.py,sha256=
|
|
5
|
+
deepagents/prompts.py,sha256=hiyiUriv-B3IQ0lwRqiJsvtgvwSS4wdeMNdXojHUisc,25603
|
|
6
6
|
deepagents/state.py,sha256=8so3MgL-zRPYP8Ci_OuVg4wHrs5uAXCErKF1AjjCSt8,726
|
|
7
|
-
deepagents/tools.py,sha256=
|
|
7
|
+
deepagents/tools.py,sha256=kTS-O8jWJsUnX0tBl19Iyg8fSR2jhD8c7jDz_xNrw0I,7138
|
|
8
8
|
deepagents/types.py,sha256=5KBSUPlWOnv9It3SnJCMHrOtp9Y4_NQGtGCp69JsEjE,694
|
|
9
|
-
deepagents-0.0.
|
|
9
|
+
deepagents-0.0.11rc1.dist-info/licenses/LICENSE,sha256=c__BaxUCK69leo2yEKynf8lWndu8iwYwge1CbyqAe-E,1071
|
|
10
10
|
tests/test_deepagents.py,sha256=SwtOiJF4c1O3r_Q3AiM7XZu6tVq4uMIcZlnsfRjx8Ig,7648
|
|
11
11
|
tests/test_hitl.py,sha256=B16ZFiyaVSOcDLz7mh1RTaQZ93EMTKOPUY-IEslkcfM,2460
|
|
12
12
|
tests/test_middleware.py,sha256=3HYmTx0Jw4XTNJjqLYeyGS_QZzcqkFuKfShtajIDhF4,2146
|
|
13
13
|
tests/utils.py,sha256=Ln_DYaMkwAVBo4XQ-QKwlCWP8zZYMenWTcFhsneoL0g,2913
|
|
14
|
-
deepagents-0.0.
|
|
15
|
-
deepagents-0.0.
|
|
16
|
-
deepagents-0.0.
|
|
17
|
-
deepagents-0.0.
|
|
14
|
+
deepagents-0.0.11rc1.dist-info/METADATA,sha256=nWOCcZljXdWY9tm3Gc_0Wyt7ZK0WScU0MhZY-jlJKuY,17331
|
|
15
|
+
deepagents-0.0.11rc1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
16
|
+
deepagents-0.0.11rc1.dist-info/top_level.txt,sha256=_w9VMQtG4YDNg5A5eAeUre7dF7x7hk9zRpT9zsFaukY,17
|
|
17
|
+
deepagents-0.0.11rc1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|