Skip to content

fix: auto-retry invisible degenerate terminal turns (#732) - #734

Merged
ranxianglei merged 1 commit into
masterfrom
2026-09-12_auto-mode-degenerate-turn
Sep 14, 2026
Merged

ranxianglei merged 1 commit into
masterfrom
2026-09-12_auto-mode-degenerate-turn

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

What

Fixes #732 — "AUTO model sometime stop".

A reasoning model can end a turn with only a thinking block (zero visible text, zero tool calls, status completed) — most often right after a post-compress re-request, where it sees the freshly-shrunk context and "wraps up" into a silent thought. The client then receives an empty completed turn and stalls until manually nudged.

Root cause (verified)

The user's log line at 14:43:32.513Z is the stop:

[degenerate-turn] responses: turn ended completed with zero visible text and zero tool calls (thinking present; no visible text emitted) … (#673)
  • Round 1 the model issued compress; bili executed it server-side and re-requested (round 2).
  • Round 2 deepseek-flash returned a reasoning-only completed turn → empty turn forwarded → agent stalled until the next request (14:46:30).
  • The second timestamp in the issue, 14:44:08.791Z, is an unrelated routine npm auto-update check.

#673 (#674) shipped only the [degenerate-turn] detector, described as "the groundwork for auto-retry" — the retry itself was never implemented. (The existing #371 fake-completion backstop detects a different shape, is opt-in/off by default, and only guards the first fetch, not loop rounds 2+.)

Fix

In src/loop/core.ts (runCompressLoop), after a round completes with nothing forwarded to the client yet (forwardedAny === false — true for these rounds on wires whose round>1 framing is suppressed, e.g. Responses) and the turn is a genuine silent thought, re-fetch once with an ephemeral continuation nudge. The nudge is appended only to the retry body — never committed to coreMessages/session state, so it is neither persisted nor replayed.

Guard rails:

Scoped to proxy mode automatically (the compress loop doesn't run in plugin mode).

Pre-flight

  • npm run typecheck ✅
  • npm test ✅ 1431 pass / 0 fail / 2 skipped (incl. new tests/loop-degenerate-retry.test.ts: D1 one invisible retry w/ nudge, D2 one-shot bound)
  • npm run build ✅ (dist self-contained)

@github-actions

github-actions Bot commented Sep 12, 2026 •

Copy link
Copy Markdown
Contributor

📦 Built Package Artifact

Branch: 2026-09-12_auto-mode-degenerate-turn (22c609c)

Option A — Install from npm PR tag (recommended)

npm install -g billion-context@pr-734

Each push to this PR publishes a new version under the pr-734 npm tag.

Option B — Download artifact

  1. Download the artifact from the Actions run
  2. Extract the tarball and install:
tar xzf billion-context-pr734.tgz
npm install -g package

This comment is automatically updated on each push.

A reasoning model can end a turn with ONLY a thinking block — zero visible
text, zero tool calls, status completed — most often right after a
post-compress re-request, where it sees the freshly-shrunk context and
"wraps up" into a silent thought. The client then receives an empty completed
turn and stalls until manually nudged (#732).

#673/#674 shipped the [degenerate-turn] detector as "the groundwork for
auto-retry" but never implemented the retry. This adds it: when nothing has
reached the client yet (forwardedAny=false — true for these rounds on wires
whose round>1 framing is suppressed, e.g. Responses) and the turn is a genuine
silent thought (sawThinking, not a legitimately empty/no-reasoning terminal),
re-fetch once with an ephemeral continuation nudge. One-shot per request; the
nudge is never committed to session state.
@ranxianglei
ranxianglei force-pushed the 2026-09-12_auto-mode-degenerate-turn branch from 8627545 to 22c609c Compare September 14, 2026 15:00
@ranxianglei
ranxianglei merged commit 9269bcc into master Sep 14, 2026
7 checks passed
This was referenced Sep 14, 2026
@ranxianglei
ranxianglei deleted the 2026-09-12_auto-mode-degenerate-turn branch October 15, 2026 05:32
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.

[BUG] In some cases, with Codex's auto model + DeepSeek, it will suddenly terminate automatically.

1 participant