From a4cbbf3e81c6a8b8ddd56b8a96d4965000d7e5f2 Mon Sep 17 00:00:00 2001 From: Ariz Chang Date: Tue, 15 Jul 2025 16:36:51 -0700 Subject: [PATCH] feat: Add ability to send state change with message PiperOrigin-RevId: 783516738 --- src/google/adk/cli/fast_api.py | 2 ++ src/google/adk/runners.py | 25 ++++++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/google/adk/cli/fast_api.py b/src/google/adk/cli/fast_api.py index 8d6ca2e4..2e37f3bb 100644 --- a/src/google/adk/cli/fast_api.py +++ b/src/google/adk/cli/fast_api.py @@ -177,6 +177,7 @@ class AgentRunRequest(common.BaseModel): session_id: str new_message: types.Content streaming: bool = False + state_delta: Optional[dict[str, Any]] = None class AddSessionToEvalSetRequest(common.BaseModel): @@ -877,6 +878,7 @@ def get_fast_api_app( user_id=req.user_id, session_id=req.session_id, new_message=req.new_message, + state_delta=req.state_delta, run_config=RunConfig(streaming_mode=stream_mode), ): # Format as SSE data diff --git a/src/google/adk/runners.py b/src/google/adk/runners.py index f8ebd04a..d459bb9d 100644 --- a/src/google/adk/runners.py +++ b/src/google/adk/runners.py @@ -17,11 +17,14 @@ from __future__ import annotations import asyncio import logging import queue +import time +from typing import Any from typing import AsyncGenerator from typing import Callable from typing import Generator from typing import List from typing import Optional +import uuid import warnings from google.genai import types @@ -38,6 +41,7 @@ from .artifacts.in_memory_artifact_service import InMemoryArtifactService from .auth.credential_service.base_credential_service import BaseCredentialService from .code_executors.built_in_code_executor import BuiltInCodeExecutor from .events.event import Event +from .events.event import EventActions from .flows.llm_flows.functions import find_matching_function_call from .memory.base_memory_service import BaseMemoryService from .memory.in_memory_memory_service import InMemoryMemoryService @@ -174,6 +178,7 @@ class Runner: user_id: str, session_id: str, new_message: types.Content, + state_delta: Optional[dict[str, Any]] = None, run_config: RunConfig = RunConfig(), ) -> AsyncGenerator[Event, None]: """Main entry method to run the agent in this runner. @@ -216,6 +221,7 @@ class Runner: new_message, invocation_context, run_config.save_input_blobs_as_artifacts, + state_delta, ) invocation_context.agent = self._find_agent_to_run(session, root_agent) @@ -284,6 +290,7 @@ class Runner: new_message: types.Content, invocation_context: InvocationContext, save_input_blobs_as_artifacts: bool = False, + state_delta: Optional[dict[str, Any]] = None, ): """Appends a new message to the session. @@ -315,11 +322,19 @@ class Runner: text=f'Uploaded file: {file_name}. It is saved into artifacts' ) # Appends only. We do not yield the event because it's not from the model. - event = Event( - invocation_id=invocation_context.invocation_id, - author='user', - content=new_message, - ) + if state_delta: + event = Event( + invocation_id=invocation_context.invocation_id, + author='user', + actions=EventActions(state_delta=state_delta), + content=new_message, + ) + else: + event = Event( + invocation_id=invocation_context.invocation_id, + author='user', + content=new_message, + ) await self.session_service.append_event(session=session, event=event) async def run_live(