mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-10 19:57:44 +02:00
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
70 lines
3.2 KiB
Python
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)
|