feat: rewrite react around raw history#9
Draft
isaacbmiller wants to merge 1 commit intocmpnd/react-native-toolsfrom
Draft
feat: rewrite react around raw history#9isaacbmiller wants to merge 1 commit intocmpnd/react-native-toolsfrom
isaacbmiller wants to merge 1 commit intocmpnd/react-native-toolsfrom
Conversation
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.
Why this PR exists
ReActis still a declarative DSPy module. What changes here is how the signature gets enacted.Before this PR,
ReActexecuted through a flattened trajectory dict and a syntheticfinishtool. That works, but it leaves a few real limitations:finishand a separate extract pass instead of being a typed commit of the declared outputsThis PR moves
ReActto a transcript-native runtime built onHistory.raw()while keeping the declarative signature model intact.What changes
History.raw()becomes the canonical execution state forReActfinishis replaced with typedsubmit(**signature_outputs)extract(history=...)remains as the fallback path, but it is normalized into the same terminal transcript shapetrajectoryremains only as a derived compatibility outputWhat this unlocks
1. Follow-up turns that refer to prior results
This PR makes the final user-facing answer part of the transcript, not just an extracted side effect.
That means patterns like this become well-founded:
The second turn now has a real antecedent in
history:That is a much better execution model than asking the model to infer meaning from a flattened trajectory blob.
2. A transcript that matches the actual runtime
The runtime now records real assistant/tool turns instead of encoding everything into
thought_i,tool_name_i,observation_i, etc.That has two benefits:
inspect_history()becomes a faithful debugging toolHistoryinstead of hidden in-memory stateThe compaction summaries that may appear in that history come from the underlying DSPy summary program introduced earlier in the stack, so even prompt compression stays within the DSPy execution model.
3. Declarative completion instead of ad hoc finish semantics
submit(**signature_outputs)commits the declared outputs directly.For a simple signature:
For a multi-output signature, completion is still typed and still canonical. The runtime materializes the final assistant message from the declared outputs rather than inventing a second free-form response channel.
4. A cleaner substrate for the next layer of ReAct features
This PR is the runtime rewrite, not the entire roadmap. But it creates the right foundation for:
DX after this change
The common call site does not get more complicated:
The new pattern this enables is follow-up interaction over prior execution state:
The important part is that
historyis now the canonical state of the run.trajectorystill exists for compatibility, but it is no longer the thing the runtime is built around.Compatibility and review guidance
ReActremains a declarative DSPy moduleextractis still present, but only as the fallback completion pathtrajectoryremains available as a derived compatibility outputReview this PR as the
ReActruntime rewrite itself. The adapter/native-tool substrate is intentionally below it in the stack.Diff
Validation
uv run pytest --deno -q tests/predict/test_react.py tests/predict/test_code_act.py tests/primitives/test_module.py -k "load_dspy_program_cross_version or test_react or test_code_act"