diff --git a/bench/computer-use/run.py b/bench/computer-use/run.py index 2b6dc32..3fe1302 100644 --- a/bench/computer-use/run.py +++ b/bench/computer-use/run.py @@ -116,6 +116,46 @@ TASKS = [ "check": lambda dh, ans: form_code() in ans}, ] +COMPONENTS = r"""設定 +

帳號設定

尚未儲存

+""" + +# Held out: apps, tools and page shapes none of the tasks above use (and nothing was tuned on). +HELDOUT = [ + {"id": "N1", "route": "screen", "name": "Mousepad 存新檔", + "setup": "(command -v mousepad >/dev/null || (apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq mousepad >/dev/null)); rm -f /home/bot/bench/hello.txt; mkdir -p /home/bot/bench; pkill -x mousepad; true", + "ask": "用你電腦上的文字編輯器 Mousepad 開一個新檔,打「你好,AnyBot」,存成 ~/bench/hello.txt。", + "check": lambda dh, ans: "你好,AnyBot" in dx("cat ~/bench/hello.txt 2>/dev/null", dh)[1]}, + {"id": "N2", "route": "screen", "name": "Chromium 加書籤", + "setup": "pkill -f '^/usr/lib/chromium/chromium'; sleep 2; python3 - <<'PY'\n" + "import json\nfor p in ['/home/bot/.config/anybot-profile/Default/Bookmarks']:\n" + " try:\n d = json.load(open(p))\n except Exception:\n continue\n" + " for root in d.get('roots', {}).values():\n if isinstance(root, dict) and 'children' in root:\n root['children'] = [c for c in root['children'] if 'example.com' not in c.get('url', '')]\n" + " d.pop('checksum', None); json.dump(d, open(p, 'w'))\nPY", + "ask": "在你電腦的 Chromium 打開 https://example.com,把這一頁加入書籤。", + "check": lambda dh, ans: "example.com" in dx("for i in $(seq 15); do grep -q example.com ~/.config/anybot-profile/Default/Bookmarks 2>/dev/null && { echo example.com; break; }; sleep 1; done", dh)[1]}, + {"id": "N3", "route": "command", "name": "ImageMagick 紅色圖", + "setup": "rm -f /home/bot/bench/red.png; mkdir -p /home/bot/bench", + "ask": "幫我在你的電腦上做一張 200×100 像素的紅色 PNG 圖片,存成 ~/bench/red.png,再告訴我圖片的尺寸。", + "check": lambda dh, ans: dx("identify -format '%wx%h ' ~/bench/red.png && convert ~/bench/red.png -format '%[pixel:p{10,10}]' info:", dh)[1].replace(" ", "").lower() in ("200x100srgb(255,0,0)", "200x100red")}, + {"id": "N4", "route": "browser", "name": "Web components 設定頁", + "setup": "mkdir -p /home/bot/bench/comp && cat > /home/bot/bench/comp/index.html <<'EOF'\n" + COMPONENTS + "\nEOF\n" + "pkill -f '^python3 -m http.server 8771'; sleep 0.5; cd /home/bot/bench/comp && (su bot -c 'setsid python3 -m http.server 8771 --bind 127.0.0.1 >/dev/null 2>&1 &'); " + "for i in 1 2 3 4 5 6 7 8 9 10; do curl -s -o /dev/null http://127.0.0.1:8771/ && break; sleep 0.5; done", + "ask": "到 http://127.0.0.1:8771 把深色模式打開、語言改成日本語,按儲存,告訴我頁面上顯示的代碼。", + "check": lambda dh, ans: "DJ7Q2" in ans}, +] + ROUTE = [("command", ("shell", "read_file", "write_file", "edit_file", "list_dir", "search", "read_terminal", "write_terminal")), ("screen", ("computer_use_",)), ("browser", ("browser_", "web_fetch"))] @@ -187,7 +227,7 @@ def main(): if os.path.realpath(a.data).startswith(real): sys.exit("--data must be a scratch copy, not the real data folder") want = {t.strip() for t in a.tasks.split(",") if t.strip()} - tasks = [t for t in TASKS if not want or t["id"] in want] + tasks = [t for t in TASKS + HELDOUT if t["id"] in want] if want else TASKS results = json.load(open(a.out)) if os.path.exists(a.out) else [] env = dict(os.environ, ANYBOT_DATA_DIR=a.data, ANYBOT_ASK_SECS=str(a.secs)) kept_skills = [] diff --git a/src/computer.rs b/src/computer.rs index 58fb026..d800941 100644 --- a/src/computer.rs +++ b/src/computer.rs @@ -19,7 +19,7 @@ pub const NAMES: [&str; 12] = ["computer_use_screenshot", "computer_use_zoom", " pub const SETTLE_MS: u64 = 500; /// Most actions one `computer_use_batch` call may carry (Anthropic's computer_batch guidance: /// short self-contained sequences, one picture at the end). -pub const MAX_BATCH: usize = 8; +pub const MAX_BATCH: usize = 16; /// A batch step's short action name → the tool it runs. Screen reads, apps and permissions stay /// single steps on purpose: a batch is for input you already planned from the current picture. @@ -293,7 +293,7 @@ pub fn specs_for(computers: &[String], default: &str, chosen: bool) -> Vec Vec