Skip to content

Commit 8fc567f

Browse files
committed
fix(tracing): serialize big integers as strings to prevent dashboard precision loss (#2094)
1 parent da82b2c commit 8fc567f

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

src/agents/tracing/span_data.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,35 @@
11
from __future__ import annotations
22

33
import abc
4+
import json
45
from collections.abc import Mapping, Sequence
56
from typing import TYPE_CHECKING, Any
67

78
if TYPE_CHECKING:
89
from openai.types.responses import Response, ResponseInputItemParam
910

11+
# JavaScript's Number.MAX_SAFE_INTEGER (2^53 - 1). Integers beyond this threshold
12+
# lose precision when parsed by JS, causing the Traces dashboard to display wrong values.
13+
_JS_MAX_SAFE_INTEGER = 9007199254740991
14+
15+
16+
def _sanitize_bigint(value: Any) -> Any:
17+
"""Recursively convert integers that exceed JS Number.MAX_SAFE_INTEGER to strings.
18+
19+
This prevents precision loss when the OpenAI Traces dashboard (JavaScript) parses
20+
large integer values that cannot be represented exactly as IEEE-754 doubles.
21+
"""
22+
if isinstance(value, bool):
23+
# bool is a subclass of int; must be checked first to avoid converting True/False
24+
return value
25+
if isinstance(value, int) and abs(value) > _JS_MAX_SAFE_INTEGER:
26+
return str(value)
27+
if isinstance(value, dict):
28+
return {k: _sanitize_bigint(v) for k, v in value.items()}
29+
if isinstance(value, list):
30+
return [_sanitize_bigint(item) for item in value]
31+
return value
32+
1033

1134
class SpanData(abc.ABC):
1235
"""
@@ -157,10 +180,16 @@ def type(self) -> str:
157180
return "function"
158181

159182
def export(self) -> dict[str, Any]:
183+
sanitized_input: str | None = None
184+
if self.input is not None:
185+
try:
186+
sanitized_input = json.dumps(_sanitize_bigint(json.loads(self.input)))
187+
except (json.JSONDecodeError, TypeError):
188+
sanitized_input = self.input
160189
return {
161190
"type": self.type,
162191
"name": self.name,
163-
"input": self.input,
192+
"input": sanitized_input,
164193
"output": str(self.output) if self.output else None,
165194
"mcp_data": self.mcp_data,
166195
}

0 commit comments

Comments
 (0)