Skip to content

fix(otel-dashboard): active-session pick + local_dm JSON extraction#39

Merged
slabgorb merged 1 commit intodevelopfrom
fix/otel-dashboard-rest-and-local-dm
Apr 24, 2026
Merged

fix(otel-dashboard): active-session pick + local_dm JSON extraction#39
slabgorb merged 1 commit intodevelopfrom
fix/otel-dashboard-rest-and-local-dm

Conversation

@slabgorb
Copy link
Copy Markdown
Owner

Summary

Fixes two OTEL dashboard bugs found during the 2026-04-24 playtest (see sq-playtest-pingpong.md lines 598, 622).

  • Bug 2 (State tab): /api/debug/state now sorts newest-mtime first, adds last_activity_ts to each view, and accepts ?session_key=<slug> to filter. The dashboard's default debugState[0] pick now lands on the active session instead of the oldest save.
  • Bug 3 (local_dm JSON parse): LocalDM._extract_json_object strips markdown code fences, preamble, and trailing commentary before json.loads. Every cleanup step is recorded on the local_dm.decompose span (json_cleanup_steps), and failure paths now record a parse_preview so the GM panel can diagnose unrecoverable responses from the dashboard. No silent fallback — contract violations remain visible.

Bug 1 (turn aggregator stuck at 0) is fixed in the paired UI PR.

Test plan

  • uv run pytest tests/agents/test_local_dm.py tests/server/test_rest.py — 40 tests pass locally
  • Live verify: start a second save alongside the active one → State tab should show the active save, not the stale one
  • Live verify: dashboard local_dm.decompose span should no longer emit degraded=true with parse_failure: JSONDecodeError each turn

Wiring tests added:

  • test_debug_state_sorts_newest_first_and_filters_by_session_key
  • test_local_dm_parses_response_wrapped_in_code_fence
  • test_local_dm_parses_response_with_preamble
  • test_local_dm_parse_failure_records_preview_on_span
  • test_extract_json_object_* (unit coverage for the extractor helper)

🤖 Generated with Claude Code

Two playtest bugs found 2026-04-24 (sq-playtest-pingpong lines 598, 622).

1. `/api/debug/state` now sorts newest-mtime first and accepts a
   `?session_key=<slug>` query filter. Also adds `last_activity_ts`
   to each view so the UI can pick explicitly. The dashboard State tab
   was stuck on `debugState[0]` — which, under alphabetical sort, was
   the oldest save, not the active session.

2. `LocalDM._extract_json_object` strips markdown code fences /
   preamble / trailing commentary before `json.loads`. Haiku was
   returning fenced responses every turn despite the system prompt
   saying "no fences", burning 45s/turn on parse failures and emitting
   `dispatch_count=0`. Every cleanup step is recorded on the
   `local_dm.decompose` OTEL span (`json_cleanup_steps` attr) so the GM
   panel sees the contract violation even when the recovery succeeds
   — no silent fallback. Failure path now records `parse_preview` so
   unrecoverable responses can be diagnosed from the dashboard instead
   of from server logs.

Wiring tests:
- test_debug_state_sorts_newest_first_and_filters_by_session_key —
  creates two saves with staggered mtimes, asserts the newer comes
  first and the filter narrows to one entry.
- test_local_dm_parses_response_wrapped_in_code_fence — feeds the
  exact failing shape (```json ...```) and asserts clean parse +
  `strip_fence` recorded on the span.
- test_local_dm_parse_failure_records_preview_on_span — failure path
  surfaces a preview for dashboard diagnosis.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@slabgorb slabgorb merged commit e96eb12 into develop Apr 24, 2026
@slabgorb slabgorb deleted the fix/otel-dashboard-rest-and-local-dm branch April 24, 2026 09:32
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.

1 participant