get prior session history properly working.

This commit is contained in:
2026-03-12 21:38:19 -04:00
parent f2c5ae43d7
commit b677228a96
2 changed files with 118 additions and 15 deletions

View File

@@ -286,7 +286,9 @@ class AppController:
self._gemini_cache_text: str = "" self._gemini_cache_text: str = ""
self._last_stable_md: str = '' self._last_stable_md: str = ''
self._token_stats: Dict[str, Any] = {} self._token_stats: Dict[str, Any] = {}
self._token_stats_dirty: bool = False self._comms_log_dirty: bool = True
self._tool_log_dirty: bool = True
self._token_stats_dirty: bool = True
self.ui_disc_truncate_pairs: int = 2 self.ui_disc_truncate_pairs: int = 2
self.ui_auto_scroll_comms: bool = True self.ui_auto_scroll_comms: bool = True
self.ui_auto_scroll_tool_calls: bool = True self.ui_auto_scroll_tool_calls: bool = True
@@ -294,10 +296,14 @@ class AppController:
self._track_discussion_active: bool = False self._track_discussion_active: bool = False
self._tier_stream_last_len: Dict[str, int] = {} self._tier_stream_last_len: Dict[str, int] = {}
self.is_viewing_prior_session: bool = False self.is_viewing_prior_session: bool = False
self._current_session_usage = None
self._current_mma_tier_usage = None
self.prior_session_entries: List[Dict[str, Any]] = [] self.prior_session_entries: List[Dict[str, Any]] = []
self.prior_tool_calls: List[Dict[str, Any]] = [] self.prior_tool_calls: List[Dict[str, Any]] = []
self.prior_disc_entries: List[Dict[str, Any]] = [] self.prior_disc_entries: List[Dict[str, Any]] = []
self.prior_mma_dashboard_state: Dict[str, Any] = {} self.prior_mma_dashboard_state = {}
self._current_token_history = None
self._current_session_start_time = None
self.test_hooks_enabled: bool = ("--enable-test-hooks" in sys.argv) or (os.environ.get("SLOP_TEST_HOOKS") == "1") self.test_hooks_enabled: bool = ("--enable-test-hooks" in sys.argv) or (os.environ.get("SLOP_TEST_HOOKS") == "1")
self.ui_manual_approve: bool = False self.ui_manual_approve: bool = False
# Injection state # Injection state
@@ -531,6 +537,11 @@ class AppController:
"payload": status "payload": status
}) })
def _trigger_gui_refresh(self):
with self._pending_gui_tasks_lock:
self._pending_gui_tasks.append({'action': 'set_comms_dirty'})
self._pending_gui_tasks.append({'action': 'set_tool_log_dirty'})
def _process_pending_gui_tasks(self) -> None: def _process_pending_gui_tasks(self) -> None:
# Periodic telemetry broadcast # Periodic telemetry broadcast
now = time.time() now = time.time()
@@ -557,6 +568,10 @@ class AppController:
# ... # ...
if action == "refresh_api_metrics": if action == "refresh_api_metrics":
self._refresh_api_metrics(task.get("payload", {}), md_content=self.last_md or None) self._refresh_api_metrics(task.get("payload", {}), md_content=self.last_md or None)
elif action == 'set_comms_dirty':
self._comms_log_dirty = True
elif action == 'set_tool_log_dirty':
self._tool_log_dirty = True
elif action == "set_ai_status": elif action == "set_ai_status":
self.ai_status = task.get("payload", "") self.ai_status = task.get("payload", "")
sys.stderr.write(f"[DEBUG] Updated ai_status via task to: {self.ai_status}\n") sys.stderr.write(f"[DEBUG] Updated ai_status via task to: {self.ai_status}\n")
@@ -986,6 +1001,12 @@ class AppController:
if not path: if not path:
return return
if not self.is_viewing_prior_session:
self._current_session_usage = copy.deepcopy(self.session_usage)
self._current_mma_tier_usage = copy.deepcopy(self.mma_tier_usage)
self._current_token_history = copy.deepcopy(self._token_history)
self._current_session_start_time = self._session_start_time
log_path = Path(path) log_path = Path(path)
if log_path.is_dir(): if log_path.is_dir():
log_file = log_path / "comms.log" log_file = log_path / "comms.log"
@@ -1020,6 +1041,15 @@ class AppController:
entries = [] entries = []
disc_entries = [] disc_entries = []
paired_tools = {}
final_tool_calls = []
new_token_history = []
new_usage = {'input_tokens': 0, 'output_tokens': 0, 'cache_read_input_tokens': 0, 'cache_creation_input_tokens': 0, 'total_tokens': 0, 'last_latency': 0.0, 'percentage': 0.0}
new_mma_usage = copy.deepcopy(self.mma_tier_usage)
for t in new_mma_usage:
new_mma_usage[t]['input'] = 0
new_mma_usage[t]['output'] = 0
try: try:
with open(log_file, "r", encoding="utf-8") as f: with open(log_file, "r", encoding="utf-8") as f:
for line in f: for line in f:
@@ -1031,6 +1061,47 @@ class AppController:
kind = entry.get("kind", entry.get("type", "")) kind = entry.get("kind", entry.get("type", ""))
payload = entry.get("payload", {}) payload = entry.get("payload", {})
ts = entry.get("ts", "") ts = entry.get("ts", "")
if kind == 'tool_call':
tid = payload.get('id') or payload.get('call_id')
script = payload.get('script') or json.dumps(payload.get('args', {}), indent=1)
script = _resolve_log_ref(script, session_dir)
entry_obj = {
'source_tier': entry.get('source_tier', 'main'),
'script': script,
'result': '', # Waiting for result
'ts': ts
}
if tid:
paired_tools[tid] = entry_obj
final_tool_calls.append(entry_obj)
elif kind == 'tool_result':
tid = payload.get('id') or payload.get('call_id')
output = payload.get('output', payload.get('content', ''))
output = _resolve_log_ref(output, session_dir)
if tid and tid in paired_tools:
paired_tools[tid]['result'] = output
else:
# Fallback: if no ID, try matching last entry in final_tool_calls that has no result
for old_call in reversed(final_tool_calls):
if not old_call['result']:
old_call['result'] = output
break
if kind == 'response' and 'usage' in payload:
u = payload['usage']
for k in ['input_tokens', 'output_tokens', 'cache_read_input_tokens', 'cache_creation_input_tokens', 'total_tokens']:
if k in new_usage: new_usage[k] += u.get(k, 0) or 0
tier = entry.get('source_tier', 'main')
if tier in new_mma_usage:
new_mma_usage[tier]['input'] += u.get('input_tokens', 0) or 0
new_mma_usage[tier]['output'] += u.get('output_tokens', 0) or 0
new_token_history.append({
'time': ts,
'input': u.get('input_tokens', 0) or 0,
'output': u.get('output_tokens', 0) or 0,
'model': entry.get('model', 'unknown')
})
if kind == "history_add": if kind == "history_add":
content = payload.get("content", payload.get("text", payload.get("message", ""))) content = payload.get("content", payload.get("text", payload.get("message", "")))
@@ -1088,11 +1159,47 @@ class AppController:
self._set_status(f"log load error: {e}") self._set_status(f"log load error: {e}")
return return
self.session_usage = new_usage
self.mma_tier_usage = new_mma_usage
self._token_history = new_token_history
if new_token_history:
try:
import datetime
first_ts = new_token_history[0]['time']
dt = datetime.datetime.strptime(first_ts, '%Y-%m-%dT%H:%M:%S')
self._session_start_time = dt.timestamp()
except:
self._session_start_time = time.time()
self.prior_session_entries = entries self.prior_session_entries = entries
self.prior_disc_entries = disc_entries self.prior_disc_entries = disc_entries
self.prior_tool_calls = final_tool_calls
self.is_viewing_prior_session = True self.is_viewing_prior_session = True
self._trigger_gui_refresh()
self._set_status(f"viewing prior session: {session_dir.name} ({len(entries)} entries)") self._set_status(f"viewing prior session: {session_dir.name} ({len(entries)} entries)")
def cb_exit_prior_session(self):
self.is_viewing_prior_session = False
if self._current_session_usage:
self.session_usage = self._current_session_usage
self._current_session_usage = None
if self._current_mma_tier_usage:
self.mma_tier_usage = self._current_mma_tier_usage
self._current_mma_tier_usage = None
if self._current_token_history is not None:
self._token_history = self._current_token_history
self._current_token_history = None
if self._current_session_start_time is not None:
self._session_start_time = self._current_session_start_time
self._current_session_start_time = None
self.prior_session_entries.clear()
self.prior_disc_entries.clear()
self.prior_tool_calls.clear()
self._trigger_gui_refresh()
self._set_status('idle')
def cb_prune_logs(self) -> None: def cb_prune_logs(self) -> None:
"""Manually triggers the log pruning process with aggressive thresholds.""" """Manually triggers the log pruning process with aggressive thresholds."""
self._set_status("Manual prune started (Age > 0d, Size < 100KB)...") self._set_status("Manual prune started (Age > 0d, Size < 100KB)...")

View File

@@ -190,15 +190,12 @@ class App:
self._new_preset_name = "" self._new_preset_name = ""
self._show_save_preset_modal = False self._show_save_preset_modal = False
self._comms_log_cache: list[dict[str, Any]] = [] self._comms_log_cache: list[dict[str, Any]] = []
self._comms_log_dirty: bool = True
self._tool_log_cache: list[dict[str, Any]] = [] self._tool_log_cache: list[dict[str, Any]] = []
self._tool_log_dirty: bool = True
self._last_ui_focus_agent: Optional[str] = None self._last_ui_focus_agent: Optional[str] = None
self._log_registry: Optional[log_registry.LogRegistry] = None self._log_registry: Optional[log_registry.LogRegistry] = None
self.perf_profiling_enabled = False self.perf_profiling_enabled = False
self.perf_show_graphs: dict[str, bool] = {} self.perf_show_graphs: dict[str, bool] = {}
self._token_stats: dict[str, Any] = {} self._token_stats: dict[str, Any] = {}
self._token_stats_dirty: bool = True
self.perf_history: dict[str, list] = {"frame_time": [0.0] * 100, "fps": [0.0] * 100} self.perf_history: dict[str, list] = {"frame_time": [0.0] * 100, "fps": [0.0] * 100}
self._nerv_crt = theme_fx.CRTFilter() self._nerv_crt = theme_fx.CRTFilter()
self.ui_crt_filter = True self.ui_crt_filter = True
@@ -442,11 +439,14 @@ class App:
self._comms_log_dirty = False self._comms_log_dirty = False
if self._tool_log_dirty: if self._tool_log_dirty:
log_raw = list(self._tool_log) if self.is_viewing_prior_session:
if self.ui_focus_agent: self._tool_log_cache = self.prior_tool_calls
self._tool_log_cache = [e for e in log_raw if e.get("source_tier", "").startswith(self.ui_focus_agent)]
else: else:
self._tool_log_cache = log_raw log_raw = list(self._tool_log)
if self.ui_focus_agent:
self._tool_log_cache = [e for e in log_raw if e.get("source_tier", "").startswith(self.ui_focus_agent)]
else:
self._tool_log_cache = log_raw
self._tool_log_dirty = False self._tool_log_dirty = False
if self.show_windows.get("Context Hub", False): if self.show_windows.get("Context Hub", False):
@@ -1989,9 +1989,7 @@ def hello():
imgui.text_colored(vec4(255, 200, 100), "VIEWING PRIOR SESSION") imgui.text_colored(vec4(255, 200, 100), "VIEWING PRIOR SESSION")
imgui.same_line() imgui.same_line()
if imgui.button("Exit Prior Session"): if imgui.button("Exit Prior Session"):
self.is_viewing_prior_session = False self.controller.cb_exit_prior_session()
self.prior_session_entries.clear()
self.prior_disc_entries.clear()
self._comms_log_dirty = True self._comms_log_dirty = True
imgui.separator() imgui.separator()
imgui.begin_child("prior_scroll", imgui.ImVec2(0, 0), False) imgui.begin_child("prior_scroll", imgui.ImVec2(0, 0), False)
@@ -2726,10 +2724,8 @@ def hello():
if self.is_viewing_prior_session: if self.is_viewing_prior_session:
imgui.same_line() imgui.same_line()
if imgui.button("Exit Prior Session"): if imgui.button("Exit Prior Session"):
self.is_viewing_prior_session = False self.controller.cb_exit_prior_session()
self.prior_session_entries.clear()
self._comms_log_dirty = True self._comms_log_dirty = True
self.ai_status = "idle"
imgui.separator() imgui.separator()
imgui.text_colored(C_OUT, "OUT") imgui.text_colored(C_OUT, "OUT")