Skip to content

feat(memory+diagnostics): surface compaction events + memory stats#36

Merged
TYRMars merged 1 commit into
mainfrom
fear/chat-detail
May 18, 2026
Merged

feat(memory+diagnostics): surface compaction events + memory stats#36
TYRMars merged 1 commit into
mainfrom
fear/chat-detail

Conversation

@TYRMars
Copy link
Copy Markdown
Owner

@TYRMars TYRMars commented May 18, 2026

Summary

  • New AgentEvent::MemoryCompacted event lets the chat surface show an inline marker when the memory backend compacts earlier turns; renders the source (cache hit / fresh summary / fallback prune / summary unavailable) and a few quick metrics.
  • New Settings → 系统 → 诊断 → Memory panel polls /v1/diagnostics/memory every 10s and surfaces the 10 CompactionCounters that were already collected but had no UI consumer.
  • SlidingWindowMemory now ships a minimal stats provider so the default JARVIS_MEMORY_MODE=window deployment serves the endpoint instead of 503.

Why

Commit 53500a0 landed SummarizingMemory three-tier cache + CompactionCounters (10 atomics) + MemoryStatsProvider trait + GET /v1/diagnostics/memory. Audit found everything was tracked but invisible:

  • agent.rs silently called memory.compact() each iteration with no event, so a user watching their chat history get shorter had no idea why.
  • The Diagnostics page only rendered worktrees / stuck-runs / failed-runs; the 10 memory counters had zero consumers.
  • The default mode=window deployment had no stats provider at all → 503.

This makes the existing telemetry actionable end-to-end without changing any compaction logic, cache strategy, or trait shape (Memory::compact signature unchanged).

Test plan

  • cargo clippy --workspace --all-targets --exclude jarvis-desktop -- -D warnings — clean
  • cargo test --workspace --exclude jarvis-desktop — passed
  • harness-memory 47/47 (5 new event tests + 1 SlidingCounters test)
  • harness-core: run_stream_emits_memory_compacted + 4 memory_event tests
  • pnpm typecheck clean; vitest 346/346 (9 new across memorySlice + memoryFrames)
  • Browser preview in zh-CN: 记忆 heading + unavailable copy resolve; mocked summarizing payload renders 6 rows; mocked sliding payload renders 2 rows; warn-tone marker renders amber dashed border + tinted pill.

🤖 Generated with Claude Code

Compaction telemetry was already collected (CompactionCounters, 10 atomics
behind /v1/diagnostics/memory) but invisible to both users and operators:
the agent silently called memory.compact() each iteration with no event,
the Diagnostics page only listed worktrees/runs, and the SlidingWindowMemory
backend (the default `JARVIS_MEMORY_MODE=window`) had no stats provider at
all. This makes the existing telemetry actionable end-to-end.

Backend (harness-core / harness-memory)

- New memory_event task-local channel mirroring plan/progress; carries
  CompactionInfo { source, turns_kept, turns_dropped, summary_chars,
  working_context_chars, model_input_tokens_est }. Emits are silent
  no-ops outside the agent loop, keeping memory unit tests trivial.
- AgentEvent::MemoryCompacted variant; Agent::run_stream scopes the
  channel around each build_request call and yields drained events
  before the next LLM iteration.
- SummarizingMemory::compact now classifies its outcome into one of
  CompactionSource {NoOp, WindowDropped, CacheMemory, CacheStore,
  FreshLlm, PtlRoundOne, PtlRoundTwo, SummaryUnavailable} and emits
  one CompactionInfo per call. Priority: PTL > summary source >
  SummaryUnavailable > NoOp.
- SlidingWindowMemory gains a minimal SlidingCounters
  { compactions_total, window_dropped } so the default deployment
  also serves /v1/diagnostics/memory instead of 503.
- jarvis-cli renders an inline one-liner for non-NoOp events.

Frontend (jarvis-web)

- Settings -> System -> Diagnostics now has a Memory panel polling
  /v1/diagnostics/memory every 10s; renders backend / compactions /
  cache hit rate / LLM failure rate / circuit opens-skips / PTL fallback
  for the summarizing backend, and a trimmed view (backend +
  compactions + window-dropped) for the sliding backend so no
  misleading zeros show up.
- New memorySlice (per-conversation ring buffer, cap 20) +
  memoryFrames handler. `reset` clears markers across conversations
  to mirror planFrames.
- New CompactionMarker component renders an inline dashed-border card
  in the chat transcript at the right message boundary; NoOp emits
  are filtered out (counters still record them). SummaryUnavailable
  and PTL fallbacks render with a warn tone (amber).
- Full zh-CN + en i18n: diagnosticsMemoryHeading, MemoryUnavailable,
  and 7 compactionSourceXxx keys.

Quality gates

- cargo clippy --workspace --all-targets --exclude jarvis-desktop
  -D warnings: clean
- cargo test --workspace --exclude jarvis-desktop: passed
- harness-memory: 47/47 (5 new event tests + 1 sliding counter test)
- harness-core: agent.rs run_stream_emits_memory_compacted +
  4 memory_event::tests
- pnpm typecheck: clean; vitest 346/346 (9 new across memorySlice /
  memoryFrames)
- Browser preview: zh-CN labels resolve; populated panel renders
  6 rows for summarizing (80% cache hit rate over the sample
  payload); sliding shape renders 2 rows; warn-tone marker renders
  amber dashed border + tinted pill.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@TYRMars TYRMars merged commit cb4d737 into main May 18, 2026
1 of 2 checks passed
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