1818from automation .agents import BaseAgent
1919from automation .agents .middleware import InjectImagesMiddleware
2020from 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
2222from automation .agents .tools .toolkits import (
2323 FileEditingToolkit ,
2424 FileNavigationToolkit ,
2525 MCPToolkit ,
2626 MergeRequestToolkit ,
27- SandboxToolkit ,
2827 WebSearchToolkit ,
2928)
3029from 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 ],
0 commit comments