Skip to content

agents: detect [END_OF_ANSWER] from text, not the provider stop reason - #1702

Merged
Evanfeenstra merged 1 commit into
mainfrom
end-marker-in-text
Sep 16, 2026
Merged

Evanfeenstra merged 1 commit into
mainfrom
end-marker-in-text

Conversation

@Evanfeenstra

Copy link
Copy Markdown
Collaborator

Problem

Every proper agent finish through Bifrost looked like a stall. The agents registered [END_OF_ANSWER] as a provider stop sequence, so Anthropic consumed the marker and the only evidence of a finish was the raw stop reason stop_sequence. Bifrost maps that lossily — stop_sequence → stop inbound, stop → end_turn outbound (core/providers/anthropic/utils.go, same in v1.6.2 and v1.8.6) — so needsContinuation saw end_turn with no marker in the text, nudged the model twice, and reported incomplete: stall. Hive's propose_code_change then refused a correct diff (stakwork/hive#5308 made that refusal explicit). Every repo_agent run behind the gateway paid two wasted rounds; a two-line change took 47s and 114k tokens.

Fix

Drop stopSequences: ["[END_OF_ANSWER]"] from the repo, graph, log, and jarvis sub-agents. The marker stays in the text, where createHasEndMarkerCondition, needsContinuation, and extractFinalAnswer already detect and strip it. That's the path every non-Anthropic provider was already on, and the only one that survives a gateway. OpenAI-compatible providers (plain stop either way) gain stall detection they never had. The rawFinishReason === "stop_sequence" check stays as harmless belt-and-braces.

turns.ts strips the marker before text becomes a reasoning Turn, so the protocol token never reaches the graph. Hive already strips it at its stream (useStreamProcessor) and MCP (orgMcpTools) boundaries.

Verification

  • test:node subset for repo/utils/turns/stream/log sessions: 108/108; tsc clean.
  • Local server, the exact Hive propose_code_change request that failed: status: completed, incomplete: undefined, 0 continuation nudges in the transcript, preview.ok with the two-file diff, marker present in the transcript text and absent from the returned content.

Follow-ups (not in this PR)

  • File the lossy stop-reason mapping upstream with Bifrost.
  • Hive's runCanvasAgent still registers the stop sequence; harmless there (nothing reads the raw reason) but could be unified.

Every proper finish through Bifrost looked like a stall. The agents
registered [END_OF_ANSWER] as a provider stop sequence, so Anthropic
consumed the marker and the only evidence of a finish was the raw stop
reason "stop_sequence". Bifrost maps that to "stop" inbound and "stop"
back to "end_turn" outbound (core/providers/anthropic/utils.go, v1.6.2
and v1.8.6 alike), so needsContinuation saw end_turn with no marker in
the text, nudged the model twice, and reported `incomplete: stall` —
which Hive's propose_code_change then refused, diff and all. Every
repo_agent run behind the gateway paid two wasted rounds.

Drop the stop sequence from the repo, graph, log, and jarvis sub-agents.
The marker stays in the text, where createHasEndMarkerCondition,
needsContinuation, and extractFinalAnswer already detect and strip it —
the path every non-Anthropic provider was on all along, and the only one
that survives a gateway. Providers that honor `stop` and report a plain
"stop" either way (OpenAI-compatible) gain stall detection they never
had. The rawFinishReason "stop_sequence" check stays as harmless
belt-and-braces.

turns.ts strips the marker before text becomes a reasoning Turn, so the
protocol token never reaches the graph. Hive already strips it at its
stream and MCP boundaries.

Verified against a local server with the exact Hive request that failed:
completed, no continuation nudges, preview.ok with the two-file diff, no
marker in the returned content.
@Evanfeenstra
Evanfeenstra merged commit 79202fd into main Sep 16, 2026
3 checks passed
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