Skip to content

Commit b6e8ee5

Browse files
committed
fix(sandbox): preserve observer idle cleanup
1 parent c39a4dc commit b6e8ee5

2 files changed

Lines changed: 55 additions & 36 deletions

File tree

astrbot/core/computer/computer_client.py

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ def _save_cua_registry() -> None:
5454
sandbox_manager.save_registry()
5555

5656

57-
def _get_cua_idle_timeout(config: dict) -> float:
57+
def _get_cua_idle_timeout(context: Context, session_id: str) -> float:
5858
_sync_sandbox_manager_refs()
59-
return sandbox_manager.get_idle_timeout(config, "cua")
59+
return sandbox_manager.providers["cua"].get_idle_timeout(context, session_id)
6060

6161

6262
def _clear_cua_idle_state(sandbox_id: str) -> None:
@@ -176,39 +176,6 @@ async def _boot_managed_cua_sandbox_hook(
176176
_sync_sandbox_manager_refs()
177177

178178

179-
def _new_managed_cua_sandbox_id() -> str:
180-
return f"cua-{uuid.uuid4().hex[:12]}"
181-
182-
183-
def _build_cua_sandbox_record_payload(
184-
*,
185-
sandbox_id: str,
186-
sandbox_name: str,
187-
session_id: str,
188-
cua_kwargs: dict,
189-
idle_timeout: float,
190-
is_default: bool = False,
191-
) -> dict:
192-
return {
193-
"sandbox_id": sandbox_id,
194-
"sandbox_name": sandbox_name,
195-
"booter_type": "cua",
196-
"provider": "cua",
197-
"managed": True,
198-
"created_by_astrbot": True,
199-
"owner_user_id": session_id,
200-
"owner_session_id": session_id,
201-
"connect_info": {
202-
"name": sandbox_name,
203-
"local": cua_kwargs.get("local", True),
204-
"image": cua_kwargs.get("image"),
205-
"os_type": cua_kwargs.get("os_type"),
206-
},
207-
"is_default": is_default,
208-
"idle_timeout": idle_timeout,
209-
}
210-
211-
212179
async def _get_or_create_cua_booter(
213180
context: Context, session_id: str, sandbox_cfg: dict
214181
) -> ComputerBooter:
@@ -471,7 +438,10 @@ async def get_cua_observer_booter(context: Context, session_id: str) -> Computer
471438
current_sandbox_id = getattr(booter, "sandbox_id", current_sandbox_id)
472439
cua_registry.touch_sandbox(current_sandbox_id)
473440
_save_cua_registry()
474-
_schedule_cua_idle_cleanup(current_sandbox_id, _get_cua_idle_timeout(config))
441+
_schedule_cua_idle_cleanup(
442+
current_sandbox_id,
443+
_get_cua_idle_timeout(context, session_id),
444+
)
475445
return booter
476446

477447

tests/unit/test_cua_computer_use.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,6 +1725,55 @@ async def available(self):
17251725
assert "shipyard-session" not in computer_client.cua_idle_state
17261726

17271727

1728+
@pytest.mark.asyncio
1729+
async def test_cua_observer_booter_schedules_configured_idle_cleanup(
1730+
monkeypatch, tmp_path
1731+
):
1732+
from astrbot.core.computer import computer_client
1733+
from astrbot.core.computer.cua_registry import CuaSandboxRegistry
1734+
1735+
class FakeBooter:
1736+
async def available(self):
1737+
return True
1738+
1739+
registry = CuaSandboxRegistry(storage_path=tmp_path / "observer-registry.json")
1740+
registry.upsert_sandbox(
1741+
sandbox_id="sb-observer-timeout",
1742+
sandbox_name="observer-timeout",
1743+
booter_type="cua",
1744+
provider="cua",
1745+
managed=True,
1746+
created_by_astrbot=True,
1747+
owner_user_id="session-a",
1748+
owner_session_id="session-a",
1749+
connect_info={"name": "observer-timeout", "local": True},
1750+
)
1751+
registry.set_current_sandbox_id("session-a", "sb-observer-timeout")
1752+
monkeypatch.setattr(computer_client, "cua_registry", registry)
1753+
computer_client.session_booter.clear()
1754+
computer_client.cua_idle_state.clear()
1755+
computer_client.session_booter["sb-observer-timeout"] = FakeBooter()
1756+
1757+
ctx = FakeContext(
1758+
{
1759+
"provider_settings": {
1760+
"computer_use_runtime": "sandbox",
1761+
"sandbox": {
1762+
"booter": "cua",
1763+
"cua_idle_timeout": 0.2,
1764+
},
1765+
}
1766+
}
1767+
)
1768+
1769+
await computer_client.get_cua_observer_booter(ctx, "session-a")
1770+
1771+
state = computer_client.cua_idle_state.get("sb-observer-timeout")
1772+
assert state is not None
1773+
assert state.task.done() is False
1774+
computer_client._clear_cua_idle_state("sb-observer-timeout")
1775+
1776+
17281777
@pytest.mark.asyncio
17291778
async def test_cua_components_map_sdk_results(tmp_path):
17301779
from astrbot.core.computer.booters.cua import (

0 commit comments

Comments
 (0)