hkblockchaintechnology commited on
Commit
dc70429
·
verified ·
1 Parent(s): ec47130

Notebook: 2.0 card text

Browse files
Files changed (1) hide show
  1. tiny_computer_agent_app.py +32 -18
tiny_computer_agent_app.py CHANGED
@@ -135,7 +135,7 @@ def readme():
135
  ```bash
136
  python -m pip install -e ".[desktop,ocr,dev]"
137
  pytest tests -q
138
- # 227 passed, 2 skipped in 18.7s (that run was 0.3.0; 2.0 has grown this to 284)
139
  ```
140
 
141
  The two skips are the live-desktop tests. Give them a display and they run for real:
@@ -307,7 +307,7 @@ def readme():
307
  `warning: no text was found on screen, so the index is 96 numbered grid cells and the
308
  agent is choosing blind` — instead of silently guessing.
309
 
310
- **284 tests pass**, including real OCR over a real image and (opt-in) live-desktop tests
311
  that click a real button.
312
 
313
  ## Verified on real Windows
@@ -355,7 +355,7 @@ def readme():
355
 
356
  None of the three failures in the first row is a harness defect: two are
357
  `ModuleNotFoundError: numpy` and the third is the guard bug documented below. With the
358
- OCR engine installed, the same suite exits **0**. (Those Windows counts predate `trace.py` and 2.0; the harness suite has since grown to 284 tests.)
359
 
360
  **The emulated-OCR caveat.** onnxruntime requires AVX2, and QEMU's software emulation of
361
  AVX2 is roughly two orders of magnitude slower than native. A suite that finishes in 17
@@ -381,7 +381,7 @@ def readme():
381
 
382
  ## The test suite, in full
383
 
384
- `pytest tests` collects **284 tests**. 282 run headless — no display, no network, no
385
  weights. The last 2 are the opt-in live-desktop tests, skipped unless
386
  `TINY_COMPUTER_AGENT_LIVE_TEST=1`. On a box without PyGObject, two of the 282 *fail* rather
387
  than skip: they assert the AT-SPI reader is reachable, and that is the honest outcome.
@@ -397,19 +397,22 @@ def readme():
397
  | `tests/test_verify.py` | 7 | success is only claimed when a verifier can actually see it |
398
  | `tests/test_safety.py` | 11 | deny lists, the kill switch, the blind-grid-click guard |
399
  | `tests/test_grid_fallback.py` | 11 | the fallback index announces itself instead of guessing |
400
- | `tests/test_desktop.py` | 10 | display detection, the preflight checks, `doctor` |
401
- | `tests/test_cli.py` | 16 | the command line: `--doctor`, `--image`, `--live`, and the 2.0 `skills` / `batch` subcommands |
402
  | `tests/test_trace.py` | 28 | traces: a run recorded with no pixels, replayed against another brain, and scored against ground truth |
403
  | `tests/test_models.py` | 7 | the model backends: lazy loading, device choice, honest refusals |
404
  | `tests/test_api_surface.py` | 4 | the public API is a promise: everything advertised is importable, and nothing public is left out |
405
  | `tests/test_decoding.py` | 24 | the mask, the answer space, the retry ladder, the vote - and that an echo is refused |
406
- | `tests/test_accessibility.py` | 26 | role filtering, the coordinate contract, the fallback chain, and real AT-SPI |
407
  | `tests/test_diff.py` | 8 | what changed between two frames: added, removed, moved, and the verifier that remembers |
408
  | `tests/test_stepwise.py` | 11 | begin / step / pause / resume, and that it equals the batch loop |
409
  | `tests/test_ocr_guard.py` | 4 | the OCR guard really skips with no engine - the guard that never fired |
410
- | `tests/test_gates.py` | 8 | the operator's yes: whitelists, ask-once gates, and a refusal that is a step |
411
  | `tests/test_skills.py` | 17 | only a verified run becomes a skill; re-grounding by label; aiming at nothing raises |
412
  | `tests/test_runner.py` | 10 | a queue, a JSONL resume file, and a report counts what was verified |
 
 
 
413
  | `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 |
414
 
415
  ```bash
@@ -424,7 +427,7 @@ def readme():
424
  pip install -e ".[ocr]" # labels from pixels (RapidOCR: no system binary)
425
  pip install -e ".[desktop,ocr]" # + real capture and real input
426
  pip install -e ".[vision,ocr]" # + the tiny model brains
427
- pytest # 284 tests, no display or network needed
428
  ```
429
 
430
  The accessibility detector needs system packages rather than an extra:
@@ -540,6 +543,8 @@ def readme():
540
  | `skills.py` | **2.0** - Skills: a *verified* run written down once, replayed by `SkillBrain` with no model. Labels, never coordinates |
541
  | `gates.py` | **2.0** - Approval gates: `AllowOnlyLabels`, `InteractiveGate` (yes / no / always / never), `AllOf` / `AnyOf`. A refusal is a step |
542
  | `runner.py` | **2.0** - `TaskRunner`: a queue of goals, a JSONL resume file, and a `RunReport` that counts what was *verified* |
 
 
543
  | `showcase.py` | The capability gallery: one real screenshot per capability, checked against the public API |
544
  | `measure_vlm.py` | Measures the four ways to ask a model, on a real screen, and prints the table |
545
  | `evaluate_daily.py` | A day's tasks against a real app, verified by the app's own log |
@@ -590,9 +595,10 @@ def readme():
590
  reads `last action: Save` afterwards, and the app wrote `Save` to its marker file.
591
  `--detector best` tries the tree first, then OCR, then the numbered grid.
592
 
593
- **Honest limits.** AT-SPI is Linux-only here; **UI Automation is not implemented**, and
594
- `accessibility_available("uia")` says exactly that rather than pretending - so an agent
595
- on Windows keeps using OCR. Tk barely publishes a tree and a canvas publishes none,
 
596
  which is why this is a detector and not a replacement.
597
 
598
  ## Can it do a day's work?
@@ -646,7 +652,7 @@ def readme():
646
 
647
  ## Capability gallery
648
 
649
- **74 capabilities, one screenshot each - and 173 of the package's 180 pre-2.0 public callables (functions, methods, classes and protocols) appear in at least one of them**, together with 10 of its public constants. The 2.0 additions are not pictured yet: **84 new public callables** (skills, approval gates, the batch runner and the structural diff) plus four new CLI entry points. The counts are read off `gallery/index.json`, which records what each picture shows.
650
 
651
  Nothing here is a mock-up. Each picture is produced by [`showcase.py`](showcase.py): a command or a call is run for real, and its actual output - or the real desktop it acted on - is what you see. The desktop shots are real screen captures on a real X server (Xvfb, 1280x800), including a real mouse click verified by the target application's own reaction.
652
 
@@ -1274,15 +1280,15 @@ def readme():
1274
  **Works:** real capture, a real OCR index with coordinates that land on the right pixel,
1275
  a real click an app reacts to, verified success, the closed vocabulary, the policy gates,
1276
  the no-progress guard, echo detection, the doctor, the CLI, portable traces that score a brain's choices offline, skills learned from verified runs,
1277
- a resumable task runner, operator approval gates, 284 tests, a 256M VLM that
1278
  reads a button label from pixels on a clean screenshot — and the same suite passing inside
1279
  a real Windows Server 2022 guest with no KVM (109 passed, exit 0, with the OCR-inference
1280
  tests excluded as impractically slow under emulation).
1281
 
1282
  **Does not work yet:** reliability on a *live* screen. The 256M VLM echoed the prompt
1283
- there; the 0.5B text planner picks wrong actions; the accessibility-tree detector is not
1284
- implemented, so labels come from OCR only; and the harness still trusts a model's `done`
1285
- when no verifier is given.
1286
 
1287
  ## Roadmap
1288
 
@@ -1307,7 +1313,15 @@ def readme():
1307
  - [x] **2.0** Operator approval gates - a label whitelist, or ask before every action
1308
  - [x] **2.0** A resumable task queue with a report, and structural verification of "it worked"
1309
  - [x] **2.0** `skills` and `batch` subcommands, and an example queue at `tasks/day.json`
1310
- - [ ] A gallery run that pictures the 2.0 additions: the 84 new public callables have no screenshot yet
 
 
 
 
 
 
 
 
1311
  - [ ] **Verify UI Automation** (Windows) against a real Windows desktop. The reader and the
1312
  detector are implemented and unit-tested against a synthetic control tree, and
1313
  `accessibility_available("uia")` reports the truth on any machine - but no Windows
 
135
  ```bash
136
  python -m pip install -e ".[desktop,ocr,dev]"
137
  pytest tests -q
138
+ # 227 passed, 2 skipped in 18.7s (that run was 0.3.0; 2.0 has grown this to 327)
139
  ```
140
 
141
  The two skips are the live-desktop tests. Give them a display and they run for real:
 
307
  `warning: no text was found on screen, so the index is 96 numbered grid cells and the
308
  agent is choosing blind` — instead of silently guessing.
309
 
310
+ **327 tests collect** - 315 pass, 12 skip for want of a display or an AT-SPI typelib - including real OCR over a real image and (opt-in) live-desktop tests
311
  that click a real button.
312
 
313
  ## Verified on real Windows
 
355
 
356
  None of the three failures in the first row is a harness defect: two are
357
  `ModuleNotFoundError: numpy` and the third is the guard bug documented below. With the
358
+ OCR engine installed, the same suite exits **0**. (Those Windows counts predate `trace.py` and 2.0; the harness suite has since grown to 327 tests.)
359
 
360
  **The emulated-OCR caveat.** onnxruntime requires AVX2, and QEMU's software emulation of
361
  AVX2 is roughly two orders of magnitude slower than native. A suite that finishes in 17
 
381
 
382
  ## The test suite, in full
383
 
384
+ `pytest tests` collects **327 tests**. 325 run headless — no display, no network, no
385
  weights. The last 2 are the opt-in live-desktop tests, skipped unless
386
  `TINY_COMPUTER_AGENT_LIVE_TEST=1`. On a box without PyGObject, two of the 282 *fail* rather
387
  than skip: they assert the AT-SPI reader is reachable, and that is the honest outcome.
 
397
  | `tests/test_verify.py` | 7 | success is only claimed when a verifier can actually see it |
398
  | `tests/test_safety.py` | 11 | deny lists, the kill switch, the blind-grid-click guard |
399
  | `tests/test_grid_fallback.py` | 11 | the fallback index announces itself instead of guessing |
400
+ | `tests/test_desktop.py` | 12 | display detection, the preflight checks, `doctor` |
401
+ | `tests/test_cli.py` | 22 | the command line: `--doctor`, `--image`, `--live`, and the 2.0 `skills` / `batch` subcommands |
402
  | `tests/test_trace.py` | 28 | traces: a run recorded with no pixels, replayed against another brain, and scored against ground truth |
403
  | `tests/test_models.py` | 7 | the model backends: lazy loading, device choice, honest refusals |
404
  | `tests/test_api_surface.py` | 4 | the public API is a promise: everything advertised is importable, and nothing public is left out |
405
  | `tests/test_decoding.py` | 24 | the mask, the answer space, the retry ladder, the vote - and that an echo is refused |
406
+ | `tests/test_accessibility.py` | 27 | role filtering, the coordinate contract, the fallback chain, and real AT-SPI |
407
  | `tests/test_diff.py` | 8 | what changed between two frames: added, removed, moved, and the verifier that remembers |
408
  | `tests/test_stepwise.py` | 11 | begin / step / pause / resume, and that it equals the batch loop |
409
  | `tests/test_ocr_guard.py` | 4 | the OCR guard really skips with no engine - the guard that never fired |
410
+ | `tests/test_gates.py` | 14 | the operator's yes: whitelists, ask-once gates, and a refusal that is a step |
411
  | `tests/test_skills.py` | 17 | only a verified run becomes a skill; re-grounding by label; aiming at nothing raises |
412
  | `tests/test_runner.py` | 10 | a queue, a JSONL resume file, and a report counts what was verified |
413
+ | `tests/test_watchdog.py` | 12 | a hung call becomes a named step instead of a stall - and the thread it leaves behind is admitted |
414
+ | `tests/test_audit.py` | 12 | the chain verifies, and editing, deleting or reordering a line is caught by number |
415
+ | `tests/test_atspi_guard.py` | 4 | the AT-SPI guard really skips without the typelib - the same trap as the OCR guard |
416
  | `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 |
417
 
418
  ```bash
 
427
  pip install -e ".[ocr]" # labels from pixels (RapidOCR: no system binary)
428
  pip install -e ".[desktop,ocr]" # + real capture and real input
429
  pip install -e ".[vision,ocr]" # + the tiny model brains
430
+ pytest # 327 tests, no display or network needed
431
  ```
432
 
433
  The accessibility detector needs system packages rather than an extra:
 
543
  | `skills.py` | **2.0** - Skills: a *verified* run written down once, replayed by `SkillBrain` with no model. Labels, never coordinates |
544
  | `gates.py` | **2.0** - Approval gates: `AllowOnlyLabels`, `InteractiveGate` (yes / no / always / never), `AllOf` / `AnyOf`. A refusal is a step |
545
  | `runner.py` | **2.0** - `TaskRunner`: a queue of goals, a JSONL resume file, and a `RunReport` that counts what was *verified* |
546
+ | `watchdog.py` | **2.0** - `Watchdog`: a deadline on `decide` / `execute` / `capture`, so a hung call is a step with a reason, not a stall |
547
+ | `audit.py` | **2.0** - `AuditLog`: an append-only, hash-chained record of a run. Edit, delete or reorder a line and `verify_audit` names it |
548
  | `showcase.py` | The capability gallery: one real screenshot per capability, checked against the public API |
549
  | `measure_vlm.py` | Measures the four ways to ask a model, on a real screen, and prints the table |
550
  | `evaluate_daily.py` | A day's tasks against a real app, verified by the app's own log |
 
595
  reads `last action: Save` afterwards, and the app wrote `Save` to its marker file.
596
  `--detector best` tries the tree first, then OCR, then the numbered grid.
597
 
598
+ **Honest limits.** AT-SPI is Linux-only here. UI Automation *is* implemented - `UiaReader` and
599
+ `UiaDetector`, unit-tested against a synthetic control tree - but it has never run against a
600
+ real Windows desktop, and `accessibility_available("uia")` reports the truth on any machine
601
+ rather than pretending, so an agent on Windows still falls back to OCR. Tk barely publishes a tree and a canvas publishes none,
602
  which is why this is a detector and not a replacement.
603
 
604
  ## Can it do a day's work?
 
652
 
653
  ## Capability gallery
654
 
655
+ **74 capabilities, one screenshot each - and 163 of the package's 270 public callables (functions, methods, classes and protocols) appear in at least one of them**, together with 8 of its 26 public constants. **Not yet pictured: 107 callables** - 103 in the 2.0 operator layer (skills 29, the batch runner 20, approval gates 19, the structural diff 14, the audit log 13, the watchdog 8) and four CLI entry points. They are covered by tests rather than by pictures, and `showcase.py` prints the exact list. The counts are read off `gallery/index.json`, which records what each picture shows, and checked against the package by `showcase.api_surface()`.
656
 
657
  Nothing here is a mock-up. Each picture is produced by [`showcase.py`](showcase.py): a command or a call is run for real, and its actual output - or the real desktop it acted on - is what you see. The desktop shots are real screen captures on a real X server (Xvfb, 1280x800), including a real mouse click verified by the target application's own reaction.
658
 
 
1280
  **Works:** real capture, a real OCR index with coordinates that land on the right pixel,
1281
  a real click an app reacts to, verified success, the closed vocabulary, the policy gates,
1282
  the no-progress guard, echo detection, the doctor, the CLI, portable traces that score a brain's choices offline, skills learned from verified runs,
1283
+ a resumable task runner, operator approval gates, a watchdog that refuses to wait forever rather than stalling silently, a hash-chained audit log, 327 tests, a 256M VLM that
1284
  reads a button label from pixels on a clean screenshot — and the same suite passing inside
1285
  a real Windows Server 2022 guest with no KVM (109 passed, exit 0, with the OCR-inference
1286
  tests excluded as impractically slow under emulation).
1287
 
1288
  **Does not work yet:** reliability on a *live* screen. The 256M VLM echoed the prompt
1289
+ there; the 0.5B text planner picks wrong actions; UI Automation has never been exercised
1290
+ against a real Windows desktop, so an agent there still reads labels from OCR; and the
1291
+ harness still trusts a model's `done` when no verifier is given.
1292
 
1293
  ## Roadmap
1294
 
 
1313
  - [x] **2.0** Operator approval gates - a label whitelist, or ask before every action
1314
  - [x] **2.0** A resumable task queue with a report, and structural verification of "it worked"
1315
  - [x] **2.0** `skills` and `batch` subcommands, and an example queue at `tasks/day.json`
1316
+ - [x] **2.0** A watchdog: a per-call and whole-episode deadline, so a call that never returns
1317
+ becomes a named step instead of a console that looks like it is thinking
1318
+ - [x] **2.0** An audit log: an append-only, hash-chained record of a run, and `--verify-audit`
1319
+ to check it - so the evidence survives the container that produced it
1320
+ - [x] **2.0** `--gate`, `--audit` and `--verify-audit` on the command line, and the shared
1321
+ AT-SPI guard, so a machine without the typelib skips rather than failing
1322
+ - [ ] A gallery run that pictures the 2.0 additions: **107 of the package's 270 public callables**
1323
+ have no screenshot yet - 103 in the operator layer and four CLI entry points. Adding the
1324
+ entries to `showcase_catalog.py` is what closes it
1325
  - [ ] **Verify UI Automation** (Windows) against a real Windows desktop. The reader and the
1326
  detector are implemented and unit-tested against a synthetic control tree, and
1327
  `accessibility_available("uia")` reports the truth on any machine - but no Windows