Skip to content

Commit f99dca0

Browse files
hayato-kishikawakishikawa-hayato
andauthored
fix(observability): handle datetime serialization in tool results (microsoft#2248)
Fixes microsoft#2219 Adds default=str to json.dumps() calls to handle non-JSON-serializable types like datetime objects in tool function results. Co-authored-by: kishikawa-hayato <84244732+HerBest-max@users.noreply.github.com>
1 parent 6ae32f0 commit f99dca0

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

python/packages/core/agent_framework/observability.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,10 +1474,10 @@ def _to_otel_part(content: "Contents") -> dict[str, Any] | None:
14741474
elif isinstance(item, BaseModel):
14751475
res.append(item.model_dump(exclude_none=True))
14761476
else:
1477-
res.append(json.dumps(item))
1478-
response = json.dumps(res)
1477+
res.append(json.dumps(item, default=str))
1478+
response = json.dumps(res, default=str)
14791479
else:
1480-
response = json.dumps(content.result)
1480+
response = json.dumps(content.result, default=str)
14811481
return {"type": "tool_call_response", "id": content.call_id, "response": response}
14821482
case _:
14831483
# GenericPart in otel output messages json spec.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Copyright (c) Microsoft. All rights reserved.
2+
3+
"""Test datetime serialization in observability telemetry."""
4+
5+
import json
6+
from datetime import datetime
7+
8+
from agent_framework._types import FunctionResultContent
9+
from agent_framework.observability import _to_otel_part
10+
11+
12+
def test_datetime_in_tool_results() -> None:
13+
"""Test that tool results with datetime values are serialized.
14+
15+
Reproduces issue #2219 where datetime objects caused TypeError.
16+
"""
17+
content = FunctionResultContent(
18+
call_id="test-call",
19+
result={"timestamp": datetime(2025, 11, 16, 10, 30, 0)},
20+
)
21+
22+
result = _to_otel_part(content)
23+
parsed = json.loads(result["response"])
24+
25+
# Datetime should be converted to string
26+
assert isinstance(parsed["timestamp"], str)

0 commit comments

Comments
 (0)