# Implementation Plan: Cache Analytics Display (cache_analytics_20260306) > **Reference:** [Spec](./spec.md) | [Architecture Guide](../../../docs/guide_architecture.md) ## Phase 1: Foundation & Research Focus: Verify existing infrastructure and set up panel structure - [ ] Task 1.1: Initialize MMA Environment - Run `activate_skill mma-orchestrator` before starting - [ ] Task 1.2: Verify ai_client.get_gemini_cache_stats() - WHERE: `src/ai_client.py` lines ~200-230 - WHAT: Confirm function exists and returns expected dict structure - HOW: Use `manual-slop_py_get_definition` on `get_gemini_cache_stats` - OUTPUT: Document exact return dict structure in task notes - [ ] Task 1.3: Verify ai_client.cleanup() - WHERE: `src/ai_client.py` line ~220 - WHAT: Confirm function clears `_gemini_cache` - HOW: Use `manual-slop_py_get_definition` on `cleanup` - SAFETY: Note that cleanup() also clears other resources - document side effects ## Phase 2: Panel Implementation Focus: Create the GUI panel structure - [ ] Task 2.1: Add cache panel state variables - WHERE: `src/gui_2.py` in `App.__init__` (around line 170) - WHAT: Add minimal state if needed (likely none - read directly from ai_client) - HOW: Follow existing state initialization pattern - CODE STYLE: 1-space indentation - SAFETY: No locks needed - read-only access to ai_client globals - [ ] Task 2.2: Create _render_cache_panel() method - WHERE: `src/gui_2.py` after other `_render_*_panel()` methods - WHAT: New method that displays cache statistics - HOW: ```python def _render_cache_panel(self) -> None: if self.current_provider != "gemini": return if not imgui.collapsing_header("Cache Analytics"): return stats = ai_client.get_gemini_cache_stats() # Render stats... ``` - CODE STYLE: 1-space indentation, NO COMMENTS - [ ] Task 2.3: Integrate panel into main GUI - WHERE: `src/gui_2.py` in `_gui_func()` method - WHAT: Call `_render_cache_panel()` in appropriate location - HOW: Add near token budget panel or in settings area - SAFETY: Ensure not called during modal dialogs ## Phase 3: Statistics Display Focus: Implement the visual statistics rendering - [ ] Task 3.1: Implement cache status display - WHERE: `src/gui_2.py` in `_render_cache_panel()` - WHAT: Show cache existence and age - HOW: - `imgui.text(f"Cache Active: {stats['cache_exists']}")` - `imgui.text(f"Age: {format_age(stats['cache_age_seconds'])}")` - HELPER: Create `format_age(seconds: float) -> str` helper - CODE STYLE: 1-space indentation - [ ] Task 3.2: Implement TTL countdown display - WHERE: `src/gui_2.py` in `_render_cache_panel()` - WHAT: Show remaining TTL with percentage - HOW: - `remaining = stats['ttl_remaining']` - `percentage = (remaining / stats['ttl_seconds']) * 100` - Use `imgui.progress_bar()` for visual - VISUAL: Warning color when percentage < 20% (use `vec4` colors defined at top of file) - [ ] Task 3.3: Implement requests counter (optional enhancement) - WHERE: `src/gui_2.py` in `_render_cache_panel()` - WHAT: Show estimated "requests while cache active" - HOW: Add `self._cache_request_count: int = 0` state, increment on send - SAFETY: This requires hooking into send flow - may skip if complex ## Phase 4: Manual Controls Focus: Implement the cache clear functionality - [ ] Task 4.1: Add clear cache button - WHERE: `src/gui_2.py` in `_render_cache_panel()` - WHAT: Button that clears the Gemini cache - HOW: ```python if imgui.button("Clear Cache"): ai_client.cleanup() # Optionally set a flag to show "Cache cleared" message ``` - SAFETY: `cleanup()` clears ALL caches, not just Gemini - document this - [ ] Task 4.2: Add clear confirmation/feedback - WHERE: `src/gui_2.py` in `_render_cache_panel()` - WHAT: Show feedback after clear - HOW: Add `self._cache_just_cleared: bool = False` flag, show message, auto-clear after 3s - CODE STYLE: 1-space indentation ## Phase 5: Testing Focus: Verify all functionality works correctly - [ ] Task 5.1: Write unit tests for cache panel - WHERE: `tests/test_cache_panel.py` (new file) - WHAT: Test panel visibility, stats display, clear button - HOW: Use `mock_app` or `app_instance` fixture from `conftest.py` - PATTERN: Follow `test_gui_phase4.py` as reference - CODE STYLE: 1-space indentation - [ ] Task 5.2: Write integration test with live_gui - WHERE: `tests/test_cache_panel.py` - WHAT: Test with actual Gemini provider (or mock) - HOW: Use `live_gui` fixture, set provider to 'gemini', verify panel shows - ARTIFACTS: Write to `tests/artifacts/` - [ ] Task 5.3: Conductor - Phase Verification - Run targeted tests: `uv run pytest tests/test_cache_panel.py -v` - Verify no lint errors in modified files - Manual visual verification in GUI ## Implementation Notes ### Thread Safety Analysis - `ai_client.get_gemini_cache_stats()` reads `_gemini_cache` and `_gemini_cache_created_at` - These are set on the asyncio worker thread during `_send_gemini()` - Reading from GUI thread is safe (atomic types) but values may be slightly stale - No locks required for display purposes ### Code Style Checklist - [ ] 1-space indentation throughout - [ ] CRLF line endings on Windows - [ ] No comments unless explicitly documenting complex logic - [ ] Type hints on all new functions - [ ] Follow existing `vec4` color naming pattern ### Files Modified - `src/gui_2.py`: Add `_render_cache_panel()`, integrate into `_gui_func()` - `tests/test_cache_panel.py`: New test file ### Dependencies - Existing: `src/ai_client.py::get_gemini_cache_stats()` - Existing: `src/ai_client.py::cleanup()` - Existing: `imgui_bundle::imgui`