Todo 50 Comparable Model and Tool Metrics Plan
Status: in_progress
Goal
Make dual_agent and chat_agent_tools directly comparable without double-counting model tokens, parallel latency, or replayed events.
Metric Contract
- Keep the existing
/api/sessions/{id}/usage endpoint and calls / turns / session shape.
- Extend the persisted call ledger with:
agent: chat_agent, event_agent, or event_kernel;
call_kind: chat_completion, argument_fallback, or tool_execution;
event_id, event_name, used_fallback, and tool_latency_ms;
- deterministic
metric_key for idempotent persistence.
- Derive
tool_invocation_mode from the immutable session config instead of duplicating it per row.
- Add independent
turns.wall_time_ms, measured once from the runtime monotonic clock.
- Token totals include only real model calls. Tool rows carry zero tokens.
- Turn/session wall time is calculated only from
turns.wall_time_ms; model elapsed and concurrent tool latencies remain per-call diagnostics and are never summed as wall time.
- Persist only logical event results (
deduplicated_from is None) so coalesced/replayed clones do not inflate tool or fallback counts.
Runtime Scope
- ChatAgent records model TTFT from the first provider stream item while preserving visible-text TTFT in existing round events.
- EventAgent consumes the complete fallback stream so trailing usage is retained, and exposes one model-call metric per fallback attempt, including failed resolution attempts.
- Event kernel records handler/tool latency on each result.
- Direct mode persists ChatAgent model calls plus logical tool executions.
- Dual mode additionally persists EventAgent fallback model calls.
Storage and UI Scope
- Migrate legacy SQLite databases with safe additive columns/indexes; legacy rows default to
chat_agent / chat_completion.
- Extend call, turn, and session summaries with mode, call counts, fallback counts, tool counts, and independent wall time.
- Keep legacy
elapsed_ms fields for compatibility; UI labels architecture/call kind and prefers turn_wall_time_ms for totals.
Files
- Modify:
src/agent_lab/domain/messages.py
- Modify:
src/agent_lab/application/session_store.py
- Modify:
src/agent_lab/application/event_agent.py
- Modify:
src/agent_lab/application/events/models.py
- Modify:
src/agent_lab/application/events/kernel.py
- Modify:
src/agent_lab/application/runtime.py
- Modify:
src/agent_lab/infrastructure/sqlite_store.py
- Modify:
src/agent_lab/presentation/static/app.js
- Modify focused tests for event kernel/agent, runtime, SQLite, and WebSocket/UI.
Requirement Execution Loop
Plan
- Add RED storage/API tests for typed call rows, legacy migration, mode derivation, idempotent metric keys, and wall-time aggregation.
- Add RED EventAgent/kernel tests for trailing usage, first-provider-item TTFT, fallback attempts, and tool latency.
- Add RED runtime parity tests proving direct and dual persist the same logical tool count while dual includes fallback model cost only when used.
- Implement the smallest additive schema, metric capture, and UI formatting changes.
- Run focused tests, full suite, JS syntax, migration stress, diff check, then specification and quality review.
Verification
uv run pytest tests/test_event_kernel.py tests/test_event_agent.py tests/test_sqlite_store.py tests/test_debug_runtime.py tests/test_websocket_api.py -q
node --check src/agent_lab/presentation/static/app.js
uv run pytest
- repeated legacy/concurrent SQLite migration test
git diff --check