Describe the bug
When using output_schema with streaming mode (StreamingMode.SSE), function calls from set_model_response are being lost or processed incorrectly. This means that the final response contains the complete set of streamed thoughts but an empty string for the answer, causing:
- Function calls not being registered: Despite the raw GenAI API response containing function calls, they do not appear in the final
Event objects
- Early stream termination: The streaming loop breaks early before receiving the function call response
- Parsing errors: When trying to parse the final response into the expected Pydantic model, the missing function calls makes it so an empty string tries to get parsed (resulting in a ValidationError)
To Reproduce
Steps to reproduce the behavior:
-
Install google-adk latest version
-
Create an agent with output_schema and enable streaming:
from pydantic import BaseModel, Field
from google.adk.agents import LlmAgent
from google.adk.runners import Runner
from google.adk.agents.run_config import RunConfig, StreamingMode
from google.adk.sessions import InMemorySessionService
from google.adk.planners import BuiltInPlanner
from google.genai.types import GenerateContentConfig, ThinkingConfig, Content, Part
# Define output schema
class ShoppingItem(BaseModel):
name: str
quantity: int
price: float
class ShoppingList(BaseModel):
items: list[ShoppingItem]
total_price: float
complexity: str = Field(description="The complexity of the shopping list, either 'easy', 'medium', or 'hard'")
# Create agent with output_schema
planner = BuiltInPlanner(
thinking_config=ThinkingConfig(include_thoughts=True, thinking_budget=-1),
)
agent = LlmAgent(
name="shopper",
model="gemini-2.0-flash-exp", # or any model that supports function calling and will
description="AI shopping list assistant",
instruction="You are a helpful shopping list assistant.",
generate_content_config=GenerateContentConfig(temperature=0.2, seed=42),
output_schema=ShoppingList,
planner=planner,
tools=[tool1, tool2, ...]
)
# Create runner and stream
session_service = InMemorySessionService()
await session_service.create_session(
app_name="test",
user_id="test",
session_id="test",
)
runner = Runner(
agent=agent,
session_service=session_service,
app_name="test",
)
event_stream = runner.run_async(
user_id="test",
session_id="test",
new_message=Content(role="user", parts=[Part(text="I need you to give me shopping list for reina pepiada")]),
run_config=RunConfig(streaming_mode=StreamingMode.SSE),
)
-
Iterate through the event stream and check for function calls:
event_count = 0
function_call_count = 0
async for event in event_stream:
event_count += 1
function_calls = event.get_function_calls()
if function_calls:
function_call_count += 1
print(f"✅ Event {event_count}: Found {len(function_calls)} function call(s)")
else:
# Check for thoughts or text
if event.content and event.content.parts:
for part in event.content.parts:
if hasattr(part, 'text') and part.text:
is_thought = getattr(part, 'thought', False)
print(f"📝 Event {event_count}: {'Thought' if is_thought else 'Text'}")
print(f"Total events: {event_count}")
print(f"Events with function_calls: {function_call_count}")
# Output: Events with function_calls: 0
# Expected: Events with function_calls: 1 (with set_model_response)
-
Observed behavior: The stream completes with 0 function calls detected, even though the raw GenAI API response contains a set_model_response function call with the structured JSON output.
-
Error or stacktrace: A Pydantic Validation error should arise when trying to parse the response
Expected behavior
When using output_schema with streaming:
- Function calls should be properly detected and yielded in the event stream
- The streaming loop should not terminate prematurely before receiving the function call
- Function call responses should not be duplicated
- The final structured response from
set_model_response should be accessible via event.get_function_calls() or event.content.parts with function_response
Describe the bug
When using
output_schemawith streaming mode (StreamingMode.SSE), function calls fromset_model_responseare being lost or processed incorrectly. This means that the final response contains the complete set of streamed thoughts but an empty string for the answer, causing:EventobjectsTo Reproduce
Steps to reproduce the behavior:
Install
google-adklatest versionCreate an agent with
output_schemaand enable streaming:Iterate through the event stream and check for function calls:
Observed behavior: The stream completes with 0 function calls detected, even though the raw GenAI API response contains a
set_model_responsefunction call with the structured JSON output.Error or stacktrace: A Pydantic Validation error should arise when trying to parse the response
Expected behavior
When using
output_schemawith streaming:set_model_responseshould be accessible viaevent.get_function_calls()orevent.content.partswithfunction_response