conductor(checkpoint): Checkpoint end of Phase 3: Diagnostics UI and Optimization
This commit is contained in:
@@ -25,7 +25,7 @@
|
||||
- [x] Task: Build the Diagnostics Panel in Dear PyGui 30d838c
|
||||
- [x] Sub-task: Write Tests (verify panel components render)
|
||||
- [x] Sub-task: Implement Feature (plots, stat readouts in `gui.py`)
|
||||
- [ ] Task: Identify and fix main thread performance bottlenecks
|
||||
- [~] Task: Identify and fix main thread performance bottlenecks
|
||||
- [ ] Sub-task: Write Tests (reproducible "heavy" load test)
|
||||
- [ ] Sub-task: Implement Feature (refactor heavy logic to workers)
|
||||
- [ ] Task: Conductor - User Manual Verification 'Phase 3: Diagnostics UI and Optimization' (Protocol in workflow.md)
|
||||
48
gui.py
48
gui.py
@@ -504,6 +504,13 @@ class App:
|
||||
"input_lag": [0.0] * 100
|
||||
}
|
||||
|
||||
self.session_usage = {
|
||||
"input_tokens": 0,
|
||||
"output_tokens": 0,
|
||||
"cache_read_input_tokens": 0,
|
||||
"cache_creation_input_tokens": 0
|
||||
}
|
||||
|
||||
session_logger.open_session()
|
||||
ai_client.set_provider(self.current_provider, self.current_model)
|
||||
ai_client.confirm_and_run_callback = self._confirm_and_run
|
||||
@@ -511,6 +518,8 @@ class App:
|
||||
ai_client.tool_log_callback = self._on_tool_log
|
||||
mcp_client.perf_monitor_callback = self.perf_monitor.get_metrics
|
||||
self.perf_monitor.alert_callback = self._on_performance_alert
|
||||
self._last_bleed_update_time = 0
|
||||
self._recalculate_session_usage()
|
||||
|
||||
# ---------------------------------------------------------------- project loading
|
||||
|
||||
@@ -775,6 +784,21 @@ class App:
|
||||
"ts": project_manager.now_ts()
|
||||
})
|
||||
|
||||
def _recalculate_session_usage(self):
|
||||
"""Aggregates usage across the session from comms log."""
|
||||
usage = {
|
||||
"input_tokens": 0,
|
||||
"output_tokens": 0,
|
||||
"cache_read_input_tokens": 0,
|
||||
"cache_creation_input_tokens": 0
|
||||
}
|
||||
for entry in ai_client.get_comms_log():
|
||||
if entry.get("kind") == "response" and "usage" in entry.get("payload", {}):
|
||||
u = entry["payload"]["usage"]
|
||||
for k in usage.keys():
|
||||
usage[k] += u.get(k, 0) or 0
|
||||
self.session_usage = usage
|
||||
|
||||
def _flush_pending_comms(self):
|
||||
"""Called every frame from the main render loop."""
|
||||
with self._pending_comms_lock:
|
||||
@@ -784,26 +808,30 @@ class App:
|
||||
self._comms_entry_count += 1
|
||||
self._append_comms_entry(entry, self._comms_entry_count)
|
||||
if entries:
|
||||
self._recalculate_session_usage()
|
||||
self._update_token_usage()
|
||||
|
||||
def _update_token_usage(self):
|
||||
if not dpg.does_item_exist("ai_token_usage"):
|
||||
return
|
||||
usage = get_total_token_usage()
|
||||
usage = self.session_usage
|
||||
total = usage["input_tokens"] + usage["output_tokens"]
|
||||
dpg.set_value("ai_token_usage", f"Tokens: {total} (In: {usage['input_tokens']} Out: {usage['output_tokens']})")
|
||||
|
||||
def _update_telemetry_panel(self):
|
||||
"""Updates the token budget visualizer in the Provider panel."""
|
||||
# Update history bleed stats for all providers
|
||||
stats = ai_client.get_history_bleed_stats()
|
||||
if dpg.does_item_exist("token_budget_bar"):
|
||||
percentage = stats.get("percentage", 0.0)
|
||||
dpg.set_value("token_budget_bar", percentage / 100.0 if percentage else 0.0)
|
||||
if dpg.does_item_exist("token_budget_label"):
|
||||
current = stats.get("current", 0)
|
||||
limit = stats.get("limit", 0)
|
||||
dpg.set_value("token_budget_label", f"{current:,} / {limit:,}")
|
||||
# Update history bleed stats for all providers (throttled)
|
||||
now = time.time()
|
||||
if now - self._last_bleed_update_time > 2.0:
|
||||
self._last_bleed_update_time = now
|
||||
stats = ai_client.get_history_bleed_stats()
|
||||
if dpg.does_item_exist("token_budget_bar"):
|
||||
percentage = stats.get("percentage", 0.0)
|
||||
dpg.set_value("token_budget_bar", percentage / 100.0 if percentage else 0.0)
|
||||
if dpg.does_item_exist("token_budget_label"):
|
||||
current = stats.get("current", 0)
|
||||
limit = stats.get("limit", 0)
|
||||
dpg.set_value("token_budget_label", f"{current:,} / {limit:,}")
|
||||
|
||||
# Update Gemini-specific cache stats
|
||||
if dpg.does_item_exist("gemini_cache_label"):
|
||||
|
||||
@@ -35,5 +35,5 @@ active = "main"
|
||||
|
||||
[discussion.discussions.main]
|
||||
git_commit = ""
|
||||
last_updated = "2026-02-23T14:48:16"
|
||||
last_updated = "2026-02-23T14:52:20"
|
||||
history = []
|
||||
|
||||
@@ -56,9 +56,11 @@ def test_telemetry_panel_updates_correctly(app_instance):
|
||||
}
|
||||
|
||||
# 3. Patch the dependencies
|
||||
app_instance._last_bleed_update_time = 0 # Force update
|
||||
with patch('ai_client.get_history_bleed_stats', return_value=mock_stats) as mock_get_stats, \
|
||||
patch('dearpygui.dearpygui.set_value') as mock_set_value, \
|
||||
patch('dearpygui.dearpygui.configure_item') as mock_configure_item, \
|
||||
patch('dearpygui.dearpygui.is_item_shown', return_value=False), \
|
||||
patch('dearpygui.dearpygui.does_item_exist', return_value=True) as mock_does_item_exist:
|
||||
|
||||
# 4. Call the method under test
|
||||
@@ -91,9 +93,11 @@ def test_cache_data_display_updates_correctly(app_instance):
|
||||
expected_text = "Gemini Caches: 5 (12.1 KB)"
|
||||
|
||||
# 3. Patch dependencies
|
||||
app_instance._last_bleed_update_time = 0 # Force update
|
||||
with patch('ai_client.get_gemini_cache_stats', return_value=mock_cache_stats) as mock_get_cache_stats, \
|
||||
patch('dearpygui.dearpygui.set_value') as mock_set_value, \
|
||||
patch('dearpygui.dearpygui.configure_item') as mock_configure_item, \
|
||||
patch('dearpygui.dearpygui.is_item_shown', return_value=False), \
|
||||
patch('dearpygui.dearpygui.does_item_exist', return_value=True) as mock_does_item_exist:
|
||||
|
||||
# We also need to mock get_history_bleed_stats as it's called in the same function
|
||||
|
||||
Reference in New Issue
Block a user