Repository navigation
ReActV2: replay a stored answer turn under finish: :submit and :tools - #356
Merged
Merged
Conversation
A turn a host stores with the task's inputs and its one output, and no step of the loop's own (a recap that stands in for the earlier conversation, say), is read as a step that answered in text before any adapter formats it. Since #343 that reading was gated on the program ending in plain text (`finish: :auto`), so under `finish: :submit` and `finish: :tools` the turn replayed only its inputs, under either history replay: the model read the event and never the answer stored with it. Read it the same way under every ending. The turn carries the task's output, so it is an answer, never a thought, and gets no unsent line, exactly as a plain-text loop's answer step replayed under submit does. Only the request changes; the history the caller holds does not.
deepfates
added a commit
that referenced
this pull request
Oct 17, 2026
* ReActV2: replay a stored answer turn under finish: :submit and :tools A turn a host stores with the task's inputs and its one output, and no step of the loop's own (a recap that stands in for the earlier conversation, say), is read as a step that answered in text before any adapter formats it. Since #343 that reading was gated on the program ending in plain text (`finish: :auto`), so under `finish: :submit` and `finish: :tools` the turn replayed only its inputs, under either history replay: the model read the event and never the answer stored with it. Read it the same way under every ending. The turn carries the task's output, so it is an answer, never a thought, and gets no unsent line, exactly as a plain-text loop's answer step replayed under submit does. Only the request changes; the history the caller holds does not. * Prepare Imp 0.16.1 release Version 0.16.1 with tag links for v0.16.1; install lines stay ~> 0.16.0, as for earlier patch releases. The changelog's Unreleased section goes under 0.16.1, and the release notes describe #356. A patch: #356 adds no option and no public API, and fixes how ReActV2 replays a stored answer turn under finish: :submit and :tools.
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.
What was wrong
A history turn a host stores with the task's inputs and its one output, and no step of the loop's own, is meant to replay as the model's message holding that output (CHANGELOG 0.6.0: "a stored turn that carries only the task's answer is replayed as that answer"). ReActV2 does this in
step_turn/2, which reads such a turn as a step that answered in text (next_thought= the answer, no calls) before any adapter formats it.Since #343 that reading was gated on
text_output(signature, finish), which is:submitfor every program withfinish: :submitorfinish: :tools. So under those endings the turn was passed through untouched, and the adapter rendered only the step outputs it found (next_thought,tool_calls), of which the turn has none. The model's request carried the turn's inputs as a user message and then nothing: no assistant message, under bothhistory_replay: :trajectoryand:actions.Request for a history of one stored turn
{ticket: "Recap notice", reply: "THE RECAP TEXT"}, then a new ticket, before this change:Turns the loop writes itself are not affected: a plain-text answer step stores
next_thoughtbeside the output, and a submit answer stores thesubmitcall and its result, so both already replay.The change
step_turn/2reads a stored answer turn the same way under every ending: it requires a one-output signature and a string value, not a plain-text ending. The turn carries the task's output, so the Chat adapter treats it as an answer, never as a thought: no "not sent" line follows it, the same as a plain-text loop's answer step replayed undersubmit(test/react_v2_ending_switch_test.exs). The history the caller holds is unchanged.What changes in requests: under
finish: :submitand:tools, one assistant message holding the stored output now follows the stored turn's inputs. Nothing else in any request changes. Underfinish: :auto, a one-output signature whose output is constrained (an enum, a pattern) or not typed string, which ends throughsubmit, gets the same replay when the stored value is a string. It too showed only the inputs before.Tests
test/react_v2_host_answer_turn_test.exs: for each offinish: :auto | :submit | :tools脳history_replay: :trajectory | :actions, the request after a stored answer turn is user (inputs), assistant (the answer), user (new inputs). Four of the six fail without the change: submit and tools, both replays. One more test checks that the returned history keeps the turn as it was written.mix check: 3728 tests, 0 failures.A patch release: no option and no public API is added.