feat(gui): Display active Gemini caches
This change adds a label to the Provider panel to show the count and total size of active Gemini caches when the Gemini provider is selected. This information is hidden for other providers.
This commit is contained in:
19
gui.py
19
gui.py
@@ -771,6 +771,7 @@ class App:
|
|||||||
|
|
||||||
def _update_telemetry_panel(self):
|
def _update_telemetry_panel(self):
|
||||||
"""Updates the token budget visualizer in the Provider panel."""
|
"""Updates the token budget visualizer in the Provider panel."""
|
||||||
|
# Update history bleed stats for all providers
|
||||||
stats = ai_client.get_history_bleed_stats()
|
stats = ai_client.get_history_bleed_stats()
|
||||||
if dpg.does_item_exist("token_budget_bar"):
|
if dpg.does_item_exist("token_budget_bar"):
|
||||||
percentage = stats.get("percentage", 0.0)
|
percentage = stats.get("percentage", 0.0)
|
||||||
@@ -780,6 +781,23 @@ class App:
|
|||||||
limit = stats.get("limit", 0)
|
limit = stats.get("limit", 0)
|
||||||
dpg.set_value("token_budget_label", f"{current:,} / {limit:,}")
|
dpg.set_value("token_budget_label", f"{current:,} / {limit:,}")
|
||||||
|
|
||||||
|
# Update Gemini-specific cache stats
|
||||||
|
if dpg.does_item_exist("gemini_cache_label"):
|
||||||
|
if self.current_provider == "gemini":
|
||||||
|
try:
|
||||||
|
cache_stats = ai_client.get_gemini_cache_stats()
|
||||||
|
count = cache_stats.get("cache_count", 0)
|
||||||
|
size_bytes = cache_stats.get("total_size_bytes", 0)
|
||||||
|
size_kb = size_bytes / 1024.0
|
||||||
|
text = f"Gemini Caches: {count} ({size_kb:.1f} KB)"
|
||||||
|
dpg.set_value("gemini_cache_label", text)
|
||||||
|
dpg.configure_item("gemini_cache_label", show=True)
|
||||||
|
except Exception as e:
|
||||||
|
# If the API call fails, just hide the label
|
||||||
|
dpg.configure_item("gemini_cache_label", show=False)
|
||||||
|
else:
|
||||||
|
dpg.configure_item("gemini_cache_label", show=False)
|
||||||
|
|
||||||
def _append_comms_entry(self, entry: dict, idx: int):
|
def _append_comms_entry(self, entry: dict, idx: int):
|
||||||
if not dpg.does_item_exist("comms_scroll"):
|
if not dpg.does_item_exist("comms_scroll"):
|
||||||
return
|
return
|
||||||
@@ -1885,6 +1903,7 @@ class App:
|
|||||||
dpg.add_text("History Token Budget:", color=_LABEL_COLOR)
|
dpg.add_text("History Token Budget:", color=_LABEL_COLOR)
|
||||||
dpg.add_progress_bar(tag="token_budget_bar", default_value=0.0, width=-1)
|
dpg.add_progress_bar(tag="token_budget_bar", default_value=0.0, width=-1)
|
||||||
dpg.add_text("0 / 0", tag="token_budget_label")
|
dpg.add_text("0 / 0", tag="token_budget_label")
|
||||||
|
dpg.add_text("", tag="gemini_cache_label", show=False)
|
||||||
dpg.add_separator()
|
dpg.add_separator()
|
||||||
dpg.add_text("Parameters")
|
dpg.add_text("Parameters")
|
||||||
dpg.add_input_float(tag="ai_temperature", label="Temperature", default_value=self.temperature, min_value=0.0, max_value=2.0)
|
dpg.add_input_float(tag="ai_temperature", label="Temperature", default_value=self.temperature, min_value=0.0, max_value=2.0)
|
||||||
|
|||||||
@@ -44,7 +44,10 @@ def test_telemetry_panel_updates_correctly(app_instance):
|
|||||||
Tests that the _update_telemetry_panel method correctly updates
|
Tests that the _update_telemetry_panel method correctly updates
|
||||||
DPG widgets based on the stats from ai_client.
|
DPG widgets based on the stats from ai_client.
|
||||||
"""
|
"""
|
||||||
# 1. Define the mock stats to be returned by ai_client
|
# 1. Set the provider to anthropic
|
||||||
|
app_instance.current_provider = "anthropic"
|
||||||
|
|
||||||
|
# 2. Define the mock stats
|
||||||
mock_stats = {
|
mock_stats = {
|
||||||
"provider": "anthropic",
|
"provider": "anthropic",
|
||||||
"limit": 180000,
|
"limit": 180000,
|
||||||
@@ -52,22 +55,57 @@ def test_telemetry_panel_updates_correctly(app_instance):
|
|||||||
"percentage": 75.0,
|
"percentage": 75.0,
|
||||||
}
|
}
|
||||||
|
|
||||||
# 2. Patch the dependencies
|
# 3. Patch the dependencies
|
||||||
with patch('ai_client.get_history_bleed_stats', return_value=mock_stats) as mock_get_stats, \
|
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.set_value') as mock_set_value, \
|
||||||
|
patch('dearpygui.dearpygui.configure_item') as mock_configure_item, \
|
||||||
patch('dearpygui.dearpygui.does_item_exist', return_value=True) as mock_does_item_exist:
|
patch('dearpygui.dearpygui.does_item_exist', return_value=True) as mock_does_item_exist:
|
||||||
|
|
||||||
# 3. Call the method under test
|
# 4. Call the method under test
|
||||||
app_instance._update_telemetry_panel()
|
app_instance._update_telemetry_panel()
|
||||||
|
|
||||||
# 4. Assert the results
|
# 5. Assert the results
|
||||||
mock_get_stats.assert_called_once()
|
mock_get_stats.assert_called_once()
|
||||||
|
|
||||||
# Check that the code verified the existence of the widgets
|
# Assert history bleed widgets were updated
|
||||||
mock_does_item_exist.assert_any_call("token_budget_bar")
|
|
||||||
mock_does_item_exist.assert_any_call("token_budget_label")
|
|
||||||
|
|
||||||
# Check that the widgets were updated with the correct values
|
|
||||||
mock_set_value.assert_any_call("token_budget_bar", 0.75)
|
mock_set_value.assert_any_call("token_budget_bar", 0.75)
|
||||||
# Note: My implementation formats numbers with commas
|
|
||||||
mock_set_value.assert_any_call("token_budget_label", "135,000 / 180,000")
|
mock_set_value.assert_any_call("token_budget_label", "135,000 / 180,000")
|
||||||
|
|
||||||
|
# Assert Gemini-specific widget was hidden
|
||||||
|
mock_configure_item.assert_any_call("gemini_cache_label", show=False)
|
||||||
|
|
||||||
|
def test_cache_data_display_updates_correctly(app_instance):
|
||||||
|
"""
|
||||||
|
Tests that the _update_telemetry_panel method correctly updates the
|
||||||
|
GUI with Gemini cache statistics when the provider is set to Gemini.
|
||||||
|
"""
|
||||||
|
# 1. Set the provider to Gemini
|
||||||
|
app_instance.current_provider = "gemini"
|
||||||
|
|
||||||
|
# 2. Define mock cache stats
|
||||||
|
mock_cache_stats = {
|
||||||
|
'cache_count': 5,
|
||||||
|
'total_size_bytes': 12345
|
||||||
|
}
|
||||||
|
# Expected formatted string
|
||||||
|
expected_text = "Gemini Caches: 5 (12.1 KB)"
|
||||||
|
|
||||||
|
# 3. Patch dependencies
|
||||||
|
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.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
|
||||||
|
with patch('ai_client.get_history_bleed_stats', return_value={}):
|
||||||
|
|
||||||
|
# 4. Call the method under test
|
||||||
|
app_instance._update_telemetry_panel()
|
||||||
|
|
||||||
|
# 5. Assert the results
|
||||||
|
mock_get_cache_stats.assert_called_once()
|
||||||
|
|
||||||
|
# Check that the UI item was shown and its value was set
|
||||||
|
mock_configure_item.assert_any_call("gemini_cache_label", show=True)
|
||||||
|
mock_set_value.assert_any_call("gemini_cache_label", expected_text)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user