fix: keep FM window scaled during degrade() and add /api/fidelity endpoint
Window was restored before degrade() was called, so FM always saw NORMAL pressure internally. Now keeps scaled window through the degrade call. Adds /api/fidelity debug endpoint showing FM state, object counts, pressure ratios, and fidelity distribution per session.
This commit is contained in:
parent
225b9b30f1
commit
4ffb93553c
1 changed files with 45 additions and 15 deletions
|
|
@ -1419,30 +1419,27 @@ def _apply_fidelity(payload: dict, session: "Session") -> None:
|
||||||
# (Same fix as _update_fidelity_pressure — FM's total_tokens() is only
|
# (Same fix as _update_fidelity_pressure — FM's total_tokens() is only
|
||||||
# a fraction of the real context, so internal pressure is always NORMAL.)
|
# a fraction of the real context, so internal pressure is always NORMAL.)
|
||||||
obj_tokens = fm.total_tokens()
|
obj_tokens = fm.total_tokens()
|
||||||
|
saved_ws = fm.window_size
|
||||||
if obj_tokens > 0 and fm.window_size > 0:
|
if obj_tokens > 0 and fm.window_size > 0:
|
||||||
real_pressure_ratio = session.token_state.get("last_effective", 0) / fm.window_size
|
real_pressure_ratio = session.token_state.get("last_effective", 0) / fm.window_size
|
||||||
if real_pressure_ratio > 0:
|
if real_pressure_ratio > 0:
|
||||||
saved_ws = fm.window_size
|
|
||||||
fm.window_size = max(1, int(obj_tokens / real_pressure_ratio))
|
fm.window_size = max(1, int(obj_tokens / real_pressure_ratio))
|
||||||
pressure = fm.current_pressure()
|
pressure = fm.current_pressure()
|
||||||
fm.window_size = saved_ws
|
|
||||||
else:
|
|
||||||
pressure = fm.current_pressure()
|
|
||||||
else:
|
|
||||||
pressure = fm.current_pressure()
|
|
||||||
if pressure > PressureZone.NORMAL:
|
if pressure > PressureZone.NORMAL:
|
||||||
|
# Keep scaled window during degrade() so it sees correct pressure
|
||||||
transitions = fm.degrade(turn)
|
transitions = fm.degrade(turn)
|
||||||
for obj_id, old_level, new_level in transitions:
|
for obj_id, old_level, new_level in transitions:
|
||||||
transitions_logged.append(f"{obj_id[:8]}:{old_level.name}→{new_level.name}")
|
transitions_logged.append(f"{obj_id[:8]}:{old_level.name}→{new_level.name}")
|
||||||
|
fm.window_size = saved_ws
|
||||||
|
|
||||||
if transitions_logged:
|
if transitions_logged:
|
||||||
print(
|
print(
|
||||||
f" {_DIM}[{session.id}] fidelity: pressure={pressure.name}, "
|
f" {_DIM}[{session.id}] fidelity: pressure={pressure.name}, "
|
||||||
f"degraded {len(transitions_logged)} objects: "
|
f"degraded {len(transitions_logged)} objects: "
|
||||||
f"{', '.join(transitions_logged[:5])}"
|
f"{', '.join(transitions_logged[:5])}"
|
||||||
f"{'...' if len(transitions_logged) > 5 else ''}{_RESET}",
|
f"{'...' if len(transitions_logged) > 5 else ''}{_RESET}",
|
||||||
file=sys.stderr,
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# ── Gateway factory ──────────────────────────────────────────────────────
|
# ── Gateway factory ──────────────────────────────────────────────────────
|
||||||
|
|
@ -1665,6 +1662,39 @@ def create_app(
|
||||||
"session_tokens": total_tokens,
|
"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")
|
@app.get("/api/blocks")
|
||||||
async def api_blocks(session_id: str | None = None) -> dict[str, Any]:
|
async def api_blocks(session_id: str | None = None) -> dict[str, Any]:
|
||||||
"""Debug endpoint: expose BlockStore state per session."""
|
"""Debug endpoint: expose BlockStore state per session."""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue