[eric] agents: a REPEAT silent quit compacts from a 40% floor; Haik's opus-5 quits at ~149K, under the 180K trigger, so the band fix alone missed his storms (ENG-354)

This commit is contained in:
ciregenz
2026-08-19 11:32:29 -07:00
parent 8ae3f94d20
commit a66b0b0eaa
3 changed files with 52 additions and 2 deletions
+2
View File
@@ -139,6 +139,8 @@ class AgentSession(BaseModel):
pending_continuation_toolless: bool = False
# Silent-quit nudges spent since the user's last real message; hard-capped so an agent that keeps ending empty can't loop.
empty_finish_nudges: int = 0
# Lifetime silent-quit count for the session; unlike the per-user-message nudge counter this never resets, so a REPEAT quit is distinguishable from a first (Haik's storm sessions logged 130+ quits each).
empty_finish_total: int = 0
# One transparent expired-token retry per user ask; the second failure earns the honest banner (ENG-294).
auth_retry_used: bool = False
# Tool-call count at the last nudge: a re-nudge is only earned by NEW tool work since then.
@@ -57,11 +57,20 @@ def maybe_nudge_empty_finish(session: AgentSession, session_id: str) -> bool:
session.empty_finish_progress_mark = p_tool_calls
# At high context the silent quit is usually the model choking on the prompt itself, so
# re-sending the same bloat just burns a nudge; compact FIRST and retry distilled (ENG-354).
# Field data (Haik, 2026-08-19): opus-5 quits from ~149K, BELOW the 180K trigger, and his storm
# sessions logged 130+ quits each; a REPEAT quit therefore compacts from a much lower floor,
# because one failed nudge is proof the prompt itself is what the model is choking on.
import os as p_os
from backend.apps.agents.manager.context_budget import compact_trigger_tokens, maybe_compact
p_input = int(session.tokens.get("input", 0) or 0)
if p_input >= int(0.8 * compact_trigger_tokens(session)) and maybe_compact(session, force=True):
p_repeat = getattr(session, "empty_finish_total", 0) >= 1
session.empty_finish_total = getattr(session, "empty_finish_total", 0) + 1
p_floor = int((0.4 if p_repeat else 0.8) * compact_trigger_tokens(session))
# Drill seam: the ENG-354 negative control runs the exp.14 behavior (no compact) on identical bits.
p_disabled = p_os.environ.get("OSW_DISABLE_EMPTY_FINISH_COMPACT") == "1"
if not p_disabled and p_input >= p_floor and maybe_compact(session, force=True):
session.needs_fresh_session = True
logger.warning(f"Agent {session_id}: empty finish at {p_input} input tokens; compacted history before the nudge")
logger.warning(f"Agent {session_id}: empty finish at {p_input} input tokens (repeat={p_repeat}); compacted history before the nudge")
session.empty_finish_nudges += 1
session.pending_continuation = True
p_final = session.empty_finish_nudges >= NUDGE_HARD_CAP
+39
View File
@@ -163,3 +163,42 @@ def test_low_context_empty_finish_nudges_without_compacting():
assert maybe_nudge_empty_finish(s, "sid-low") is True
assert s.compacted_through_msg_id is None
assert getattr(s, "needs_fresh_session", False) is False
def test_repeat_quit_compacts_from_the_low_floor():
"""ENG-354 field data: opus-5 quits at ~149K, BELOW the 180K trigger; a repeat quit must compact anyway."""
from backend.apps.agents.manager.run.empty_finish import maybe_nudge_empty_finish
s = p_session(("user", "long task"),
("tool_call", {"tool": "Read", "input": {"file_path": "/a"}}),
("tool_result", {"text": "x"}),
("tool_call", {"tool": "Read", "input": {"file_path": "/b"}}),
("tool_result", {"text": "y"}),
("tool_call", {"tool": "Read", "input": {"file_path": "/c"}}),
("tool_result", {"text": "z"}))
s.context_window = 1_000_000
s.tokens["input"] = 100_000 # below the 144K first-quit floor, above the 72K repeat floor
assert maybe_nudge_empty_finish(s, "sid-r1") is True
assert s.compacted_through_msg_id is None, "first quit below the band must NOT compact"
# New user message resets the per-message counter but not the lifetime one; the loop consumed the pending continuation.
s.pending_continuation = False
s.empty_finish_nudges = 0
s.empty_finish_progress_mark = 0
assert maybe_nudge_empty_finish(s, "sid-r2") is True
assert s.compacted_through_msg_id is not None, "repeat quit must compact from the low floor"
assert s.needs_fresh_session is True
def test_drill_seam_disables_compaction(monkeypatch):
from backend.apps.agents.manager.run.empty_finish import maybe_nudge_empty_finish
monkeypatch.setenv("OSW_DISABLE_EMPTY_FINISH_COMPACT", "1")
s = p_session(("user", "t"),
("tool_call", {"tool": "Read", "input": {}}),
("tool_result", {"text": "x"}),
("tool_call", {"tool": "Read", "input": {}}),
("tool_result", {"text": "y"}),
("tool_call", {"tool": "Read", "input": {}}),
("tool_result", {"text": "z"}))
s.context_window = 1_000_000
s.tokens["input"] = 190_000
assert maybe_nudge_empty_finish(s, "sid-seam") is True
assert s.compacted_through_msg_id is None