Skip to content

Commit cf646bf

Browse files
committed
Migrated sandbox tools to middleware.
1 parent 2ff01d1 commit cf646bf

File tree

10 files changed

+231
-279
lines changed

10 files changed

+231
-279
lines changed

daiv/automation/agents/plan_and_execute/agent.py

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,12 @@
1818
from automation.agents import BaseAgent
1919
from automation.agents.middleware import InjectImagesMiddleware
2020
from automation.agents.tools.navigation import READ_MAX_LINES
21-
from automation.agents.tools.sandbox import BASH_TOOL_NAME, format_code_tool
21+
from automation.agents.tools.sandbox import BASH_TOOL_NAME, FORMAT_CODE_TOOL_NAME, SandboxMiddleware
2222
from automation.agents.tools.toolkits import (
2323
FileEditingToolkit,
2424
FileNavigationToolkit,
2525
MCPToolkit,
2626
MergeRequestToolkit,
27-
SandboxToolkit,
2827
WebSearchToolkit,
2928
)
3029
from codebase.context import RuntimeCtx
@@ -99,17 +98,7 @@ class ExecutorMiddleware(AgentMiddleware):
9998
Middleware to select the tools for the executor agent based on the tool calls.
10099
"""
101100

102-
def __init__(self, *, enable_bash: bool = False, enable_format_code: bool = False):
103-
"""
104-
Initialize the middleware.
105-
106-
Args:
107-
enable_bash (bool): Whether to enable the bash tool.
108-
enable_format_code (bool): Whether to enable the format code tool.
109-
"""
110-
super().__init__()
111-
self.enable_bash = enable_bash
112-
self.enable_format_code = enable_format_code
101+
name = "executor_middleware"
113102

114103
async def abefore_agent(self, state: ExecutorState, runtime: Runtime[RuntimeCtx]) -> dict[str, Any] | None:
115104
"""
@@ -138,14 +127,14 @@ async def awrap_model_call(
138127
Returns:
139128
ModelCallResult: The result of the model call.
140129
"""
130+
tools_names = [tool.name for tool in request.tools]
141131
request.system_prompt = execute_plan_system.format(
142132
current_date_time=timezone.now().strftime("%d %B, %Y"),
143133
repository=request.runtime.context.repo_id,
144-
commands_enabled=self.enable_bash,
145-
format_code_enabled=self.enable_format_code,
146-
tools_names=[tool.name for tool in request.tools],
134+
commands_enabled=BASH_TOOL_NAME in tools_names,
135+
format_code_enabled=FORMAT_CODE_TOOL_NAME in tools_names,
136+
tools_names=tools_names,
147137
).content
148-
149138
return await handler(request)
150139

151140

@@ -195,15 +184,21 @@ async def plan(
195184
Returns:
196185
Command[Literal["plan_approval", "__end__"]]: The next step in the workflow.
197186
"""
198-
mcp_tools = await MCPToolkit.get_tools()
199-
file_navigation_tools = FileNavigationToolkit.get_tools()
200-
web_search_tools = WebSearchToolkit.get_tools()
201187

202-
all_tools: list[BaseTool] = mcp_tools + file_navigation_tools + web_search_tools + [plan_think_tool]
188+
all_tools: list[BaseTool] = (
189+
(await MCPToolkit.get_tools())
190+
+ FileNavigationToolkit.get_tools()
191+
+ WebSearchToolkit.get_tools()
192+
+ [plan_think_tool]
193+
)
203194

204195
if runtime.context.merge_request_id:
205196
all_tools.extend(MergeRequestToolkit.get_tools())
206197

198+
conditional_middlewares: list[AgentMiddleware] = []
199+
if runtime.context.config.sandbox.enabled:
200+
conditional_middlewares.append(SandboxMiddleware(read_only_bash=True))
201+
207202
planner_agent = create_agent(
208203
model=BaseAgent.get_model(
209204
model=settings.PLANNING_MODEL_NAME, max_tokens=8_192, thinking_level=settings.PLANNING_THINKING_LEVEL
@@ -213,7 +208,12 @@ async def plan(
213208
checkpointer=False,
214209
context_schema=RuntimeCtx,
215210
response_format=ToolStrategy(FinalizerOutput),
216-
middleware=[plan_system_prompt, InjectImagesMiddleware(), AnthropicPromptCachingMiddleware()],
211+
middleware=[
212+
plan_system_prompt,
213+
InjectImagesMiddleware(),
214+
*conditional_middlewares,
215+
AnthropicPromptCachingMiddleware(),
216+
],
217217
name="planner_agent",
218218
)
219219

@@ -274,27 +274,25 @@ async def execute_plan(
274274
Returns:
275275
Command[Literal["__end__"]]: The next step in the workflow.
276276
"""
277-
all_tools: list[BaseTool] = (
278-
FileNavigationToolkit.get_tools() + FileEditingToolkit.get_tools() + [review_code_changes_tool]
279-
)
280-
277+
conditional_middlewares: list[AgentMiddleware] = []
281278
if runtime.context.config.sandbox.enabled:
282-
all_tools += SandboxToolkit.get_tools()
283-
284-
if not self.skip_format_code and runtime.context.config.sandbox.format_code_enabled:
285-
all_tools.append(format_code_tool)
279+
conditional_middlewares.append(
280+
SandboxMiddleware(
281+
include_format_code=bool(
282+
not self.skip_format_code and runtime.context.config.sandbox.format_code_enabled
283+
)
284+
)
285+
)
286286

287287
executor_agent = create_agent(
288288
model=BaseAgent.get_model(model=settings.EXECUTION_MODEL_NAME, max_tokens=8_192),
289289
state_schema=ExecutorState,
290290
context_schema=RuntimeCtx,
291-
tools=all_tools,
291+
tools=(FileNavigationToolkit.get_tools() + FileEditingToolkit.get_tools() + [review_code_changes_tool]),
292292
store=runtime.store,
293293
middleware=[
294-
ExecutorMiddleware(
295-
enable_bash=runtime.context.config.sandbox.enabled,
296-
enable_format_code=not self.skip_format_code and runtime.context.config.sandbox.format_code_enabled,
297-
),
294+
ExecutorMiddleware(),
295+
*conditional_middlewares,
298296
TodoListMiddleware(),
299297
AnthropicPromptCachingMiddleware(),
300298
],

daiv/automation/agents/plan_and_execute/prompts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
7070
### Phase 1: Understand (Required)
7171
1. **Plan your approach** using `think` - outline what you need to investigate
72-
2. **Gather context** using investigation tools (`ls`, `read`, `grep`, `glob`, `fetch`, `web_search`, etc.)
72+
2. **Gather context** using investigation tools (`ls`, `read`, `grep`, `glob`, `fetch`, `web_search`,{% if commands_enabled %} `bash`,{% endif %} etc.)
7373
3. **Update your understanding** with `think` as you learn new information
7474
7575
### Phase 2: Deliver (Required)

daiv/automation/agents/plan_and_execute/tools.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ def plan_think_tool(plan: str):
2626
2727
**Usage rules:**
2828
- Does NOT fetch new information or modify anything, it's just a placeholder to help you track progress.
29-
- Update tasks as you learn new information to help you track progress.
29+
- Add any new follow-up tasks as you discover them during your investigation.
30+
- 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.
3031
- **Important:** It is critical that you mark tasks as completed as soon as you are done with them. Do not batch up multiple tasks before marking them as completed.
3132
3233
**Skip using this tool when:**
@@ -35,8 +36,10 @@ def plan_think_tool(plan: str):
3536
- The task can be completed in less than 3 trivial steps
3637
- The task is purely conversational or informational
3738
39+
Being proactive with task management demonstrates attentiveness and ensures you complete all requirements successfully.
40+
3841
Args:
39-
plan (str): The plan to investigate.
42+
plan (str): The plan to investigate in markdown format.
4043
4144
Returns:
4245
A message indicating that the thought has been registered.

0 commit comments

Comments
 (0)