docs(examples): add force_tool_first_turn hook example#2014
Open
gold-silver-copper wants to merge 1 commit into
Open
docs(examples): add force_tool_first_turn hook example#2014gold-silver-copper wants to merge 1 commit into
gold-silver-copper wants to merge 1 commit into
Conversation
Demonstrates a per-turn RequestPatch footgun and its fix. A RequestPatch is per-turn and re-fires on every turn, so an AgentHook that patches tool_choice = Required on every CompletionCall forces a tool call on every turn — the model never gets a turn to stop calling tools and answer, so the run loops until max_turns and fails with MaxTurnsError. The example runs that footgun first (catching the MaxTurnsError), then the fix: gate the patch on ctx.turn() == 1 so the tool is forced only on the first turn and later turns resolve normally. Registered as a workspace example and listed in examples/README.md. Requires OPENAI_API_KEY to run.
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
Adds a runnable example,
examples/force_tool_first_turn, that demonstrates a real per-turnRequestPatchfootgun in the hook system and its fix.The pattern
A hook can force the model to call a tool by returning
Flow::patch_request(RequestPatch::new().tool_choice(ToolChoice::Required))onStepEvent::CompletionCall. ButRequestPatchis per-turn and non-sticky —CompletionCallre-fires on every turn — so applyingRequiredunconditionally forces a tool call on every turn. The model never reaches a turn where it can stop calling tools and write the final answer, so the run loops untilmax_turnsand fails withPromptError::MaxTurnsError.The fix is to gate the patch on the turn index:
The example runs the footgun first (and catches the resulting
MaxTurnsError), then runs the fix, so the difference is visible end-to-end.Changes
examples/force_tool_first_turn/{Cargo.toml,src/main.rs}— the example (auto-registered via theexamples/*workspace glob).examples/README.md— one table row for the new example.Cargo.lock— the new package entry.No production code changes.
Validation
cargo check -p force_tool_first_turn— clean.cargo clippy -p force_tool_first_turn— clean.cargo fmt -p force_tool_first_turn— clean.Requires
OPENAI_API_KEYto run (an example, not a test).