Skip to content

feat(buzz-agent): surface stop reason and silent-turn WARN in telemetry - #7038

Merged
wpfleger96 merged 4 commits into
mainfrom
wpfleger/agent-silent-turn-telemetry
Aug 29, 2026
Merged

feat(buzz-agent): surface stop reason and silent-turn WARN in telemetry#7038
wpfleger96 merged 4 commits into
mainfrom
wpfleger/agent-silent-turn-telemetry

Conversation

@wpfleger96

@wpfleger96 wpfleger96 commented Aug 29, 2026

Copy link
Copy Markdown
Member

What

Two telemetry additions to make a known silent-death failure mode visible in harness logs.

1. stop field on llm: call completed INFO (crates/buzz-agent/src/llm.rs)

The ProviderStop value was already parsed and stored on LlmResponse but never emitted in the log line. Without it, "model chose end_turn" vs "gateway truncated/refused" is indistinguishable from telemetry alone.

2. WARN on silent-turn signature (crates/buzz-agent/src/agent.rs)

Emits a WARN when a turn produces no publish, no visible assistant text, and either near-zero or absent output tokens. The WARN logic is extracted into warn_if_silent_turn (pure synchronous function) so the seam is testable without the async run loop.

Three independent gates before the WARN fires:

  1. !buzz_reply_call_seen — no publish attempt in any round, tracked unconditionally via the existing is_buzz_reply_call matcher. Read-only tool calls do NOT suppress the WARN; a turn that ran tools but never published and died at 3 tokens is still a silent death.
  2. text_is_empty — no visible assistant text in the final round. A terse reply like "OK" (≤12 tokens, non-empty) is not a silent death.
  3. Token check — two distinct WARN messages:
    • Some(t) where t <= 12: near-zero token count, the observed failure signature (2–12 tokens)
    • None usage: provider omitted token counts entirely, separately diagnostic

Tests use a scoped tracing_subscriber layer (same pattern as the existing stall-warn tests in llm.rs) to exercise the WARN seam directly:

  • Canonical signature (no publish, no text, 4 tokens) → 1 WARN
  • Non-empty assistant text → 0 WARNs
  • Publish seen → 0 WARNs
  • None usage (no publish, no text) → 1 WARN

Why

Recurring silent-death incident in a specific agent×channel combination: sessions die with 1 LLM call, 2–12 output tokens, no tool calls, no message, no error — recorded as a "successful" turn. The harness log shows the token count but not the stop_reason, leaving the root cause undiagnosable without request-level tracing. The observed shape also includes tool-step-then-3-token-death (one tool call, then silence) — the publish-aware gate catches both shapes.

Context thread: buzz://message?channel=91fd9ca1-cf04-4ef7-b18f-aa2aee55692b&id=e3f1693f2e29f26a0c840f8054d592270c1504beacdc1d9c2063d8ab82960a06

Scope

Logging and telemetry only. No behavior change, no retry-logic change, no stop-reason mapping change.

Add two telemetry improvements to make the silent-death failure mode
visible in harness logs.

1. Emit `stop` on the existing `llm: call completed` INFO line in
   `llm.rs`. The `ProviderStop` value was already parsed and carried on
   `LlmResponse` but never logged, leaving "model chose end_turn" vs
   "gateway truncated/refused" indistinguishable from telemetry alone.

2. Log a WARN in `agent.rs` when a turn ends with no tool calls and
   output tokens below a conservative threshold (< 10). This is the
   exact signature observed in the silent-death incidents: one LLM call,
   2–12 output tokens, no actions, no message posted. The WARN carries
   the `stop` reason and token count so a single re-ping in an affected
   channel identifies the failure class directly from the log.

Neither change alters turn-handling logic, retry behavior, or stop-
reason mapping semantics. The WARN is diagnostic only.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
@wpfleger96
wpfleger96 requested a review from a team as a code owner August 29, 2026 18:45
@wpfleger96
wpfleger96 deployed to codex-review August 29, 2026 18:45 — with GitHub Actions Active
@github-actions github-actions Bot added the codex-security-review-current The posted Codex security review matches its recorded range. label Aug 29, 2026
@github-actions

github-actions Bot commented Aug 29, 2026

Copy link
Copy Markdown

🔐 Codex Security Review

Status: review required for the current range.

The current range is 00e61eafa917d296104006576b7a2ddbfd58bb5a...bff19c6479ddf7ccfa1ed240106e195b305281b2.
A new review must complete for this exact range. When manual authorization
is required, a Block organization member must comment exactly
@buzz-security-review bff19c6479ddf7ccfa1ed240106e195b305281b2 to authorize a new review.
Any previous review applies only to its recorded range.

…e boundary, None separation

Three review fixes (all agent.rs):

1. Turn-level gate: add per-run `any_tool_call_seen` flag, updated
   unconditionally when tool calls execute.  Gate the WARN on
   `!any_tool_call_seen` so a normal multi-round turn (tools ran in
   prior rounds, short final completion is expected) is never mislabeled
   as a silent death.

2. Inclusive threshold: change predicate to `output_tokens <=
   SILENT_TURN_TOKEN_THRESHOLD` (was `<`) and raise the constant from
   10 to 12 to include the full observed failure range (2–12).  The
   `is_silent_turn` signature changes from `Option<u64>` to `u64` —
   caller now handles None explicitly.

3. Separate None branch: providers that omit usage entirely are a
   distinct diagnostic case, not "near-zero tokens".  Emit a separate
   WARN message for the None arm rather than equating it with low
   output counts; fixes the false-positive on any normal no-tool
   response from a usage-omitting provider.

Tests updated: boundary tests now cover 0/12 (inclusive edge) and
13/large (above); new negative test proves the combined gate is silent
when any_tool_call_seen is true even with zero final-round tokens.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
@github-actions github-actions Bot removed the codex-security-review-current The posted Codex security review matches its recorded range. label Aug 29, 2026
@wpfleger96
wpfleger96 deployed to codex-review August 29, 2026 18:57 — with GitHub Actions Active
@github-actions github-actions Bot added the codex-security-review-current The posted Codex security review matches its recorded range. label Aug 29, 2026
…eam tests

Four review fixes (agent.rs):

1. Publish-aware gate: replace any_tool_call_seen with unconditional
   buzz_reply_call_seen (via existing is_buzz_reply_call).  Read-only
   tool calls no longer suppress the WARN — a turn that ran tools but
   never published then died at 3 tokens is a silent death.  Only a
   genuine publish suppresses it.

2. Text check: capture response.text.trim().is_empty() before the move
   into history.push, and add it as a gate on warn_if_silent_turn so
   a terse reply like "OK" (non-empty text, ≤12 tokens) is not labeled
   a silent death.

3. Extracted warn_if_silent_turn: pull the WARN emit block into a
   pure synchronous free function taking (buzz_reply_call_seen,
   text_is_empty, output_tokens, stop).  The run() call site becomes
   a single function call; the seam is directly testable.

4. Seam tests: replace the tautology negative test with 4 tests using
   a scoped tracing_subscriber layer (same pattern as the existing
   stall-warn tests in llm.rs) that counts WARNs from warn_if_silent_turn
   at the actual emission site:
   - canonical signature (no publish, no text, 4 tokens) → 1 WARN
   - non-empty text present → 0 WARNs
   - publish seen → 0 WARNs
   - None usage (no publish, no text) → 1 WARN (distinct message)

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
@github-actions github-actions Bot removed the codex-security-review-current The posted Codex security review matches its recorded range. label Aug 29, 2026
… "no tool calls"

The gate is publish-aware, not tool-call-aware, so the message strings
were inaccurate for the read-only-tool → 3-token-death shape the WARN
now covers. Wording only; no logic change.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
@wpfleger96
wpfleger96 merged commit eed74bd into main Aug 29, 2026
41 of 42 checks passed
@wpfleger96
wpfleger96 deleted the wpfleger/agent-silent-turn-telemetry branch August 29, 2026 23:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant