-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Description
Feature Request: Add state_delta Support to LiveRequest for WebSocket Live Mode
Is your feature request related to a problem? Please describe.
Currently, the HTTP POST /run endpoint supports updating session state via the state_delta parameter in RunAgentRequest. However, the WebSocket /run_live endpoint does not provide an equivalent mechanism to update session state when sending messages through LiveRequest.
This creates an inconsistency between the two APIs:
- HTTP
/run: Supportsstate_deltainRunAgentRequest→ passed torunner.run_async(state_delta=...) - WebSocket
/run_live:LiveRequestonly supportscontent,blob,activity_start,activity_end, andclosefields
When building applications that use live bidirectional streaming (especially for text-based interactions, not just audio), there's no direct way to update session state alongside user messages. This limitation forces developers to use workarounds like creating custom tools or parsing state updates from message content, which is less elegant and harder to maintain.
Describe the solution you'd like
Add a state_delta field to the LiveRequest class to enable state updates in live mode, similar to how it works in the standard /run endpoint.
Proposed Implementation:
- Extend
LiveRequestclass insrc/google/adk/agents/live_request_queue.py:
class LiveRequest(BaseModel):
"""Request send to live agents."""
model_config = ConfigDict(ser_json_bytes='base64', val_json_bytes='base64')
content: Optional[types.Content] = None
"""If set, send the content to the model in turn-by-turn mode."""
blob: Optional[types.Blob] = None
"""If set, send the blob to the model in realtime mode."""
activity_start: Optional[types.ActivityStart] = None
"""If set, signal the start of user activity to the model."""
activity_end: Optional[types.ActivityEnd] = None
"""If set, signal the end of user activity to the model."""
close: bool = False
"""If set, close the queue."""
state_delta: Optional[dict[str, Any]] = None # NEW FIELD
"""If set, update the session state with the provided delta."""- Process
state_deltain_send_to_modelmethod insrc/google/adk/flows/llm_flows/base_llm_flow.py:
async def _send_to_model(self, llm_connection, invocation_context):
while True:
live_request = await invocation_context.live_request_queue.get()
# Handle state_delta updates
if live_request.state_delta:
event = Event(
invocation_id=invocation_context.invocation_id,
author='user',
actions=EventActions(state_delta=live_request.state_delta)
)
await invocation_context.session_service.append_event(
session=invocation_context.session,
event=event
)
# ... rest of the existing logic- Client usage example:
# Python client
live_request = LiveRequest(
content=types.Content(
role="user",
parts=[types.Part(text="Hello")]
),
state_delta={
"user_preference": "dark_mode",
"last_action": "greeting"
}
)
websocket.send_text(live_request.model_dump_json())// JavaScript client
const liveRequest = {
content: {
role: "user",
parts: [{ text: "Hello" }]
},
state_delta: {
"user_preference": "dark_mode",
"last_action": "greeting"
}
};
websocket.send(JSON.stringify(liveRequest));Describe alternatives you've considered
-
Custom Tool Approach: Create a tool that updates session state, then have the model call it. This works but adds unnecessary LLM roundtrips and token usage.
-
Callback-based Parsing: Parse special markers in message content (e.g.,
"update_state:key=value") and handle them in callbacks. This is fragile and mixes data with content. -
Pre-update via HTTP: Call
/runendpoint withstate_deltabefore establishing WebSocket connection. This doesn't work for dynamic state updates during an ongoing live session. -
Direct Session Modification: Directly modify
session.stateoutside of the event system. This is explicitly discouraged in the documentation as it bypasses event history and breaks persistence.
None of these alternatives are as clean or consistent with ADK's design principles as native state_delta support in LiveRequest.
Additional context
- Related documentation: https://adk.wiki/sessions/state/#state
- The official docs emphasize using
EventActions.state_deltafor proper state management with auditability and persistence - This feature would bring parity between HTTP and WebSocket APIs
- Particularly useful for text-based live interactions where state needs to be updated alongside messages
- Maintains consistency with the existing state management architecture
References:
RunAgentRequestimplementation:src/google/adk/cli/adk_web_server.py:201-209LiveRequestimplementation:src/google/adk/agents/live_request_queue.py:26-42runner.run_asyncwith state_delta:src/google/adk/runners.py:411-432- State management best practices: https://adk.wiki/sessions/state/#state