Repository navigation
fix(cot_agent): ReAct parser: stale JSON flush state, spurious flags, final-answer variants, EOF caches - #3952
Merged
crazywoola merged 1 commit intoSep 28, 2026
Conversation
…final-answer variants, dropped EOF prefixes
- Reset the prefix matcher state after a completed JSON blob flush so
a prefix right after a blob ({...}Action: / {...}FinalAnswer:) is no
longer leaked as thought text or blocks live answer streaming
({, }, tab and CR are now accepted as prefix delimiters).
- Only flag JSON blobs as parse failures when they are action-shaped
(emitted after Action: or carrying action-ish keys); innocent JSON
such as citations, markdown links or arbitrary objects is now plain
thought text, so the round is no longer killed by a spurious
"Action parse failed".
- Accept the compact "FinalAnswer" and underscore "final_answer" JSON
action names as final answers via a shared is_final_action()
predicate used by the strategy (the SDK AgentScratchpadUnit.is_final
spellings remain covered).
- Flush partial prefix matcher caches at stream end so a response cut
mid-prefix no longer silently drops those characters.
- Coerce malformed (non-dict/str) action_input to a JSON string so a
list/scalar input never raises out of the parser.
crazywoola
approved these changes
Sep 28, 2026
crazywoola
temporarily deployed
to
agent-strategies/cot_agent
September 28, 2026 02:35 — with
GitHub Actions
Inactive
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four ReAct stream-parser fixes in
output_parser/cot_output_parser.py(+ the sharedis_final_action()predicate and its three call sites instrategies/ReAct.py), each with a regression test that fails against the current code:last_characterkept the closing}/], so a prefix right after a blob ({...}Action:{...},{...}FinalAnswer:) was leaked as literal thought text (and}FinalAnswer:additionally blocked live answer streaming). Fix: resetlast_characterto a delimiter in the flush block and accept\t/\ras prefix delimiters.THINKINGwas flagged, so innocent JSON (citations[1], markdown links,{}, arbitrary objects) killed the tool round with a misleading error. Fix: only flag action-shaped blobs (emitted right afterAction:or carrying action-ish keys); everything else is plain thought text.FinalAnswer/final_answernot recognized as final — only the spaced"final answer"was treated as final, so the compact/underscore JSON action names fell into "there is not a tool named ..." and wasted a round. Fix: sharedis_final_action()predicate (lower + strip_/spaces) used at the round-finality check and both assistant-history formatters; the SDKis_final()spellings remain covered....FinalAns) silently dropped the buffered characters. Fix: flush all threePrefixMatchercaches as text in the current state at stream end.Also: malformed (non-dict/str)
action_input(e.g. a list) is coerced to a JSON string so it never raises out of the parser (strategy-side handling is a documented follow-up).Testing
test_cot_output_parser.pyandtest_react.py, all verified to fail against the pre-fix code (stashed-source run: 17 failed) and pass with the fix.{}/arbitrary JSON not flagged; arbitrary JSON around a real action (real action wins);Action:-prefixed invalid JSON still flagged;}Action:/}FinalAnswer:adjacency; tab/CR before prefixes; truncated prefix at EOF; listaction_inputcoercion;FinalAnswer/final_answer/final answervariants through the full strategy (tool not invoked, final answer streamed).ruff checkon the touched files: zero new findings (10 pre-existing E402 from the tests'sys.pathpattern, unchanged).Notes
is_final_actionpredicate/call sites + tests + manifest version. No strategy-loop, budget, truncation, prompt, or YAML changes.Release Notes
}Action:/}FinalAnswer:), and live final-answer streaming is no longer blocked.{}) no longer triggers a spurious "Action parse failed" error.FinalAnswerandfinal_answerJSON action names are now recognized as final answers.Change Type