From 4ccfec589b769f023dbc33e41ee3a358def8b654 Mon Sep 17 00:00:00 2001 From: Zamil Majdy Date: Sun, 12 Apr 2026 11:23:08 +0000 Subject: [PATCH] fix(backend): use mutating annotation for E2B write/edit tools and remove phantom tool names - Apply _MUTATING_ANNOTATION (readOnlyHint=False) to E2B write_file and edit_file tools to prevent unsafe parallel dispatch of file-mutating operations in the sandbox - Remove WRITE_TOOL_NAME and EDIT_TOOL_NAME from get_copilot_tool_names E2B branch since those unified tools are not registered in E2B mode (E2B uses write_file/edit_file from E2B_FILE_TOOLS instead) --- .../backend/backend/copilot/sdk/tool_adapter.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py b/autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py index 1bc2077d64..18cf235897 100644 --- a/autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py +++ b/autogpt_platform/backend/backend/copilot/sdk/tool_adapter.py @@ -646,13 +646,19 @@ def create_copilot_mcp_server(*, use_e2b: bool = False): sdk_tools.append(decorated) # E2B file tools replace SDK built-in Read/Write/Edit/Glob/Grep. + _MUTATING_E2B_TOOLS = {"write_file", "edit_file"} if use_e2b: for name, desc, schema, handler in E2B_FILE_TOOLS: + ann = ( + _MUTATING_ANNOTATION + if name in _MUTATING_E2B_TOOLS + else _PARALLEL_ANNOTATION + ) decorated = tool( name, desc, schema, - annotations=_PARALLEL_ANNOTATION, + annotations=ann, )(_make_truncating_wrapper(handler, name)) sdk_tools.append(decorated) @@ -819,12 +825,11 @@ def get_copilot_tool_names(*, use_e2b: bool = False) -> list[str]: if not use_e2b: return list(COPILOT_TOOL_NAMES) - # E2B_FILE_TOOL_NAMES already includes "read_file" \u2014 don't list - # READ_TOOL_NAME separately to avoid double registration. + # In E2B mode, Write/Edit are NOT registered (E2B uses write_file/edit_file + # from E2B_FILE_TOOLS instead), so don't include them here. + # _READ_TOOL_NAME is still needed for SDK tool-result reads. return [ *[f"{MCP_TOOL_PREFIX}{name}" for name in TOOL_REGISTRY.keys()], - f"{MCP_TOOL_PREFIX}{WRITE_TOOL_NAME}", - f"{MCP_TOOL_PREFIX}{EDIT_TOOL_NAME}", f"{MCP_TOOL_PREFIX}{_READ_TOOL_NAME}", *[f"{MCP_TOOL_PREFIX}{name}" for name in E2B_FILE_TOOL_NAMES], *_SDK_BUILTIN_ALWAYS,