deepagents 0.0.11rc1__py3-none-any.whl → 0.0.12rc2__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/tools.py DELETED
@@ -1,201 +0,0 @@
1
- from re import L
2
- from langchain_core.tools import tool, InjectedToolCallId
3
- from langchain_core.messages import ToolMessage
4
- from langgraph.types import Command
5
- from langchain.tools.tool_node import InjectedState
6
- from typing import Annotated, Union
7
- from deepagents.state import Todo, FilesystemState
8
- from deepagents.prompts import (
9
- WRITE_TODOS_TOOL_DESCRIPTION,
10
- LIST_FILES_TOOL_DESCRIPTION,
11
- READ_FILE_TOOL_DESCRIPTION,
12
- WRITE_FILE_TOOL_DESCRIPTION,
13
- EDIT_FILE_TOOL_DESCRIPTION,
14
- )
15
- from ai_filesystem import FilesystemClient
16
- import os
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/", "")
26
-
27
- @tool(description=WRITE_TODOS_TOOL_DESCRIPTION)
28
- def write_todos(
29
- todos: list[Todo], tool_call_id: Annotated[str, InjectedToolCallId]
30
- ) -> Command:
31
- return Command(
32
- update={
33
- "todos": todos,
34
- "messages": [
35
- ToolMessage(f"Updated todo list to {todos}", tool_call_id=tool_call_id)
36
- ],
37
- }
38
- )
39
-
40
-
41
- @tool(description=LIST_FILES_TOOL_DESCRIPTION)
42
- def ls(state: Annotated[FilesystemState, InjectedState]) -> list[str]:
43
- """List all files"""
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
55
-
56
-
57
- @tool(description=READ_FILE_TOOL_DESCRIPTION)
58
- def read_file(
59
- file_path: str,
60
- state: Annotated[FilesystemState, InjectedState],
61
- offset: int = 0,
62
- limit: int = 2000,
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
-
73
- mock_filesystem = state.get("files", {})
74
- if file_path not in mock_filesystem:
75
- return f"Error: File '{file_path}' not found"
76
-
77
- # Get file content
78
- content = mock_filesystem[file_path]
79
-
80
- # Handle empty file
81
- if not content or content.strip() == "":
82
- return "System reminder: File exists but has empty contents"
83
-
84
- # Split content into lines
85
- lines = content.splitlines()
86
-
87
- # Apply line offset and limit
88
- start_idx = offset
89
- end_idx = min(start_idx + limit, len(lines))
90
-
91
- # Handle case where offset is beyond file length
92
- if start_idx >= len(lines):
93
- return f"Error: Line offset {offset} exceeds file length ({len(lines)} lines)"
94
-
95
- # Format output with line numbers (cat -n format)
96
- result_lines = []
97
- for i in range(start_idx, end_idx):
98
- line_content = lines[i]
99
-
100
- # Truncate lines longer than 2000 characters
101
- if len(line_content) > 2000:
102
- line_content = line_content[:2000]
103
-
104
- # Line numbers start at 1, so add 1 to the index
105
- line_number = i + 1
106
- result_lines.append(f"{line_number:6d}\t{line_content}")
107
-
108
- return "\n".join(result_lines)
109
-
110
-
111
- @tool(description=WRITE_FILE_TOOL_DESCRIPTION)
112
- def write_file(
113
- file_path: str,
114
- content: str,
115
- state: Annotated[FilesystemState, InjectedState],
116
- tool_call_id: Annotated[str, InjectedToolCallId],
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
-
131
- files = state.get("files", {})
132
- return Command(
133
- update={
134
- "files": files,
135
- "messages": [ToolMessage(f"Updated file {file_path}", tool_call_id=tool_call_id)]
136
- }
137
- )
138
-
139
-
140
- @tool(description=EDIT_FILE_TOOL_DESCRIPTION)
141
- def edit_file(
142
- file_path: str,
143
- old_string: str,
144
- new_string: str,
145
- state: Annotated[FilesystemState, InjectedState],
146
- tool_call_id: Annotated[str, InjectedToolCallId],
147
- replace_all: bool = False,
148
- ) -> Union[Command, str]:
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
-
163
- mock_filesystem = state.get("files", {})
164
- # Check if file exists in mock filesystem
165
- if file_path not in mock_filesystem:
166
- return f"Error: File '{file_path}' not found"
167
-
168
- # Get current file content
169
- content = mock_filesystem[file_path]
170
-
171
- # Check if old_string exists in the file
172
- if old_string not in content:
173
- return f"Error: String not found in file: '{old_string}'"
174
-
175
- # If not replace_all, check for uniqueness
176
- if not replace_all:
177
- occurrences = content.count(old_string)
178
- if occurrences > 1:
179
- return f"Error: String '{old_string}' appears {occurrences} times in file. Use replace_all=True to replace all instances, or provide a more specific string with surrounding context."
180
- elif occurrences == 0:
181
- return f"Error: String not found in file: '{old_string}'"
182
-
183
- # Perform the replacement
184
- if replace_all:
185
- new_content = content.replace(old_string, new_string)
186
- replacement_count = content.count(old_string)
187
- result_msg = f"Successfully replaced {replacement_count} instance(s) of the string in '{file_path}'"
188
- else:
189
- new_content = content.replace(
190
- old_string, new_string, 1
191
- ) # Replace only first occurrence
192
- result_msg = f"Successfully replaced string in '{file_path}'"
193
-
194
- # Update the mock filesystem
195
- mock_filesystem[file_path] = new_content
196
- return Command(
197
- update={
198
- "files": mock_filesystem,
199
- "messages": [ToolMessage(result_msg, tool_call_id=tool_call_id)],
200
- }
201
- )
deepagents/types.py DELETED
@@ -1,21 +0,0 @@
1
- from typing import NotRequired, Union, Any
2
- from typing_extensions import TypedDict
3
- from langchain_core.language_models import LanguageModelLike
4
- from langchain.agents.middleware import AgentMiddleware
5
- from langchain_core.runnables import Runnable
6
- from langchain_core.tools import BaseTool
7
-
8
- class SubAgent(TypedDict):
9
- name: str
10
- description: str
11
- prompt: str
12
- tools: NotRequired[list[BaseTool]]
13
- # Optional per-subagent model: can be either a model instance OR dict settings
14
- model: NotRequired[Union[LanguageModelLike, dict[str, Any]]]
15
- middleware: NotRequired[list[AgentMiddleware]]
16
-
17
-
18
- class CustomSubAgent(TypedDict):
19
- name: str
20
- description: str
21
- graph: Runnable
@@ -1,17 +0,0 @@
1
- deepagents/__init__.py,sha256=fA_91ByxPb3e8aPfci43zOXrWz8ylh_CFQALo7EUKi8,312
2
- deepagents/graph.py,sha256=sLN0gWJma9dGgJI_RHDK-I1cEZMCo8nfxuF4a8vN7Po,6288
3
- deepagents/middleware.py,sha256=P2y1crsedTH1uZlKS3fpc7pd4jwz8dR8jnw7repUjLk,7254
4
- deepagents/model.py,sha256=VyRIkdeXJH8HqLrudTKucHpBTtrwMFTQGRlXBj0kUyo,155
5
- deepagents/prompts.py,sha256=hiyiUriv-B3IQ0lwRqiJsvtgvwSS4wdeMNdXojHUisc,25603
6
- deepagents/state.py,sha256=8so3MgL-zRPYP8Ci_OuVg4wHrs5uAXCErKF1AjjCSt8,726
7
- deepagents/tools.py,sha256=kTS-O8jWJsUnX0tBl19Iyg8fSR2jhD8c7jDz_xNrw0I,7138
8
- deepagents/types.py,sha256=5KBSUPlWOnv9It3SnJCMHrOtp9Y4_NQGtGCp69JsEjE,694
9
- deepagents-0.0.11rc1.dist-info/licenses/LICENSE,sha256=c__BaxUCK69leo2yEKynf8lWndu8iwYwge1CbyqAe-E,1071
10
- tests/test_deepagents.py,sha256=SwtOiJF4c1O3r_Q3AiM7XZu6tVq4uMIcZlnsfRjx8Ig,7648
11
- tests/test_hitl.py,sha256=B16ZFiyaVSOcDLz7mh1RTaQZ93EMTKOPUY-IEslkcfM,2460
12
- tests/test_middleware.py,sha256=3HYmTx0Jw4XTNJjqLYeyGS_QZzcqkFuKfShtajIDhF4,2146
13
- tests/utils.py,sha256=Ln_DYaMkwAVBo4XQ-QKwlCWP8zZYMenWTcFhsneoL0g,2913
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,,
tests/test_deepagents.py DELETED
@@ -1,136 +0,0 @@
1
- from deepagents.graph import create_deep_agent
2
- from langchain.agents import create_agent
3
- from tests.utils import assert_all_deepagent_qualities, SAMPLE_MODEL, sample_tool, get_weather, get_soccer_scores, SampleMiddlewareWithTools, SampleMiddlewareWithToolsAndState, WeatherToolMiddleware, ResearchMiddleware, ResearchMiddlewareWithTools, TOY_BASKETBALL_RESEARCH
4
-
5
- class TestDeepAgents:
6
- def test_base_deep_agent(self):
7
- agent = create_deep_agent()
8
- assert_all_deepagent_qualities(agent)
9
-
10
- def test_deep_agent_with_tool(self):
11
- agent = create_deep_agent(tools=[sample_tool])
12
- assert_all_deepagent_qualities(agent)
13
- assert "sample_tool" in agent.nodes["tools"].bound._tools_by_name.keys()
14
-
15
- def test_deep_agent_with_middleware_with_tool(self):
16
- agent = create_deep_agent(middleware=[SampleMiddlewareWithTools()])
17
- assert_all_deepagent_qualities(agent)
18
- assert "sample_tool" in agent.nodes["tools"].bound._tools_by_name.keys()
19
-
20
- def test_deep_agent_with_middleware_with_tool_and_state(self):
21
- agent = create_deep_agent(middleware=[SampleMiddlewareWithToolsAndState()])
22
- assert_all_deepagent_qualities(agent)
23
- assert "sample_tool" in agent.nodes["tools"].bound._tools_by_name.keys()
24
- assert "sample_input" in agent.stream_channels
25
-
26
- def test_deep_agent_with_subagents(self):
27
- subagents = [
28
- {
29
- "name": "weather_agent",
30
- "description": "Use this agent to get the weather",
31
- "prompt": "You are a weather agent.",
32
- "tools": [get_weather],
33
- "model": SAMPLE_MODEL,
34
- }
35
- ]
36
- agent = create_deep_agent(tools=[sample_tool], subagents=subagents)
37
- assert_all_deepagent_qualities(agent)
38
- result = agent.invoke({"messages": [{"role": "user", "content": "What is the weather in Tokyo?"}]})
39
- agent_messages = [msg for msg in result.get("messages", []) if msg.type == "ai"]
40
- tool_calls = [tool_call for msg in agent_messages for tool_call in msg.tool_calls]
41
- assert any([tool_call["name"] == "task" and tool_call["args"].get("subagent_type") == "weather_agent" for tool_call in tool_calls])
42
-
43
- def test_deep_agent_with_subagents_gen_purpose(self):
44
- subagents = [
45
- {
46
- "name": "weather_agent",
47
- "description": "Use this agent to get the weather",
48
- "prompt": "You are a weather agent.",
49
- "tools": [get_weather],
50
- "model": SAMPLE_MODEL,
51
- }
52
- ]
53
- agent = create_deep_agent(tools=[sample_tool], subagents=subagents)
54
- assert_all_deepagent_qualities(agent)
55
- result = agent.invoke({"messages": [{"role": "user", "content": "Use the general purpose subagent to call the sample tool"}]})
56
- agent_messages = [msg for msg in result.get("messages", []) if msg.type == "ai"]
57
- tool_calls = [tool_call for msg in agent_messages for tool_call in msg.tool_calls]
58
- assert any([tool_call["name"] == "task" and tool_call["args"].get("subagent_type") == "general-purpose" for tool_call in tool_calls])
59
-
60
- def test_deep_agent_with_subagents_with_middleware(self):
61
- subagents = [
62
- {
63
- "name": "weather_agent",
64
- "description": "Use this agent to get the weather",
65
- "prompt": "You are a weather agent.",
66
- "tools": [],
67
- "model": SAMPLE_MODEL,
68
- "middleware": [WeatherToolMiddleware()],
69
- }
70
- ]
71
- agent = create_deep_agent(tools=[sample_tool], subagents=subagents)
72
- assert_all_deepagent_qualities(agent)
73
- result = agent.invoke({"messages": [{"role": "user", "content": "What is the weather in Tokyo?"}]})
74
- agent_messages = [msg for msg in result.get("messages", []) if msg.type == "ai"]
75
- tool_calls = [tool_call for msg in agent_messages for tool_call in msg.tool_calls]
76
- assert any([tool_call["name"] == "task" and tool_call["args"].get("subagent_type") == "weather_agent" for tool_call in tool_calls])
77
-
78
- def test_deep_agent_with_custom_subagents(self):
79
- subagents = [
80
- {
81
- "name": "weather_agent",
82
- "description": "Use this agent to get the weather",
83
- "prompt": "You are a weather agent.",
84
- "tools": [get_weather],
85
- "model": SAMPLE_MODEL,
86
- },
87
- {
88
- "name": "soccer_agent",
89
- "description": "Use this agent to get the latest soccer scores",
90
- "graph": create_agent(
91
- model=SAMPLE_MODEL,
92
- tools=[get_soccer_scores],
93
- prompt="You are a soccer agent.",
94
- )
95
- }
96
- ]
97
- agent = create_deep_agent(tools=[sample_tool], subagents=subagents)
98
- assert_all_deepagent_qualities(agent)
99
- result = agent.invoke({"messages": [{"role": "user", "content": "Look up the weather in Tokyo, and the latest scores for Manchester City!"}]})
100
- agent_messages = [msg for msg in result.get("messages", []) if msg.type == "ai"]
101
- tool_calls = [tool_call for msg in agent_messages for tool_call in msg.tool_calls]
102
- assert any([tool_call["name"] == "task" and tool_call["args"].get("subagent_type") == "weather_agent" for tool_call in tool_calls])
103
- assert any([tool_call["name"] == "task" and tool_call["args"].get("subagent_type") == "soccer_agent" for tool_call in tool_calls])
104
-
105
- def test_deep_agent_with_extended_state_and_subagents(self):
106
- subagents = [
107
- {
108
- "name": "basketball_info_agent",
109
- "description": "Use this agent to get surface level info on any basketball topic",
110
- "prompt": "You are a basketball info agent.",
111
- "middleware": [ResearchMiddlewareWithTools()],
112
- }
113
- ]
114
- agent = create_deep_agent(tools=[sample_tool], subagents=subagents, middleware=[ResearchMiddleware()])
115
- assert_all_deepagent_qualities(agent)
116
- assert "research" in agent.stream_channels
117
- result = agent.invoke({"messages": [{"role": "user", "content": "Get surface level info on lebron james"}]}, config={"recursion_limit": 100})
118
- agent_messages = [msg for msg in result.get("messages", []) if msg.type == "ai"]
119
- tool_calls = [tool_call for msg in agent_messages for tool_call in msg.tool_calls]
120
- assert any([tool_call["name"] == "task" and tool_call["args"].get("subagent_type") == "basketball_info_agent" for tool_call in tool_calls])
121
- assert TOY_BASKETBALL_RESEARCH in result["research"]
122
-
123
- def test_deep_agent_with_subagents_no_tools(self):
124
- subagents = [
125
- {
126
- "name": "basketball_info_agent",
127
- "description": "Use this agent to get surface level info on any basketball topic",
128
- "prompt": "You are a basketball info agent.",
129
- }
130
- ]
131
- agent = create_deep_agent(tools=[sample_tool], subagents=subagents)
132
- assert_all_deepagent_qualities(agent)
133
- result = agent.invoke({"messages": [{"role": "user", "content": "Use the basketball info subagent to call the sample tool"}]}, config={"recursion_limit": 100})
134
- agent_messages = [msg for msg in result.get("messages", []) if msg.type == "ai"]
135
- tool_calls = [tool_call for msg in agent_messages for tool_call in msg.tool_calls]
136
- assert any([tool_call["name"] == "task" and tool_call["args"].get("subagent_type") == "basketball_info_agent" for tool_call in tool_calls])
tests/test_hitl.py DELETED
@@ -1,51 +0,0 @@
1
- from deepagents.graph import create_deep_agent
2
- from tests.utils import assert_all_deepagent_qualities, get_weather, sample_tool, get_soccer_scores
3
- from langgraph.checkpoint.memory import MemorySaver
4
- from langgraph.types import Command
5
- import uuid
6
-
7
- SAMPLE_TOOL_CONFIG = {
8
- "sample_tool": True,
9
- "get_weather": False,
10
- "get_soccer_scores": {
11
- "allow_accept": True,
12
- "allow_reject": True,
13
- "allow_respond": False,
14
- "description": "Ohohohooooo"
15
- },
16
- }
17
-
18
- class TestHITL:
19
- def test_hitl_agent(self):
20
- checkpointer = MemorySaver()
21
- agent = create_deep_agent(tools=[sample_tool, get_weather, get_soccer_scores], tool_configs=SAMPLE_TOOL_CONFIG, checkpointer=checkpointer)
22
- config = {
23
- "configurable": {
24
- "thread_id": uuid.uuid4()
25
- }
26
- }
27
- assert_all_deepagent_qualities(agent)
28
- result = agent.invoke({"messages": [{"role": "user", "content": "Call the sample tool, get the weather in New York and get scores for the latest soccer games in parallel"}]}, config=config)
29
- agent_messages = [msg for msg in result.get("messages", []) if msg.type == "ai"]
30
- tool_calls = [tool_call for msg in agent_messages for tool_call in msg.tool_calls]
31
- assert any([tool_call["name"] == "sample_tool" for tool_call in tool_calls])
32
- assert any([tool_call["name"] == "get_weather" for tool_call in tool_calls])
33
- assert any([tool_call["name"] == "get_soccer_scores" for tool_call in tool_calls])
34
-
35
- assert result["__interrupt__"] is not None
36
- interrupts = result["__interrupt__"][0].value
37
- assert len(interrupts) == 2
38
- assert any([interrupt["action_request"]["action"] == "sample_tool" for interrupt in interrupts])
39
- assert any([interrupt["action_request"]["action"] == "get_soccer_scores" for interrupt in interrupts])
40
-
41
- result2 = agent.invoke(
42
- Command(
43
- resume=[{"type": "accept"}, {"type": "accept"}]
44
- ),
45
- config=config
46
- )
47
- tool_results = [msg for msg in result2.get("messages", []) if msg.type == "tool"]
48
- assert any([tool_result.name == "sample_tool" for tool_result in tool_results])
49
- assert any([tool_result.name == "get_weather" for tool_result in tool_results])
50
- assert any([tool_result.name == "get_soccer_scores" for tool_result in tool_results])
51
- assert "__interrupt__" not in result2
tests/test_middleware.py DELETED
@@ -1,57 +0,0 @@
1
- from langchain.agents import create_agent
2
- from deepagents.middleware import (
3
- PlanningMiddleware,
4
- FilesystemMiddleware,
5
- SubAgentMiddleware,
6
- )
7
-
8
- SAMPLE_MODEL = "claude-3-5-sonnet-20240620"
9
-
10
- class TestAddMiddleware:
11
- def test_planning_middleware(self):
12
- middleware = [PlanningMiddleware()]
13
- agent = create_agent(model=SAMPLE_MODEL, middleware=middleware, tools=[])
14
- assert "todos" in agent.stream_channels
15
- assert "write_todos" in agent.nodes["tools"].bound._tools_by_name.keys()
16
-
17
- def test_filesystem_middleware(self):
18
- middleware = [FilesystemMiddleware()]
19
- agent = create_agent(model=SAMPLE_MODEL, middleware=middleware, tools=[])
20
- assert "files" in agent.stream_channels
21
- agent_tools = agent.nodes["tools"].bound._tools_by_name.keys()
22
- assert "ls" in agent_tools
23
- assert "read_file" in agent_tools
24
- assert "write_file" in agent_tools
25
- assert "edit_file" in agent_tools
26
-
27
- def test_subagent_middleware(self):
28
- middleware = [
29
- SubAgentMiddleware(
30
- default_subagent_tools=[],
31
- subagents=[],
32
- model=SAMPLE_MODEL
33
- )
34
- ]
35
- agent = create_agent(model=SAMPLE_MODEL, middleware=middleware, tools=[])
36
- assert "task" in agent.nodes["tools"].bound._tools_by_name.keys()
37
-
38
- def test_multiple_middleware(self):
39
- middleware = [
40
- PlanningMiddleware(),
41
- FilesystemMiddleware(),
42
- SubAgentMiddleware(
43
- default_subagent_tools=[],
44
- subagents=[],
45
- model=SAMPLE_MODEL
46
- )
47
- ]
48
- agent = create_agent(model=SAMPLE_MODEL, middleware=middleware, tools=[])
49
- assert "todos" in agent.stream_channels
50
- assert "files" in agent.stream_channels
51
- agent_tools = agent.nodes["tools"].bound._tools_by_name.keys()
52
- assert "write_todos" in agent_tools
53
- assert "ls" in agent_tools
54
- assert "read_file" in agent_tools
55
- assert "write_file" in agent_tools
56
- assert "edit_file" in agent_tools
57
- assert "task" in agent_tools
tests/utils.py DELETED
@@ -1,81 +0,0 @@
1
- from langchain_core.tools import tool, InjectedToolCallId
2
- from langchain.agents.middleware import AgentMiddleware
3
- from typing import Annotated
4
- from langchain.agents.tool_node import InjectedState
5
- from langchain.agents.middleware import AgentMiddleware, AgentState
6
- from langgraph.types import Command
7
- from langchain_core.messages import ToolMessage
8
-
9
- def assert_all_deepagent_qualities(agent):
10
- assert "todos" in agent.stream_channels
11
- assert "files" in agent.stream_channels
12
- assert "write_todos" in agent.nodes["tools"].bound._tools_by_name.keys()
13
- assert "ls" in agent.nodes["tools"].bound._tools_by_name.keys()
14
- assert "read_file" in agent.nodes["tools"].bound._tools_by_name.keys()
15
- assert "write_file" in agent.nodes["tools"].bound._tools_by_name.keys()
16
- assert "edit_file" in agent.nodes["tools"].bound._tools_by_name.keys()
17
- assert "task" in agent.nodes["tools"].bound._tools_by_name.keys()
18
-
19
- ###########################
20
- # Mock tools and middleware
21
- ###########################
22
-
23
- SAMPLE_MODEL = "claude-3-5-sonnet-20240620"
24
-
25
- @tool(description="Use this tool to get the weather")
26
- def get_weather(location: str):
27
- return f"The weather in {location} is sunny."
28
-
29
- @tool(description="Use this tool to get the latest soccer scores")
30
- def get_soccer_scores(team: str):
31
- return f"The latest soccer scores for {team} are 2-1."
32
-
33
- @tool(description="Sample tool")
34
- def sample_tool(sample_input: str):
35
- return sample_input
36
-
37
- @tool(description="Sample tool with injected state")
38
- def sample_tool_with_injected_state(sample_input: str, state: Annotated[dict, InjectedState]):
39
- return sample_input + state["sample_input"]
40
-
41
- TOY_BASKETBALL_RESEARCH = "Lebron James is the best basketball player of all time with over 40k points and 21 seasons in the NBA."
42
-
43
- @tool(description="Use this tool to conduct research into basketball and save it to state")
44
- def research_basketball(
45
- topic: str,
46
- state: Annotated[dict, InjectedState],
47
- tool_call_id: Annotated[str, InjectedToolCallId]
48
- ):
49
- current_research = state.get("research", "")
50
- research = f"{current_research}\n\nResearching on {topic}... Done! {TOY_BASKETBALL_RESEARCH}"
51
- return Command(
52
- update={
53
- "research": research,
54
- "messages": [
55
- ToolMessage(research, tool_call_id=tool_call_id)
56
- ]
57
- }
58
- )
59
-
60
- class ResearchState(AgentState):
61
- research: str
62
-
63
- class ResearchMiddlewareWithTools(AgentMiddleware):
64
- state_schema = ResearchState
65
- tools = [research_basketball]
66
-
67
- class ResearchMiddleware(AgentMiddleware):
68
- state_schema = ResearchState
69
-
70
- class SampleMiddlewareWithTools(AgentMiddleware):
71
- tools = [sample_tool]
72
-
73
- class SampleState(AgentState):
74
- sample_input: str
75
-
76
- class SampleMiddlewareWithToolsAndState(AgentMiddleware):
77
- state_schema = SampleState
78
- tools = [sample_tool]
79
-
80
- class WeatherToolMiddleware(AgentMiddleware):
81
- tools = [get_weather]