Files
openswarm/backend/apps/agents/manager/run/empty_finish_telemetry.py
T
ciregenzandClaude Opus 5 10084b1b28 [eric] agents: split the delegation backstop and the quit telemetry into their own files
Both host files crossed the 300-line ceiling; the seams were already there (quick-tool wedge vs delegation backstop, ladder logic vs its telemetry).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018foyDoK19jjbYdudfzQVkZ
2026-08-24 22:07:31 -07:00

70 lines
3.2 KiB
Python

"""Telemetry for the silent-quit ladder, split out of empty_finish.py to keep that file to one job.
The two events answer different questions and must not be conflated: a NUDGE means we poked a mute
agent, which is the system working; an EXHAUSTION is the only one the user ever sees. Counting the
first and not the second is why "how often does the recovery fail" was unanswerable across 1,695
recorded nudges (ENG-399).
"""
import logging
from typeguard import typechecked
logger = logging.getLogger(__name__)
@typechecked
def report_nudge(session: object, session_id: str, input_tokens: int, tool_calls: int) -> None:
"""A silent quit is the hardest class to diagnose after the fact, so it carries the same
envelope as a hard error: without breadcrumbs you cannot see what the turn was doing."""
try:
from backend.apps.service.client import submit_diagnostic
from backend.apps.agents.core import flight_recorder as p_fr
p_n = int(getattr(session, "empty_finish_nudges", 0) or 0)
submit_diagnostic({
"kind": "empty_finish_nudge",
"session_id": session_id,
"model": getattr(session, "model", None),
"input_tokens": input_tokens,
"compacted": bool(getattr(session, "needs_fresh_session", False)),
"tool_calls": tool_calls,
"nudge": p_n,
"flight": p_fr.build_envelope(
session_id, "empty_finish_nudge", "silent_quit",
getattr(session, "model", None), "stream", p_n),
})
except Exception:
logger.debug("submit_diagnostic empty_finish_nudge failed", exc_info=True)
@typechecked
def report_exhausted(session: object, session_id: str) -> None:
"""The ONE outcome the user actually sees, and it was never recorded.
We counted 1,695 nudges on one install and zero outcomes, so "1,695 silent quits" read as alarm
when most of it is the ladder working. Only this event means someone lost an answer.
"""
try:
from backend.apps.service.client import submit_diagnostic
from backend.apps.agents.core import flight_recorder as p_fr
from backend.apps.agents.manager.run.empty_finish import count_tool_calls, turn_showed_work
p_work = turn_showed_work(session)
p_sub = "showed_work" if p_work else "no_progress"
p_n = int(getattr(session, "empty_finish_nudges", 0) or 0)
submit_diagnostic({
"kind": "empty_finish_exhausted",
"subkind": p_sub,
"session_id": session_id,
"model": getattr(session, "model", None),
"input_tokens": int((getattr(session, "tokens", None) or {}).get("input", 0) or 0),
"tool_calls": count_tool_calls(session),
"nudges_spent": p_n,
"quits_this_session": int(getattr(session, "empty_finish_total", 0) or 0),
"history_prefix_sent": getattr(session, "history_prefix_sent", None),
"flight": p_fr.build_envelope(
session_id, "empty_finish_exhausted", p_sub,
getattr(session, "model", None), "stream", p_n),
})
except Exception:
logger.debug("submit_diagnostic empty_finish_exhausted failed", exc_info=True)