|
@@ -0,0 +1,65 @@
|
|
|
|
|
+# 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
|
|
|
|
|
+
|
|
|
|
|
+1. Add RED storage/API tests for typed call rows, legacy migration, mode derivation, idempotent metric keys, and wall-time aggregation.
|
|
|
|
|
+2. Add RED EventAgent/kernel tests for trailing usage, first-provider-item TTFT, fallback attempts, and tool latency.
|
|
|
|
|
+3. Add RED runtime parity tests proving direct and dual persist the same logical tool count while dual includes fallback model cost only when used.
|
|
|
|
|
+4. Implement the smallest additive schema, metric capture, and UI formatting changes.
|
|
|
|
|
+5. 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`
|