fix: Validate user message parts and agent transfer targets (v1) - #6798
Merged
Conversation
Port of "prevent model bypass in resumable mode by rejecting user-authored function calls" from main. Before, a `function_call` part supplied by the caller in a user message was persisted to the session unchecked, both through `Runner._append_new_message_to_session` and through the live path in `BaseLlmFlow._send_to_model`. The stored call then looked exactly like one the model had produced, so the tool-execution machinery would pick it up. A client could therefore run a registered tool without the model ever seeing the request. Now both append sites raise `ValueError` when any part of a user message carries a `function_call`. Behaviour change: `runner.run_async(new_message=...)` raises `ValueError` if the message contains a `function_call` part. Callers that seeded a session with a synthetic tool call this way need to change. Function *responses* are unaffected, and no caller in this repository passes a `function_call` as a user message. Upstream applies two guards in `runners.py`. The second is on `_append_user_event`, which does not exist on this branch; every append path here funnels through `_append_new_message_to_session`, so one guard covers them all.
Port of "check if transfer target is a sibling agent" from main, originally contributed as #3862 and closing #3850. Before, `disallow_transfer_to_peers=True` only shaped what the model was told: it kept peers out of the transfer instruction and out of the `transfer_to_agent` enum. If the model named a sibling anyway, having picked the name out of the conversation history or the user's prompt, `_get_agent_to_run` looked it up in the agent tree and handed control over. The setting was a hint, not a rule. Now `_get_agent_to_run` raises `ValueError` when an `LlmAgent` with `disallow_transfer_to_peers` set resolves a target that shares its parent and is not itself. Behaviour change: an agent that sets `disallow_transfer_to_peers=True` and still transfers to a peer now raises instead of transferring. Transfer to self, transfer to a parent, and transfers from a caller that is not an `LlmAgent` are unchanged.
wukath
approved these changes
Aug 19, 2026
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.
This PR ports two validation fixes to the
v1branch:fix: Reject function_call parts in user messages(upstream283e92ef)runner.run_async(new_message=...)raisesValueErrorwhen any part of the message carries afunction_call. Function responses are unaffected.BaseLlmFlow._send_to_modelraises the sameValueErrorfor content arriving on a live request queue./runreturns 500 for such a request.fix: Check that a transfer target is a sibling agent(upstreamfa18d26a, closes disallow_transfer_to_peers=True can be bypassed #3850)_get_agent_to_runraisesValueErrorwhen the callingLlmAgentsetsdisallow_transfer_to_peers=Trueand the resolved target is a peer.LlmAgentcaller are unchanged.disallow_transfer_to_peersto let the transfer through.