diff --git a/src/google/adk/models/lite_llm.py b/src/google/adk/models/lite_llm.py index 8c1568ccc7..063cbfe7f9 100644 --- a/src/google/adk/models/lite_llm.py +++ b/src/google/adk/models/lite_llm.py @@ -51,6 +51,8 @@ from pydantic import Field from typing_extensions import override +from ..utils.serialization_utils import serialize_pydantic_model + from ..utils._google_client_headers import merge_tracking_headers from .base_llm import BaseLlm from .llm_request import LlmRequest @@ -493,6 +495,9 @@ def _safe_json_serialize(obj) -> str: """ try: + serialized = serialize_pydantic_model(obj) + if serialized is not None: + return serialized # Try direct JSON serialization first return json.dumps(obj, ensure_ascii=False) except (TypeError, OverflowError): diff --git a/src/google/adk/telemetry/tracing.py b/src/google/adk/telemetry/tracing.py index 707bc31396..1093d3a796 100644 --- a/src/google/adk/telemetry/tracing.py +++ b/src/google/adk/telemetry/tracing.py @@ -65,6 +65,7 @@ from .. import version from ..utils.model_name_utils import is_gemini_model +from ..utils.serialization_utils import serialize_pydantic_model from ._experimental_semconv import is_experimental_semconv from ._experimental_semconv import maybe_log_completion_details from ._experimental_semconv import set_operation_details_attributes_from_request @@ -117,6 +118,9 @@ def _safe_json_serialize(obj) -> str: """ try: + serialized = serialize_pydantic_model(obj) + if serialized is not None: + return serialized # Try direct JSON serialization first return json.dumps( obj, ensure_ascii=False, default=lambda o: '' diff --git a/src/google/adk/utils/serialization_utils.py b/src/google/adk/utils/serialization_utils.py new file mode 100644 index 0000000000..f2dc19420c --- /dev/null +++ b/src/google/adk/utils/serialization_utils.py @@ -0,0 +1,35 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Shared serialization utilities for Pydantic models.""" + +import json +from typing import Any +from typing import Optional + +from pydantic import BaseModel + + +def serialize_pydantic_model(obj: Any) -> Optional[str]: + """Serialize a Pydantic BaseModel to a JSON string. + + Args: + obj: The object to check and serialize. + + Returns: + A JSON string if the object is a Pydantic BaseModel, or None otherwise. + """ + if isinstance(obj, BaseModel): + return json.dumps(obj.model_dump(), default=str) + return None