From b7882d7f843efb4f83f2e5544ad8b8f9156589ce Mon Sep 17 00:00:00 2001 From: kishikawa-hayato <84244732+HerBest-max@users.noreply.github.com> Date: Sun, 16 Nov 2025 00:40:48 +0900 Subject: [PATCH] fix(observability): handle datetime serialization in tool results Fixes #2219 Adds default=str to json.dumps() calls to handle non-JSON-serializable types like datetime objects in tool function results. --- .../core/agent_framework/observability.py | 6 ++--- .../core/tests/test_observability_datetime.py | 26 +++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 python/packages/core/tests/test_observability_datetime.py diff --git a/python/packages/core/agent_framework/observability.py b/python/packages/core/agent_framework/observability.py index 3e44fae23c..3fe4a8ef25 100644 --- a/python/packages/core/agent_framework/observability.py +++ b/python/packages/core/agent_framework/observability.py @@ -1472,10 +1472,10 @@ def _to_otel_part(content: "Contents") -> dict[str, Any] | None: elif isinstance(item, BaseModel): res.append(item.model_dump(exclude_none=True)) else: - res.append(json.dumps(item)) - response = json.dumps(res) + res.append(json.dumps(item, default=str)) + response = json.dumps(res, default=str) else: - response = json.dumps(content.result) + response = json.dumps(content.result, default=str) return {"type": "tool_call_response", "id": content.call_id, "response": response} case _: # GenericPart in otel output messages json spec. diff --git a/python/packages/core/tests/test_observability_datetime.py b/python/packages/core/tests/test_observability_datetime.py new file mode 100644 index 0000000000..05efdc1a5e --- /dev/null +++ b/python/packages/core/tests/test_observability_datetime.py @@ -0,0 +1,26 @@ +# Copyright (c) Microsoft. All rights reserved. + +"""Test datetime serialization in observability telemetry.""" + +import json +from datetime import datetime + +from agent_framework._types import FunctionResultContent +from agent_framework.observability import _to_otel_part + + +def test_datetime_in_tool_results() -> None: + """Test that tool results with datetime values are serialized. + + Reproduces issue #2219 where datetime objects caused TypeError. + """ + content = FunctionResultContent( + call_id="test-call", + result={"timestamp": datetime(2025, 11, 16, 10, 30, 0)}, + ) + + result = _to_otel_part(content) + parsed = json.loads(result["response"]) + + # Datetime should be converted to string + assert isinstance(parsed["timestamp"], str)