Repository navigation
Conversation
_safe_json_serialize fell back to str() for the whole payload when json.dumps hit a value it cannot encode, so a tool result with one date, Decimal, UUID, Enum, set, bytes or Pydantic model reached the model as a Python repr. An output_schema agent wrapped in AgentTool always returns such values for date and Decimal fields. Convert them with pydantic_core.to_jsonable_python, as the Gemma path does since google#7668, and keep str() only for payloads Pydantic cannot serialize.
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
@googlebot I signed it! |
Link to Issue or Description of Change
1. Link to an existing issue (if applicable):
load_memory) #7667, fix(models): stop Gemma 3 failing on datetime or Pydantic tool results #7668 (same fix on the Gemma path), fix(openai): serialize tool results that hold datetimes, bytes or models #8086 (same fix for OpenAILlm)2. Or, if no issue exists, describe the change:
Problem:
_safe_json_serializeinmodels/lite_llm.pyfalls back tostr()of the whole payload whenjson.dumpshits a value it cannot encode. A tool result with onedate,Decimal,UUID,Enum,set,bytesor Pydantic model therefore reaches the model as a Python repr ({'due_date': datetime.date(2026, 12, 1), 'total': Decimal('12.50')}). Anoutput_schemaagent wrapped inAgentToolreturns such values for any date or Decimal field.Solution:
When
json.dumpsfails, convert the payload withpydantic_core.to_jsonable_python(obj, by_alias=False, exclude_none=True, bytes_mode="base64"), the same options the Gemma path uses since #7668, and only then fall back tostr(). Payloads thatjson.dumpsalready handles are unchanged. Unknown objects and circular dicts still fall back tostr(), so the existing tests for those cases keep passing.Testing Plan
Unit Tests:
Added to
tests/unittests/models/test_litellm.py:test_safe_json_serialize_converts_values_json_cannot_encode(date, Decimal, Enum, UUID, nested Pydantic model, None)test_content_to_message_param_function_response_with_date_is_jsonManual End-to-End (E2E) Tests:
Script (no API key needed; fake models, real ADK runner and the real LiteLLM converter): a child
LlmAgentwithoutput_schemaholdingdate,DecimalandEnumfields is called by a parent throughAgentTool, and the function response event is passed to_content_to_message_param.Before (google-adk 2.14.0):
After (this branch, macOS, Python 3.12):
Checklist
Additional context
Formatting checked with pyink 25.12 and isort using the repo's pyproject settings.