Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c3b4be2
feat: add CUA computer-use sandbox support
zouyonghe Apr 27, 2026
76cdb53
fix: add CUA config metadata translations
zouyonghe Apr 27, 2026
bc9f966
fix: address CUA sandbox review feedback
zouyonghe Apr 27, 2026
cd7ca5a
fix: default CUA sandbox to local mode
zouyonghe Apr 27, 2026
dc882c1
fix: harden CUA SDK method compatibility
zouyonghe Apr 27, 2026
1fbcfd3
fix: harden CUA GUI and permission handling
zouyonghe Apr 27, 2026
0c02edd
fix: refine CUA capability and shell handling
zouyonghe Apr 27, 2026
22d7400
fix: avoid inline CUA screenshot image results by default
zouyonghe Apr 27, 2026
df54a02
fix: guide CUA browser startup workflow
zouyonghe Apr 27, 2026
b8674ef
feat: add CUA browser and key press tools
zouyonghe Apr 27, 2026
0fab3f4
fix: launch CUA browser as sandbox user
zouyonghe Apr 27, 2026
bfe0431
fix: stabilize CUA browser screenshots
zouyonghe Apr 27, 2026
a5f8dfc
fix: simplify CUA browser launch command
zouyonghe Apr 27, 2026
07939ab
fix: remove CUA open browser tool
zouyonghe Apr 27, 2026
e06ae8d
fix: align CUA desktop control guidance
zouyonghe Apr 27, 2026
095d142
fix: harden CUA shell background handling
zouyonghe Apr 27, 2026
8367e11
fix: harden CUA runtime adapters
zouyonghe Apr 27, 2026
60625d2
fix: surface CUA filesystem failures
zouyonghe Apr 27, 2026
e1bc2c4
fix: clarify CUA shell fallback support
zouyonghe Apr 27, 2026
4af592d
fix: harden CUA shell helpers
zouyonghe Apr 27, 2026
19d7896
fix: guard CUA file fallbacks
zouyonghe Apr 27, 2026
0e985a7
fix: redact sensitive config log paths
zouyonghe Apr 27, 2026
0a1790b
fix: guard CUA download fallback
zouyonghe Apr 27, 2026
89aad65
test: cover CUA GUI and shell env wiring
zouyonghe Apr 27, 2026
5cc921d
fix: preserve CUA command result output
zouyonghe Apr 27, 2026
8ffc2ce
fix: normalize CUA return codes
zouyonghe Apr 27, 2026
c084a5a
fix: preserve foreground shell behavior
zouyonghe Apr 27, 2026
ff46f9e
fix: clean up failed CUA boots
zouyonghe Apr 27, 2026
14f7295
docs: add CUA sandbox runtime guide
zouyonghe Apr 27, 2026
598a59d
test: cover CUA GUI tool registration
zouyonghe Apr 27, 2026
e257158
refactor: simplify CUA fallback handling
zouyonghe Apr 27, 2026
51c0525
refactor: simplify CUA shell helpers
zouyonghe Apr 27, 2026
9f23aa8
test: cover CUA screenshot result shapes
zouyonghe Apr 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion astrbot/core/astr_agent_tool_exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
from astrbot.core.provider.entites import ProviderRequest
from astrbot.core.provider.register import llm_tools
from astrbot.core.tools.computer_tools import (
CuaKeyboardTypeTool,
CuaMouseClickTool,
CuaScreenshotTool,
ExecuteShellTool,
FileDownloadTool,
FileEditTool,
Expand Down Expand Up @@ -186,7 +189,9 @@ def _get_runtime_computer_tools(
cls,
runtime: str,
tool_mgr,
booter: str | None = None,
) -> dict[str, FunctionTool]:
booter = "" if booter is None else str(booter).lower()
if runtime == "sandbox":
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
shell_tool = tool_mgr.get_builtin_tool(ExecuteShellTool)
python_tool = tool_mgr.get_builtin_tool(PythonTool)
Expand All @@ -196,7 +201,7 @@ def _get_runtime_computer_tools(
write_tool = tool_mgr.get_builtin_tool(FileWriteTool)
edit_tool = tool_mgr.get_builtin_tool(FileEditTool)
grep_tool = tool_mgr.get_builtin_tool(GrepTool)
return {
tools = {
shell_tool.name: shell_tool,
python_tool.name: python_tool,
upload_tool.name: upload_tool,
Expand All @@ -206,6 +211,18 @@ def _get_runtime_computer_tools(
edit_tool.name: edit_tool,
grep_tool.name: grep_tool,
}
if booter == "cua":
screenshot_tool = tool_mgr.get_builtin_tool(CuaScreenshotTool)
mouse_click_tool = tool_mgr.get_builtin_tool(CuaMouseClickTool)
keyboard_type_tool = tool_mgr.get_builtin_tool(CuaKeyboardTypeTool)
tools.update(
{
screenshot_tool.name: screenshot_tool,
mouse_click_tool.name: mouse_click_tool,
keyboard_type_tool.name: keyboard_type_tool,
}
)
return tools
if runtime == "local":
shell_tool = tool_mgr.get_builtin_tool(ExecuteShellTool)
python_tool = tool_mgr.get_builtin_tool(LocalPythonTool)
Expand Down Expand Up @@ -242,6 +259,7 @@ def _build_handoff_toolset(
runtime_computer_tools = cls._get_runtime_computer_tools(
runtime,
tool_mgr,
provider_settings.get("sandbox", {}).get("booter"),
)

# Keep persona semantics aligned with the main agent: tools=None means
Expand Down
19 changes: 19 additions & 0 deletions astrbot/core/astr_main_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
BrowserExecTool,
CreateSkillCandidateTool,
CreateSkillPayloadTool,
CuaKeyboardTypeTool,
CuaMouseClickTool,
CuaScreenshotTool,
EvaluateSkillCandidateTool,
ExecuteShellTool,
FileDownloadTool,
Expand Down Expand Up @@ -1015,6 +1018,22 @@ def _apply_sandbox_tools(
req.func_tool.add_tool(tool_mgr.get_builtin_tool(RollbackSkillReleaseTool))
req.func_tool.add_tool(tool_mgr.get_builtin_tool(SyncSkillReleaseTool))

if booter == "cua":
req.system_prompt += (
"\n[CUA Desktop Control]\n"
"Use `astrbot_execute_shell` with `background=true` to launch GUI apps. "
'Use Firefox for browser tasks, for example `firefox "https://example.com"`. '
"After each visible step, call `astrbot_cua_screenshot` with "
"`send_to_user=true` and `return_image_to_llm=true` so the user can "
"monitor progress. When typing, inspect the screenshot first and confirm "
"the target field is focused and empty or safe to append to. Use "
"`astrbot_cua_mouse_click` for coordinates and `astrbot_cua_keyboard_type` "
"for text input; use text=`\\n` for Enter.\n"
)
req.func_tool.add_tool(tool_mgr.get_builtin_tool(CuaScreenshotTool))
req.func_tool.add_tool(tool_mgr.get_builtin_tool(CuaMouseClickTool))
req.func_tool.add_tool(tool_mgr.get_builtin_tool(CuaKeyboardTypeTool))

req.system_prompt = f"{req.system_prompt or ''}\n{SANDBOX_MODE_PROMPT}\n"


Expand Down
5 changes: 5 additions & 0 deletions astrbot/core/computer/booters/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from ..olayer import (
BrowserComponent,
FileSystemComponent,
GUIComponent,
PythonComponent,
ShellComponent,
)
Expand Down Expand Up @@ -29,6 +30,10 @@ def capabilities(self) -> tuple[str, ...] | None:
def browser(self) -> BrowserComponent | None:
return None

@property
def gui(self) -> GUIComponent | None:
return None

async def boot(self, session_id: str) -> None: ...

async def shutdown(self) -> None: ...
Expand Down
Loading
Loading