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.
Summary
The session creation API accepts an optional
eventslist and appends those events directly to the new session. These events can currently include internal ADK runtime/tool protocol fields such asfunction_call,function_response,long_running_tool_ids, andactions.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_confirmationfunction call with an embeddedoriginalFunctionCall, then resume that embedded registered tool call when a matching confirmation response is sent.Affected code
src/google/adk/cli/adk_web_server.pysrc/google/adk/flows/llm_flows/request_confirmation.pyProblem
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
originalFunctionCallpayload 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
EventActionsruntime 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:
CreateSessionRequest.eventsbefore creating the sessionrequested_tool_confirmationsstateValidation
The PR includes regression tests covering:
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.pypython -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 -qResult: 17 passed.
I also ran
tests/unittests/cli/test_fast_api.py; on Windows it has unrelated baseline failures that I reproduced on cleanorigin/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.