fix(gui): move heavy processing from render loop to controller - gui only visualizes state
This commit is contained in:
@@ -146,6 +146,7 @@ class AppController:
|
||||
self.mma_status: str = "idle"
|
||||
self._tool_log: List[Dict[str, Any]] = []
|
||||
self._tool_stats: Dict[str, Dict[str, Any]] = {} # {tool_name: {"count": 0, "total_time_ms": 0.0, "failures": 0}}
|
||||
self._cached_cache_stats: Dict[str, Any] = {} # Pre-computed cache stats for GUI
|
||||
self._comms_log: List[Dict[str, Any]] = []
|
||||
self.session_usage: Dict[str, Any] = {
|
||||
"input_tokens": 0,
|
||||
@@ -1740,6 +1741,17 @@ class AppController:
|
||||
count = cache_stats.get("cache_count", 0)
|
||||
size_bytes = cache_stats.get("total_size_bytes", 0)
|
||||
self._gemini_cache_text = f"Gemini Caches: {count} ({size_bytes / 1024:.1f} KB)"
|
||||
self._update_cached_stats()
|
||||
|
||||
def _update_cached_stats(self) -> None:
|
||||
import ai_client
|
||||
self._cached_cache_stats = ai_client.get_gemini_cache_stats()
|
||||
self._cached_tool_stats = dict(self._tool_stats)
|
||||
|
||||
def clear_cache(self) -> None:
|
||||
import ai_client
|
||||
ai_client.cleanup()
|
||||
self._update_cached_stats()
|
||||
|
||||
def _flush_to_project(self) -> None:
|
||||
proj = self.project
|
||||
|
||||
37
src/gui_2.py
37
src/gui_2.py
@@ -1433,38 +1433,22 @@ class App:
|
||||
imgui.text_disabled(f" [{role}] ~{toks:,} tokens")
|
||||
shown += 1
|
||||
imgui.separator()
|
||||
if ai_client._provider == "gemini":
|
||||
if ai_client._gemini_cache is not None:
|
||||
age = time.time() - (ai_client._gemini_cache_created_at or time.time())
|
||||
ttl = ai_client._GEMINI_CACHE_TTL
|
||||
imgui.text_colored(C_LBL, f"Gemini Cache: ACTIVE | Age: {age:.0f}s / {ttl}s | Renews at: {ttl * 0.9:.0f}s")
|
||||
else:
|
||||
imgui.text_disabled("Gemini Cache: INACTIVE")
|
||||
elif ai_client._provider == "anthropic":
|
||||
with ai_client._anthropic_history_lock:
|
||||
turns = len(ai_client._anthropic_history)
|
||||
cache_reads = 0
|
||||
for entry in reversed(ai_client.get_comms_log()):
|
||||
if entry.get("kind") == "response":
|
||||
cache_reads = (entry.get("payload") or {}).get("usage", {}).get("cache_read_input_tokens") or 0
|
||||
break
|
||||
imgui.text_disabled("Anthropic: 4-breakpoint ephemeral caching (auto-managed)")
|
||||
imgui.text_disabled(f" {turns} history turns | Cache reads last call: {cache_reads:,}")
|
||||
cache_stats = getattr(self.controller, '_cached_cache_stats', {})
|
||||
if cache_stats.get("cache_exists"):
|
||||
age = cache_stats.get("cache_age_seconds", 0)
|
||||
ttl = cache_stats.get("ttl_seconds", 3600)
|
||||
imgui.text_colored(C_LBL, f"Gemini Cache: ACTIVE | Age: {age:.0f}s / {ttl}s | Renews at: {ttl * 0.9:.0f}s")
|
||||
else:
|
||||
imgui.text_disabled("Gemini Cache: INACTIVE")
|
||||
|
||||
def _render_cache_panel(self) -> None:
|
||||
if self.current_provider != "gemini":
|
||||
return
|
||||
if not imgui.collapsing_header("Cache Analytics"):
|
||||
return
|
||||
now = time.time()
|
||||
if not hasattr(self, '_cache_stats_cache_time') or now - self._cache_stats_cache_time > 1.0:
|
||||
self._cached_cache_stats = ai_client.get_gemini_cache_stats()
|
||||
self._cache_stats_cache_time = now
|
||||
stats = self._cached_cache_stats
|
||||
stats = getattr(self.controller, '_cached_cache_stats', {})
|
||||
if not stats.get("cache_exists"):
|
||||
imgui.text_disabled("No active cache")
|
||||
if imgui.button("Force Cache"):
|
||||
pass
|
||||
return
|
||||
age_sec = stats.get("cache_age_seconds", 0)
|
||||
ttl_remaining = stats.get("ttl_remaining", 0)
|
||||
@@ -1483,7 +1467,7 @@ class App:
|
||||
imgui.progress_bar(ttl_pct / 100.0, imgui.ImVec2(-1, 0), f"{ttl_pct:.0f}%")
|
||||
imgui.pop_style_color()
|
||||
if imgui.button("Clear Cache"):
|
||||
ai_client.cleanup()
|
||||
self.controller.clear_cache()
|
||||
self._cache_cleared_timestamp = time.time()
|
||||
if hasattr(self, '_cache_cleared_timestamp') and time.time() - self._cache_cleared_timestamp < 5:
|
||||
imgui.text_colored(imgui.ImVec4(0.2, 1.0, 0.2, 1.0), "Cache cleared - will rebuild on next request")
|
||||
@@ -1494,8 +1478,7 @@ class App:
|
||||
now = time.time()
|
||||
if not hasattr(self, '_tool_stats_cache_time') or now - self._tool_stats_cache_time > 1.0:
|
||||
self._cached_tool_stats = getattr(self.controller, '_tool_stats', {})
|
||||
self._tool_stats_cache_time = now
|
||||
tool_stats = getattr(self, '_cached_tool_stats', {})
|
||||
tool_stats = getattr(self.controller, '_cached_tool_stats', {})
|
||||
if not tool_stats:
|
||||
imgui.text_disabled("No tool usage data")
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user