5.4 KiB
5.4 KiB
Track Specification: Cache Analytics Display (cache_analytics_20260306)
Overview
Gemini cache hit/miss visualization, memory usage, TTL status display. Uses existing ai_client.get_gemini_cache_stats() which is implemented but has no GUI representation.
Current State Audit
Already Implemented (DO NOT re-implement)
ai_client.get_gemini_cache_stats()(src/ai_client.py) - Returns dict with:cache_exists: bool - Whether a Gemini cache is activecache_age_seconds: float - Age of current cache in secondsttl_seconds: int - Cache TTL (default 3600)ttl_remaining: float - Seconds until cache expirescreated_at: float - Unix timestamp of cache creation
- Gemini cache variables (src/ai_client.py lines ~60-70):
_gemini_cache: TheCachedContentobject or None_gemini_cache_created_at: float timestamp when cache was created_GEMINI_CACHE_TTL: int = 3600 (1 hour default)
- Cache invalidation logic already handles 90% TTL proactive renewal
Gaps to Fill (This Track's Scope)
- No GUI panel to display cache statistics
- No visual indicator of cache health/TTL
- No manual cache clear button in UI
- No hit/miss tracking (Gemini API doesn't expose this directly - may need approximation)
Architectural Constraints
Threading & State Access
- Non-Blocking: Cache queries MUST NOT block the UI thread. The
get_gemini_cache_stats()function reads module-level globals (_gemini_cache,_gemini_cache_created_at) which are modified on the asyncio worker thread during_send_gemini(). - No Lock Needed: These are atomic reads (bool/float/int), but be aware they may be stale by render time. This is acceptable for display purposes.
- Cross-Thread Pattern: Use
manual-slop_get_git_diffto understand how other read-only stats are accessed ingui_2.py(e.g.,ai_client.get_comms_log()).
GUI Integration
- Location: Add to
_render_token_budget_panel()ingui_2.pyor create new_render_cache_panel()method. - ImGui Pattern: Use
imgui.collapsing_header("Cache Analytics")to allow collapsing. - Code Style: 1-space indentation, no comments unless requested.
Performance
- Polling vs Pushing: Cache stats are cheap to compute (just float math). Safe to recompute each frame when panel is open.
- No Event Needed: Unlike MMA state, cache stats don't need event-driven updates.
Architecture Reference
Consult these docs for implementation patterns:
- docs/guide_architecture.md: Thread domains, cross-thread patterns
- docs/guide_tools.md: Hook API if exposing cache stats via API
Key Integration Points
| File | Lines | Purpose |
|---|---|---|
src/ai_client.py |
~200-230 | get_gemini_cache_stats() function |
src/ai_client.py |
~60-70 | Cache globals (_gemini_cache, _GEMINI_CACHE_TTL) |
src/ai_client.py |
~220 | cleanup() function for manual cache clear |
src/gui_2.py |
~1800-1900 | _render_token_budget_panel() - potential location |
src/gui_2.py |
~150-200 | App.__init__ state initialization pattern |
Functional Requirements
FR1: Cache Status Display
- Display whether a Gemini cache is currently active (
cache_existsbool) - Show cache age in human-readable format (e.g., "45m 23s old")
- Only show panel when
current_provider == "gemini"
FR2: TTL Countdown
- Display remaining TTL in seconds and as percentage (e.g., "15:23 remaining (42%)")
- Visual indicator when TTL is below 20% (warning color)
- Note: Cache auto-rebuilds at 90% TTL, so this shows time until rebuild trigger
FR3: Manual Clear Button
- Button to manually clear cache via
ai_client.cleanup() - Button should have confirmation or be clearly labeled as destructive
- After clear, display "Cache cleared - will rebuild on next request"
FR4: Hit/Miss Estimation (Optional Enhancement)
- Since Gemini API doesn't expose actual hit/miss counts, estimate by:
- Counting number of
send()calls while cache exists - Display as "Cache active for N requests"
- Counting number of
Non-Functional Requirements
| Requirement | Constraint |
|---|---|
| Frame Time Impact | <1ms when panel visible |
| Memory Overhead | <1KB for display state |
| Thread Safety | Read-only access to ai_client globals |
Testing Requirements
Unit Tests
- Test panel renders without error when provider is Gemini
- Test panel is hidden when provider is not Gemini
- Test clear button calls
ai_client.cleanup()
Integration Tests (via live_gui fixture)
- Verify cache stats display after actual Gemini API call
- Verify TTL countdown decrements over time
Structural Testing Contract
- NO mocking of
ai_clientinternals - use real state - Test artifacts go to
tests/artifacts/
Out of Scope
- Anthropic prompt caching display (different mechanism - ephemeral breakpoints)
- DeepSeek caching (not implemented)
- Actual hit/miss tracking from Gemini API (not exposed)
- Persisting cache stats across sessions
Acceptance Criteria
- Cache panel displays in GUI when provider is Gemini
- Cache age shown in human-readable format
- TTL countdown visible with percentage
- Warning color when TTL < 20%
- Manual clear button works and calls
ai_client.cleanup() - Panel hidden for non-Gemini providers
- Uses existing
get_gemini_cache_stats()- no new ai_client code - 1-space indentation maintained