Kaynağa Gözat

docs: record round stats todo

zhenyu.hu 3 hafta önce
ebeveyn
işleme
c3947d1f3e
2 değiştirilmiş dosya ile 105 ekleme ve 1 silme
  1. 104 0
      docs/plans/todo-12-round-stats.md
  2. 1 1
      docs/plans/todos.md

+ 104 - 0
docs/plans/todo-12-round-stats.md

@@ -0,0 +1,104 @@
+# Todo 12 Structured Round Stats Plan
+
+**Status:** done
+
+## Goal
+
+Move round statistics to structured backend events for token counts, cached tokens, TTFT, elapsed time, and per-turn summaries.
+
+## Why
+
+The original requirement calls for chat-window round statistics: token count, cache hits, TTFT, and total elapsed time. The MVP UI calculates TTFT/elapsed in the browser and only displays usage chunks. That is useful visually, but not enough for reproducible Agent debugging. Backend-emitted stats should become part of the WebSocket event stream.
+
+## Scope
+
+This todo covers:
+
+- Backend timing collection inside `DebugRuntime.run()`.
+- Structured `round_stats` WebSocket messages.
+- Usage aggregation from streamed `usage` items.
+- UI rendering from backend `round_stats` events.
+- Tests for deterministic stats using an injectable clock.
+
+This todo does not cover:
+
+- Persistent run history.
+- Multi-run comparison dashboards.
+- Provider-side detailed cache diagnostics beyond available `cached_tokens`.
+- Cost estimation.
+
+## Files
+
+- Modify: `src/agent_lab/application/runtime.py`
+- Modify/add application contracts or domain models only if needed.
+- Modify: `src/agent_lab/presentation/static/app.js`
+- Modify/add tests, preferably `tests/test_debug_runtime.py` and `tests/test_websocket_api.py`.
+- Do not modify: `docs/plans/todos.md`.
+
+## Design
+
+Add an injectable monotonic clock to `DebugRuntime`:
+
+```python
+Clock = Callable[[], float]
+DebugRuntime(chat_client, queues=None, registry=None, clock=time.perf_counter)
+```
+
+Track one `round_index` per ChatAgent call. For each round:
+
+- `started_at = clock()`;
+- first message delta sets `ttft_ms` if unset;
+- usage item updates `prompt_tokens`, `completion_tokens`, `total_tokens`, and `cached_tokens`;
+- after the ChatAgent stream completes, emit:
+
+```json
+{
+  "type": "round_stats",
+  "round_index": 1,
+  "ttft_ms": 123,
+  "elapsed_ms": 456,
+  "prompt_tokens": 10,
+  "completion_tokens": 20,
+  "total_tokens": 30,
+  "cached_tokens": 5,
+  "had_event": true
+}
+```
+
+Keep existing `usage` messages for compatibility, but the UI should prefer `round_stats` for the stats panel. If no token arrives, `ttft_ms` can be `null`.
+
+## Steps
+
+1. Add failing runtime tests for:
+   - `round_stats` is emitted after a model turn;
+   - TTFT and elapsed are derived from the injected clock;
+   - usage totals are included;
+   - multi-turn event handoff emits one stats object per ChatAgent call.
+2. Refactor `DebugRuntime` to collect and emit stats through the existing output queue.
+3. Update `app.js` to update stats from `round_stats` messages and keep current browser timing only as a fallback before stats arrives.
+4. Add or update static JS tests/assertions for `round_stats` handling.
+5. Run:
+
+```bash
+uv run pytest tests/test_debug_runtime.py tests/test_websocket_api.py
+uv run pytest
+```
+
+6. If successful, commit implementation files only with:
+
+```bash
+git commit -m "feat: emit structured round stats"
+```
+
+## Verification
+
+Result:
+
+- `uv run pytest tests/test_debug_runtime.py tests/test_websocket_api.py` passed: 23 tests, 1 existing Starlette deprecation warning.
+- `uv run pytest` passed: 28 tests, 1 existing Starlette deprecation warning.
+
+## Evaluation
+
+- Backend emits deterministic `round_stats` messages with round index, TTFT, elapsed time, token totals, cached tokens, and event presence.
+- UI handles backend `round_stats` and keeps browser-side timing as a fallback.
+- The original MVP requirement for chat-window round statistics is covered.

+ 1 - 1
docs/plans/todos.md

@@ -29,4 +29,4 @@
 | 9 | done | `docs/plans/todo-9-explicit-runtime-queues.md` | Refactor runtime internals to explicit input, output, and event queues while preserving the WebSocket stream contract. | Tests prove ChatAgent consumes input queue, EventAgent consumes event queue, and output queue drives streamed responses. |
 | 10 | done | `docs/plans/todo-10-tool-registry-management.md` | Replace the single hardcoded EventAgent tool checkbox with a backend tool registry and UI-managed loaded tools. | Tests prove available tools are listed by API and selected tools control EventAgent behavior. |
 | 11 | done | `docs/plans/todo-11-prompt-workspace.md` | Improve prompt/pre-message editing with browser-side persistence and reusable prompt sets. | UI tests or focused JS tests prove prompts persist and can be restored. |
-| 12 | pending | `docs/plans/todo-12-round-stats.md` | Move round statistics to structured backend events for token counts, cached tokens, TTFT, elapsed time, and per-turn summaries. | Tests prove backend emits deterministic stats events and UI renders them. |
+| 12 | done | `docs/plans/todo-12-round-stats.md` | Move round statistics to structured backend events for token counts, cached tokens, TTFT, elapsed time, and per-turn summaries. | `uv run pytest tests/test_debug_runtime.py tests/test_websocket_api.py`; `uv run pytest`. |