Skip to content

fix: Validate user message parts and agent transfer targets (v1) - #6798

Merged
GWeale merged 2 commits into
v1from
backport-v1-pr07
Aug 19, 2026
Merged

fix: Validate user message parts and agent transfer targets (v1)#6798
GWeale merged 2 commits into
v1from
backport-v1-pr07

Conversation

@GWeale

@GWeale GWeale commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

This PR ports two validation fixes to the v1 branch:

  1. fix: Reject function_call parts in user messages (upstream 283e92ef)

    • runner.run_async(new_message=...) raises ValueError when any part of the message carries a function_call. Function responses are unaffected.
    • BaseLlmFlow._send_to_model raises the same ValueError for content arriving on a live request queue.
    • Callers seeding a session with a synthetic tool call need to drop that part; there is no opt-out. The CLI web server's /run returns 500 for such a request.
  2. fix: Check that a transfer target is a sibling agent (upstream fa18d26a, closes disallow_transfer_to_peers=True can be bypassed #3850)

    • _get_agent_to_run raises ValueError when the calling LlmAgent sets disallow_transfer_to_peers=True and the resolved target is a peer.
    • Transfer to self, transfer to a parent, and transfers from a non-LlmAgent caller are unchanged.
    • Clear disallow_transfer_to_peers to let the transfer through.

GWeale added 2 commits August 17, 2026 22:54
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.
@GWeale GWeale changed the title fix: Port user-message and agent-transfer validation fixes to v1 fix: Validate user message parts and agent transfer targets (v1) Aug 19, 2026
@GWeale
GWeale merged commit d830355 into v1 Aug 19, 2026
14 checks passed
@GWeale
GWeale deleted the backport-v1-pr07 branch August 20, 2026 00:04
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.

3 participants