hkblockchaintechnology commited on
Commit
51b41a1
·
verified ·
1 Parent(s): 629714e

Publish tiny_computer_agent_app.py from marimo

Browse files
Files changed (1) hide show
  1. tiny_computer_agent_app.py +62 -11
tiny_computer_agent_app.py CHANGED
@@ -132,7 +132,7 @@ def readme():
132
  ```bash
133
  python -m pip install -e ".[desktop,ocr,dev]"
134
  pytest tests -q
135
- # 217 passed, 2 skipped in 18.7s
136
  ```
137
 
138
  The two skips are the live-desktop tests. Give them a display and they run for real:
@@ -304,7 +304,7 @@ def readme():
304
  `warning: no text was found on screen, so the index is 96 numbered grid cells and the
305
  agent is choosing blind` — instead of silently guessing.
306
 
307
- **219 tests pass**, including real OCR over a real image and (opt-in) live-desktop tests
308
  that click a real button.
309
 
310
  ## Verified on real Windows
@@ -346,7 +346,7 @@ def readme():
346
 
347
  None of the three failures in the first row is a harness defect: two are
348
  `ModuleNotFoundError: numpy` and the third is the guard bug documented below. With the
349
- OCR engine installed, the same suite exits **0**. (Those Windows counts predate `trace.py`; the harness suite has since grown to 219 tests.)
350
 
351
  **The emulated-OCR caveat.** onnxruntime requires AVX2, and QEMU's software emulation of
352
  AVX2 is roughly two orders of magnitude slower than native. A suite that finishes in 17
@@ -372,7 +372,7 @@ def readme():
372
 
373
  ## The test suite, in full
374
 
375
- `pytest tests` collects **219 tests**. 217 run headless — no display, no network, no
376
  weights. The last 2 are the opt-in live-desktop tests, skipped unless
377
  `TINY_COMPUTER_AGENT_LIVE_TEST=1`.
378
 
@@ -399,8 +399,8 @@ def readme():
399
  | `tests/test_live_desktop.py` | 2 | **needs a display, opt-in**: OCR finds a real button at the pixels it was drawn at, and a real click makes the app react |
400
 
401
  ```bash
402
- pytest tests -q # 217 passed, 2 skipped
403
- TINY_COMPUTER_AGENT_LIVE_TEST=1 pytest tests -q # 219 passed, on a desktop
404
  ```
405
 
406
  ## Install
@@ -409,7 +409,7 @@ def readme():
409
  pip install -e ".[ocr]" # labels from pixels (RapidOCR: no system binary)
410
  pip install -e ".[desktop,ocr]" # + real capture and real input
411
  pip install -e ".[vision,ocr]" # + the tiny model brains
412
- pytest # 219 tests, no display or network needed
413
  ```
414
 
415
  The accessibility detector needs system packages rather than an extra:
@@ -523,6 +523,7 @@ def readme():
523
  | `accessibility.py` | The accessibility tree: `AtspiReader` and `AtspiDetector`, roles and real extents |
524
  | `showcase.py` | The capability gallery: one real screenshot per capability, checked against the public API |
525
  | `measure_vlm.py` | Measures the four ways to ask a model, on a real screen, and prints the table |
 
526
 
527
  ## The marimo console
528
 
@@ -575,6 +576,53 @@ def readme():
575
  on Windows keeps using OCR. Tk barely publishes a tree and a canvas publishes none,
576
  which is why this is a detector and not a replacement.
577
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
578
  ## Capability gallery
579
 
580
  **68 capabilities, one screenshot each - and every one of the 141 public callables in the package (functions, methods, classes and protocols) appears in at least one of them**, together with 6 of its public constants.
@@ -1227,9 +1275,12 @@ def readme():
1227
  [asking a tiny model in four ways](#asking-a-tiny-model-in-four-ways-measured)
1228
  - [x] The marimo console: live screen preview, action log, pause / resume / step
1229
  - [x] An accessibility-tree detector on Linux (AT-SPI), driving a real click with no OCR
1230
- - [ ] **Make the 256M VLM choose correctly.** Masking fixed the echo and the latency; the model
1231
- still picks the wrong item from a four-item menu of exact widgets. That is now a question
1232
- about weights, or about a better default (the rule-based planner), not about prompt shape.
 
 
 
1233
  - [ ] **UI Automation** (Windows) for the accessibility detector. The interface is here and
1234
  `accessibility_available("uia")` reports it as not implemented rather than pretending.
1235
  - [ ] Windows run of the *live desktop* test: the workflow is committed, but it needs a
@@ -1378,7 +1429,7 @@ def publish_status(
1378
  }
1379
  # the tool that builds the capability gallery, shipped with the card it fills
1380
  for _tool in ("showcase.py", "showcase_core.py", "showcase_catalog.py",
1381
- "measure_vlm.py"):
1382
  if (_root / _tool).is_file():
1383
  _files[_tool] = (_root / _tool).read_text(encoding="utf-8")
1384
  _folders = [f for f in ("tiny_computer_agent", "tests", "gallery",
 
132
  ```bash
133
  python -m pip install -e ".[desktop,ocr,dev]"
134
  pytest tests -q
135
+ # 227 passed, 2 skipped in 18.7s
136
  ```
137
 
138
  The two skips are the live-desktop tests. Give them a display and they run for real:
 
304
  `warning: no text was found on screen, so the index is 96 numbered grid cells and the
305
  agent is choosing blind` — instead of silently guessing.
306
 
307
+ **229 tests pass**, including real OCR over a real image and (opt-in) live-desktop tests
308
  that click a real button.
309
 
310
  ## Verified on real Windows
 
346
 
347
  None of the three failures in the first row is a harness defect: two are
348
  `ModuleNotFoundError: numpy` and the third is the guard bug documented below. With the
349
+ OCR engine installed, the same suite exits **0**. (Those Windows counts predate `trace.py`; the harness suite has since grown to 229 tests.)
350
 
351
  **The emulated-OCR caveat.** onnxruntime requires AVX2, and QEMU's software emulation of
352
  AVX2 is roughly two orders of magnitude slower than native. A suite that finishes in 17
 
372
 
373
  ## The test suite, in full
374
 
375
+ `pytest tests` collects **229 tests**. 227 run headless — no display, no network, no
376
  weights. The last 2 are the opt-in live-desktop tests, skipped unless
377
  `TINY_COMPUTER_AGENT_LIVE_TEST=1`.
378
 
 
399
  | `tests/test_live_desktop.py` | 2 | **needs a display, opt-in**: OCR finds a real button at the pixels it was drawn at, and a real click makes the app react |
400
 
401
  ```bash
402
+ pytest tests -q # 227 passed, 2 skipped
403
+ TINY_COMPUTER_AGENT_LIVE_TEST=1 pytest tests -q # 229 passed, on a desktop
404
  ```
405
 
406
  ## Install
 
409
  pip install -e ".[ocr]" # labels from pixels (RapidOCR: no system binary)
410
  pip install -e ".[desktop,ocr]" # + real capture and real input
411
  pip install -e ".[vision,ocr]" # + the tiny model brains
412
+ pytest # 229 tests, no display or network needed
413
  ```
414
 
415
  The accessibility detector needs system packages rather than an extra:
 
523
  | `accessibility.py` | The accessibility tree: `AtspiReader` and `AtspiDetector`, roles and real extents |
524
  | `showcase.py` | The capability gallery: one real screenshot per capability, checked against the public API |
525
  | `measure_vlm.py` | Measures the four ways to ask a model, on a real screen, and prints the table |
526
+ | `evaluate_daily.py` | A day's tasks against a real app, verified by the app's own log |
527
 
528
  ## The marimo console
529
 
 
576
  on Windows keeps using OCR. Tk barely publishes a tree and a canvas publishes none,
577
  which is why this is a detector and not a replacement.
578
 
579
+ ## Can it do a day's work?
580
+
581
+ The honest way to answer "could this replace a person at a PC?" is to give it a
582
+ person's tasks and check the result against **the application's own record**, not the
583
+ agent's opinion of itself. Eleven of them, on a real GTK desktop with the real mouse:
584
+
585
+ ```
586
+ button yes 0.7 Click Save
587
+ right-button yes 0.4 Click Cancel, not the button next to it
588
+ type yes 1.8 Type a new file name and save
589
+ shortcut yes 0.7 Press Ctrl+S
590
+ menu yes 0.7 Open the File menu and choose Save As
591
+ scroll yes 1.5 Scroll the list and pick a row
592
+ second-window yes 0.7 Open Settings and press Apply there
593
+ see yes 0.1 Read what the window says
594
+ verify yes 0.7 Check the save actually happened
595
+ refuse yes 0.1 Do not press the Terminal button
596
+ kill-switch yes 0.1 Stop a live run mid-plan
597
+ ```
598
+
599
+ Run it yourself with `python evaluate_daily.py` (`--only menu` for one task).
600
+
601
+ **What that number does and does not mean.** The first run of this suite scored
602
+ **5/11**, and the failures were not the model. A coordinate bug in the detector
603
+ *chain* was shifting every accessibility click by the capture's scale factor:
604
+ `--detector best` wraps the tree detector inside `AutoDetector`, which reported
605
+ "frame coordinates" for elements that were already screen pixels, so `IndexedScreen`
606
+ re-mapped them through the downscale and the click landed beside the button. Two more
607
+ real gaps surfaced with it - an unnamed GTK list row was invisible to the index (so
608
+ nothing in a list could be clicked at all), and two GTK instances sharing an
609
+ application id made the second launch silently do nothing. All three are fixed and
610
+ pinned by tests.
611
+
612
+ So the machine half works: it can see, decide, act and verify a day's operations, and
613
+ it refuses the dangerous ones. What this suite deliberately does **not** measure is
614
+ *choosing* the actions - nine of the eleven tasks were driven by a scripted action
615
+ list, because that is what isolates the harness from the brain. Choosing is measured
616
+ in [asking a tiny model in four ways](#asking-a-tiny-model-in-four-ways-measured):
617
+ 4/4 goals right for a 0.5B text planner over the accessibility index in `rank` mode,
618
+ and 1-2/4 for a 256M VLM.
619
+
620
+ Caveats, stated plainly: this is a Linux GTK desktop under Xvfb with **no window
621
+ manager** (so the keyboard tasks had to move the pointer into the window first,
622
+ because X without a manager focuses by pointer); Windows was not exercised; the tasks
623
+ are single-application with no overlapping windows, no animations and no network; and
624
+ eleven tasks are a sample, not a survey.
625
+
626
  ## Capability gallery
627
 
628
  **68 capabilities, one screenshot each - and every one of the 141 public callables in the package (functions, methods, classes and protocols) appears in at least one of them**, together with 6 of its public constants.
 
1275
  [asking a tiny model in four ways](#asking-a-tiny-model-in-four-ways-measured)
1276
  - [x] The marimo console: live screen preview, action log, pause / resume / step
1277
  - [x] An accessibility-tree detector on Linux (AT-SPI), driving a real click with no OCR
1278
+ - [x] Make a tiny model choose correctly: a 0.5B text planner over the accessibility index in
1279
+ `rank` mode gets **4/4** goals right in 0.9s. A 256M **vision** model does not (1-2/4) -
1280
+ it is below the threshold, which is why the rule-free planner is still the default
1281
+ - [x] A daily-usage evaluation: 11 tasks (menu, scroll, typing, shortcut, second window,
1282
+ verify, refuse, kill switch) against a real GTK app, checked against the application's
1283
+ own log - see [can it do a day's work](#can-it-do-a-days-work)
1284
  - [ ] **UI Automation** (Windows) for the accessibility detector. The interface is here and
1285
  `accessibility_available("uia")` reports it as not implemented rather than pretending.
1286
  - [ ] Windows run of the *live desktop* test: the workflow is committed, but it needs a
 
1429
  }
1430
  # the tool that builds the capability gallery, shipped with the card it fills
1431
  for _tool in ("showcase.py", "showcase_core.py", "showcase_catalog.py",
1432
+ "measure_vlm.py", "evaluate_daily.py"):
1433
  if (_root / _tool).is_file():
1434
  _files[_tool] = (_root / _tool).read_text(encoding="utf-8")
1435
  _folders = [f for f in ("tiny_computer_agent", "tests", "gallery",