Skip to content

#161 lada: surface all per-task progress metrics to the Hub (openclaw self-select)#162

Merged
AlvinShenSSW merged 4 commits into
mainfrom
afk/161-lada-hub-metrics
Jul 2, 2026
Merged

#161 lada: surface all per-task progress metrics to the Hub (openclaw self-select)#162
AlvinShenSSW merged 4 commits into
mainfrom
afk/161-lada-hub-metrics

Conversation

@AlvinShenSSW

Copy link
Copy Markdown
Owner

Closes #161.

What

Lada capture mode already parses the full per-task progress set — percent, elapsed, processed_frames, eta, remaining_frames, fps, current_file — into MonitorStatus.metrics, which is serialized verbatim into /status and stored whole in hub.db.status_log. The agent→hub transport was already complete. The gap was consumer-side discoverability: openclaw's guide documented only the queue_* fields, and status.md rendered only queue counts, so the data was present in the JSON but nothing selected it.

This formally delivers those fields to the Hub side — no wire/protocol change.

Changes

  • status.md (status_md.py): append per-task essentials (percent · ETA · fps) to the Lada line. Additive — the legacy X/Y done (Z left) and | file | substrings the V2 scrapers (idle-detector-v2 / daily-report) match stay byte-identical. Each field guarded (_is_num, 0<=percent<=100, _inlined eta); capture-off Lada renders exactly as before; hard-bad state still shows state, not stale progress.
  • openclaw-integration.md: field-reference table + reader example + status.md sample now document every per-task field, each flagged capture-mode only (lada_capture_progress: true).
  • Tests: test_lada.py locks the exact metrics contract (names/types) via the real reader path so a future rename can't silently drop a field from the Hub, and asserts idle snapshots omit progress; test_status_md.py covers render, capture-off no-regression, NaN/n/a/out-of-range dropping, eta sanitize, and error-state.

Not changed

  • No lada.py parsing change (all fields already emitted).
  • No protocol / hub-store / hub.db change — metrics is an open dict, already forwarded.

Tests

uv run --locked pytest → all green. uv lock --check clean. ruff clean.

Design

docs/specs/2026-07-02-161-lada-hub-metrics-design.md.

Review trail (/afk)

Claude implement + TDD. External gates run automatically: Codex 外门 then Kimi 终审. Left open awaiting operator merge (leave-open policy).

AlvinShenSSW and others added 4 commits July 2, 2026 23:58
… self-select)

Lada capture mode already parses percent/eta/elapsed/processed_frames/
remaining_frames/fps/current_file into MonitorStatus.metrics, which rides
/status → hub.db verbatim — the transport was already complete. The gap was
consumer-side discoverability.

- status.md: render per-task essentials (percent · ETA · fps) appended to the
  Lada line, additively so the legacy "X/Y done (Z left)" / "| file |" substrings
  the V2 scrapers match stay byte-identical. Each field guarded (_is_num /
  0..100 / _inline eta); capture-off Lada renders exactly as before.
- openclaw-integration.md: field table + reader example + status.md sample now
  document every per-task field, flagged capture-mode-only.
- Tests: lock the exact metrics contract (names/types) via the real reader path;
  status.md render/no-regression/sanitize/bad-state coverage.

No protocol/hub-store change (metrics is an open dict, already forwarded).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A managed Lada that supplies I/O via lada_extra_args (--input/--output) instead
of the folder fields has capture-mode progress but no queue_total (_queue_counts
reads only the folder fields). Nesting progress under queue_total hid it for that
supported config. Assemble the Lada line from three independent, space-joined
pieces (queue seg · current file · progress); byte-identical when all present,
still renders progress when only that is available.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Assert set(_progress) equals the expected per-task keys so a future rename
fails the test instead of silently dropping a field from the Hub — matching the
design doc's intent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@AlvinShenSSW

Copy link
Copy Markdown
Owner Author

Review trail (/afk — Claude-driven)

Both external reviews ran (reviewer ≠ implementer):

  • Codex 外门 (outer gate): round 1 found one P2 — status.md progress was nested under queue_total, hiding per-task progress for a supported config that supplies I/O via lada_extra_args (no folder-derived queue count). Fixed by decoupling the Lada line into three independent space-joined pieces (queue · file · progress); legacy substrings stay byte-identical. Round 2: CLEAN ("additive, guarded against malformed metrics, covered by focused tests; no discrete regression").
  • Kimi 终审 (final): VERDICT: PASS. 2 LOW nits, no blockers. Applied nit Define TaskPaw Web App architecture and migration scope #1 (lock the exact parsed metric key set so a rename fails the contract test). Nit Create a stable HTTP API contract for the web app #2 (a slightly broad "fps" not in line assertion) accepted as-is — fps only originates from this code path.

CI green. Left open awaiting operator merge (leave-open policy).

@AlvinShenSSW AlvinShenSSW merged commit c0d5acf into main Jul 2, 2026
7 checks passed
@AlvinShenSSW AlvinShenSSW deleted the afk/161-lada-hub-metrics branch July 2, 2026 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lada: 把逐任务进度全部字段同步到 Hub(percent/eta/frames/fps),供 openclaw 自选

1 participant