Skip to content

Commit b70439b

Browse files
committed
Merge branch 'master' of https://github.com/elecvoid243/AstrBot
2 parents 2f93e9e + c098de9 commit b70439b

78 files changed

Lines changed: 6080 additions & 1611 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build-docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
- name: checkout
1414
uses: actions/checkout@v6
1515
- name: Setup pnpm
16-
uses: pnpm/action-setup@v5.0.0
16+
uses: pnpm/action-setup@v6.0.3
1717
with:
1818
version: 10.28.2
1919
- name: Setup Node.js

.github/workflows/dashboard_ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
uses: actions/checkout@v6
1616

1717
- name: Setup pnpm
18-
uses: pnpm/action-setup@v5.0.0
18+
uses: pnpm/action-setup@v6.0.3
1919
with:
2020
version: 10.28.2
2121

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ jobs:
5151
echo "tag=$tag" >> "$GITHUB_OUTPUT"
5252
5353
- name: Setup pnpm
54-
uses: pnpm/action-setup@v5.0.0
54+
uses: pnpm/action-setup@v6.0.3
5555
with:
5656
version: 10.28.2
5757

astrbot/core/agent/runners/tool_loop_agent_runner.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,7 +1322,7 @@ async def _resolve_tool_exec(
13221322
model=self.req.model,
13231323
session_id=self.req.session_id,
13241324
extra_user_content_parts=self.req.extra_user_content_parts,
1325-
tool_choice="required",
1325+
# tool_choice="required",
13261326
abort_signal=self._abort_signal,
13271327
)
13281328
if requery_resp:
@@ -1348,7 +1348,7 @@ async def _resolve_tool_exec(
13481348
model=self.req.model,
13491349
session_id=self.req.session_id,
13501350
extra_user_content_parts=self.req.extra_user_content_parts,
1351-
tool_choice="required",
1351+
# tool_choice="required",
13521352
abort_signal=self._abort_signal,
13531353
)
13541354
if repair_resp:

astrbot/core/agent/tool_image_cache.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ def __init__(self) -> None:
5252
self._initialized = True
5353
self._cache_dir = os.path.join(get_astrbot_temp_path(), self.CACHE_DIR_NAME)
5454
os.makedirs(self._cache_dir, exist_ok=True)
55-
logger.debug(f"ToolImageCache initialized, cache dir: {self._cache_dir}")
5655

5756
def _get_file_extension(self, mime_type: str) -> str:
5857
"""Get file extension from MIME type."""

astrbot/core/astr_agent_tool_exec.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
from astrbot.core.provider.entites import ProviderRequest
3333
from astrbot.core.provider.register import llm_tools
3434
from astrbot.core.tools.computer_tools import (
35+
CuaKeyboardTypeTool,
36+
CuaMouseClickTool,
37+
CuaScreenshotTool,
3538
ExecuteShellTool,
3639
FileDownloadTool,
3740
FileEditTool,
@@ -187,7 +190,9 @@ def _get_runtime_computer_tools(
187190
cls,
188191
runtime: str,
189192
tool_mgr,
193+
booter: str | None = None,
190194
) -> dict[str, FunctionTool]:
195+
booter = "" if booter is None else str(booter).lower()
191196
if runtime == "sandbox":
192197
shell_tool = tool_mgr.get_builtin_tool(ExecuteShellTool)
193198
python_tool = tool_mgr.get_builtin_tool(PythonTool)
@@ -197,7 +202,7 @@ def _get_runtime_computer_tools(
197202
write_tool = tool_mgr.get_builtin_tool(FileWriteTool)
198203
edit_tool = tool_mgr.get_builtin_tool(FileEditTool)
199204
grep_tool = tool_mgr.get_builtin_tool(GrepTool)
200-
return {
205+
tools = {
201206
shell_tool.name: shell_tool,
202207
python_tool.name: python_tool,
203208
upload_tool.name: upload_tool,
@@ -207,6 +212,18 @@ def _get_runtime_computer_tools(
207212
edit_tool.name: edit_tool,
208213
grep_tool.name: grep_tool,
209214
}
215+
if booter == "cua":
216+
screenshot_tool = tool_mgr.get_builtin_tool(CuaScreenshotTool)
217+
mouse_click_tool = tool_mgr.get_builtin_tool(CuaMouseClickTool)
218+
keyboard_type_tool = tool_mgr.get_builtin_tool(CuaKeyboardTypeTool)
219+
tools.update(
220+
{
221+
screenshot_tool.name: screenshot_tool,
222+
mouse_click_tool.name: mouse_click_tool,
223+
keyboard_type_tool.name: keyboard_type_tool,
224+
}
225+
)
226+
return tools
210227
if runtime == "local":
211228
shell_tool = tool_mgr.get_builtin_tool(ExecuteShellTool)
212229
python_tool = tool_mgr.get_builtin_tool(LocalPythonTool)
@@ -243,6 +260,7 @@ def _build_handoff_toolset(
243260
runtime_computer_tools = cls._get_runtime_computer_tools(
244261
runtime,
245262
tool_mgr,
263+
provider_settings.get("sandbox", {}).get("booter"),
246264
)
247265

248266
# Keep persona semantics aligned with the main agent: tools=None means

astrbot/core/astr_main_agent.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848
BrowserExecTool,
4949
CreateSkillCandidateTool,
5050
CreateSkillPayloadTool,
51+
CuaKeyboardTypeTool,
52+
CuaMouseClickTool,
53+
CuaScreenshotTool,
5154
EvaluateSkillCandidateTool,
5255
ExecuteShellTool,
5356
FileDownloadTool,
@@ -1108,6 +1111,22 @@ def _apply_sandbox_tools(
11081111
req.func_tool.add_tool(tool_mgr.get_builtin_tool(RollbackSkillReleaseTool))
11091112
req.func_tool.add_tool(tool_mgr.get_builtin_tool(SyncSkillReleaseTool))
11101113

1114+
if booter == "cua":
1115+
req.system_prompt += (
1116+
"\n[CUA Desktop Control]\n"
1117+
"Use `astrbot_execute_shell` with `background=true` to launch GUI apps. "
1118+
'Use Firefox for browser tasks, for example `firefox "https://example.com"`. '
1119+
"After each visible step, call `astrbot_cua_screenshot` with "
1120+
"`send_to_user=true` and `return_image_to_llm=true` so the user can "
1121+
"monitor progress. When typing, inspect the screenshot first and confirm "
1122+
"the target field is focused and empty or safe to append to. Use "
1123+
"`astrbot_cua_mouse_click` for coordinates and `astrbot_cua_keyboard_type` "
1124+
"for text input; use text=`\\n` for Enter.\n"
1125+
)
1126+
req.func_tool.add_tool(tool_mgr.get_builtin_tool(CuaScreenshotTool))
1127+
req.func_tool.add_tool(tool_mgr.get_builtin_tool(CuaMouseClickTool))
1128+
req.func_tool.add_tool(tool_mgr.get_builtin_tool(CuaKeyboardTypeTool))
1129+
11111130
req.system_prompt = f"{req.system_prompt or ''}\n{SANDBOX_MODE_PROMPT}\n"
11121131

11131132

astrbot/core/computer/booters/base.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from ..olayer import (
22
BrowserComponent,
33
FileSystemComponent,
4+
GUIComponent,
45
PythonComponent,
56
ShellComponent,
67
)
@@ -29,9 +30,21 @@ def capabilities(self) -> tuple[str, ...] | None:
2930
def browser(self) -> BrowserComponent | None:
3031
return None
3132

33+
@property
34+
def gui(self) -> GUIComponent | None:
35+
return None
36+
3237
async def boot(self, session_id: str) -> None: ...
3338

34-
async def shutdown(self) -> None: ...
39+
async def shutdown(self, **kwargs) -> None:
40+
"""Shut down the computer sandbox.
41+
42+
Subclasses may accept extra keyword arguments for
43+
type-specific cleanup (e.g. ``delete_sandbox`` for
44+
ShipyardNeoBooter). The default implementation ignores
45+
them.
46+
"""
47+
...
3548

3649
async def upload_file(self, path: str, file_name: str) -> dict:
3750
"""Upload file to the computer.

0 commit comments

Comments
 (0)