diff --git a/src/mnemosyne/gateway.py b/src/mnemosyne/gateway.py index 047c1f7..0f528b8 100644 --- a/src/mnemosyne/gateway.py +++ b/src/mnemosyne/gateway.py @@ -1419,30 +1419,27 @@ def _apply_fidelity(payload: dict, session: "Session") -> None: # (Same fix as _update_fidelity_pressure — FM's total_tokens() is only # a fraction of the real context, so internal pressure is always NORMAL.) obj_tokens = fm.total_tokens() + saved_ws = fm.window_size if obj_tokens > 0 and fm.window_size > 0: real_pressure_ratio = session.token_state.get("last_effective", 0) / fm.window_size if real_pressure_ratio > 0: - saved_ws = fm.window_size fm.window_size = max(1, int(obj_tokens / real_pressure_ratio)) - pressure = fm.current_pressure() - fm.window_size = saved_ws - else: - pressure = fm.current_pressure() - else: - pressure = fm.current_pressure() + pressure = fm.current_pressure() if pressure > PressureZone.NORMAL: + # Keep scaled window during degrade() so it sees correct pressure transitions = fm.degrade(turn) for obj_id, old_level, new_level in transitions: transitions_logged.append(f"{obj_id[:8]}:{old_level.name}→{new_level.name}") + fm.window_size = saved_ws - if transitions_logged: - print( - f" {_DIM}[{session.id}] fidelity: pressure={pressure.name}, " - f"degraded {len(transitions_logged)} objects: " - f"{', '.join(transitions_logged[:5])}" - f"{'...' if len(transitions_logged) > 5 else ''}{_RESET}", - file=sys.stderr, - ) + if transitions_logged: + print( + f" {_DIM}[{session.id}] fidelity: pressure={pressure.name}, " + f"degraded {len(transitions_logged)} objects: " + f"{', '.join(transitions_logged[:5])}" + f"{'...' if len(transitions_logged) > 5 else ''}{_RESET}", + file=sys.stderr, + ) # ── Gateway factory ────────────────────────────────────────────────────── @@ -1665,6 +1662,39 @@ def create_app( "session_tokens": total_tokens, } + @app.get("/api/fidelity") + async def api_fidelity(session_id: str | None = None) -> dict[str, Any]: + """Debug endpoint: expose FidelityManager state per session.""" + all_sessions = sessions.all() + out: dict[str, Any] = {} + for sid, sess in all_sessions.items(): + if session_id and sid != session_id: + continue + fm = sess.fidelity_manager + obj_count = len(fm._objects) + obj_tokens = fm.total_tokens() + dist: dict[int, int] = {} + for obj in fm._objects.values(): + dist[obj.current_fidelity] = dist.get(obj.current_fidelity, 0) + 1 + last_eff = sess.token_state.get("last_effective", 0) + real_ratio = last_eff / fm.window_size if fm.window_size > 0 else 0 + out[sid] = { + "object_count": obj_count, + "object_tokens": obj_tokens, + "window_size": fm.window_size, + "real_pressure_ratio": round(real_ratio, 3), + "internal_pressure": fm.current_pressure().name if obj_count > 0 else "NO_OBJECTS", + "last_effective_tokens": last_eff, + "fidelity_distribution": dist, + "thresholds": { + "caution": fm.threshold_caution, + "warning": fm.threshold_warning, + "critical": fm.threshold_critical, + "emergency": fm.threshold_emergency, + }, + } + return out + @app.get("/api/blocks") async def api_blocks(session_id: str | None = None) -> dict[str, Any]: """Debug endpoint: expose BlockStore state per session."""