Skip to content

ReActV2: replay a stored answer turn under finish: :submit and :tools - #356

Merged
deepfates merged 1 commit into
mainfrom
react-v2-replay-host-answer-under-submit
Oct 17, 2026
Merged

deepfates merged 1 commit into
mainfrom
react-v2-replay-host-answer-under-submit

Conversation

@deepfates

@deepfates deepfates commented Oct 17, 2026 •

Copy link
Copy Markdown
Owner

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 :submit for every program with finish: :submit or finish: :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 both history_replay: :trajectory and :actions.

Request for a history of one stored turn {ticket: "Recap notice", reply: "THE RECAP TEXT"}, then a new ticket, before this change:

finish replay messages after system
auto trajectory / actions user "Recap notice", assistant "THE RECAP TEXT", user "New event"
submit trajectory / actions user "Recap notice", user "New event"
tools trajectory / actions user "Recap notice", user "New event"

Turns the loop writes itself are not affected: a plain-text answer step stores next_thought beside the output, and a submit answer stores the submit call and its result, so both already replay.

The change

step_turn/2 reads 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 under submit (test/react_v2_ending_switch_test.exs). The history the caller holds is unchanged.

What changes in requests: under finish: :submit and :tools, one assistant message holding the stored output now follows the stored turn's inputs. Nothing else in any request changes. Under finish: :auto, a one-output signature whose output is constrained (an enum, a pattern) or not typed string, which ends through submit, 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 of finish: :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.

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
deepfates merged commit 1a2a432 into main Oct 17, 2026
13 checks passed
@deepfates
deepfates deleted the react-v2-replay-host-answer-under-submit branch October 17, 2026 21:13
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.
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