Skip to content

Reject runtime tool protocol events during session initialization #5290

@petrmarinec

Description

@petrmarinec

Summary

The session creation API accepts an optional events list and appends those events directly to the new session. These events can currently include internal ADK runtime/tool protocol fields such as function_call, function_response, long_running_tool_ids, and actions.requested_tool_confirmations.

This allows client-supplied session initialization data to be treated later as ADK-generated tool state. In particular, the HITL confirmation resolver can consume a seeded adk_request_confirmation function call with an embedded originalFunctionCall, then resume that embedded registered tool call when a matching confirmation response is sent.

Affected code

  • src/google/adk/cli/adk_web_server.py
  • src/google/adk/flows/llm_flows/request_confirmation.py

Problem

Session initialization is useful for restoring conversation history, but runtime-only tool protocol fields should not cross the client/API trust boundary as authoritative ADK-generated state.

A client-provided event can currently seed data that looks like an internal confirmation request. The confirmation resolver only needs the confirmation function-call id and originalFunctionCall payload to map the later confirmation response back to a tool call. That can cause a registered tool to be invoked without a real prior model function call and without a real prior ADK-generated confirmation request.

Expected behavior

Client-supplied session initialization events should be limited to non-runtime conversation history. Function calls, function responses, long-running tool ids, and internal EventActions runtime fields should be rejected at the HTTP session initialization boundary.

The confirmation resolver should also only resume tool calls that are backed by real prior function-call and confirmation-request state in the current event history.

Proposed fix

I have a PR prepared that:

  • rejects runtime/tool protocol fields in CreateSessionRequest.events before creating the session
  • still allows text-only initial session history
  • requires confirmation resumption to match a prior original function call and prior requested_tool_confirmations state
  • keeps existing HITL confirmation behavior working

Validation

The PR includes regression tests covering:

  • text-only session initialization is still accepted
  • session initialization rejects function-call/function-response runtime events
  • session initialization rejects internal runtime action metadata
  • forged confirmation requests do not resume tools
  • existing HITL confirmation runner flows still pass

Local validation:

  • python -m pyink --check src/google/adk/flows/llm_flows/request_confirmation.py src/google/adk/cli/adk_web_server.py tests/unittests/flows/llm_flows/test_request_confirmation.py tests/unittests/cli/test_fast_api.py
  • python -m pytest tests/unittests/flows/llm_flows/test_request_confirmation.py tests/unittests/cli/test_fast_api.py::test_create_session_accepts_initial_text_events tests/unittests/cli/test_fast_api.py::test_create_session_rejects_runtime_tool_events tests/unittests/cli/test_fast_api.py::test_create_session_rejects_runtime_action_events tests/unittests/runners/test_run_tool_confirmation.py -q

Result: 17 passed.

I also ran tests/unittests/cli/test_fast_api.py; on Windows it has unrelated baseline failures that I reproduced on clean origin/main: two CRLF assertion failures in builder GET tests and two A2A temporary-directory teardown errors. Excluding those baseline Windows-only cases, the FastAPI file passes locally: 61 passed, 4 deselected.

Metadata

Metadata

Labels

web[Component] This issue will be transferred to adk-web

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions