feat(gui): add Session Insights panel with token history tracking

This commit is contained in:
2026-03-07 11:17:51 -05:00
parent d6cdbf21d7
commit 9aea9b6210
2 changed files with 47 additions and 0 deletions

View File

@@ -147,6 +147,8 @@ class AppController:
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._token_history: List[Dict[str, Any]] = [] # Token usage over time [{"time": t, "input": n, "output": n, "model": s}, ...]
self._session_start_time: float = time.time() # For calculating burn rate
self._comms_log: List[Dict[str, Any]] = []
self.session_usage: Dict[str, Any] = {
"input_tokens": 0,
@@ -961,6 +963,15 @@ class AppController:
for k in ["input_tokens", "output_tokens", "cache_read_input_tokens", "cache_creation_input_tokens", "total_tokens"]:
if k in u:
self.session_usage[k] += u.get(k, 0) or 0
input_t = u.get("input_tokens", 0)
output_t = u.get("output_tokens", 0)
model = payload.get("model", "unknown")
self._token_history.append({
"time": time.time(),
"input": input_t,
"output": output_t,
"model": model
})
if kind in ("tool_result", "tool_call"):
role = "Tool" if kind == "tool_result" else "Vendor API"
@@ -1753,6 +1764,28 @@ class AppController:
ai_client.cleanup()
self._update_cached_stats()
def get_session_insights(self) -> Dict[str, Any]:
import cost_tracker
total_input = sum(e["input"] for e in self._token_history)
total_output = sum(e["output"] for e in self._token_history)
total_tokens = total_input + total_output
elapsed_min = (time.time() - self._session_start_time) / 60.0 if self._token_history else 0
burn_rate = total_tokens / elapsed_min if elapsed_min > 0 else 0
session_cost = cost_tracker.estimate_cost("gemini-2.5-flash", total_input, total_output)
completed = sum(1 for t in self.active_tickets if t.get("status") == "complete")
efficiency = total_tokens / completed if completed > 0 else 0
return {
"total_tokens": total_tokens,
"total_input": total_input,
"total_output": total_output,
"elapsed_min": elapsed_min,
"burn_rate": burn_rate,
"session_cost": session_cost,
"completed_tickets": completed,
"efficiency": efficiency,
"call_count": len(self._token_history)
}
def _flush_to_project(self) -> None:
proj = self.project
proj.setdefault("output", {})["output_dir"] = self.ui_output_dir