Skip to content

Commit e16be4c

Browse files
address review feedback
1 parent 05973fd commit e16be4c

3 files changed

Lines changed: 27 additions & 9 deletions

File tree

src/agentevals/loader/auto.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,20 @@ def detect_format(path: str) -> str | None:
4040
"""Return the format name for ``path`` (``"jaeger-json"`` or ``"otlp-json"``).
4141
4242
Order:
43-
1. ``.jsonl`` extension implies OTLP (one span per line).
44-
2. Otherwise read and inspect top-level keys:
43+
1. The file must exist and be readable. Missing/unreadable files always
44+
return ``None`` regardless of extension.
45+
2. ``.jsonl`` extension implies OTLP (one span per line).
46+
3. Otherwise read and inspect top-level keys:
4547
- ``resourceSpans`` / ``batches`` / wrapped ``trace.{...}`` → OTLP
4648
- ``data`` → Jaeger
47-
Returns ``None`` if the file isn't valid JSON or the shape isn't
48-
recognized; callers that still want to attempt a load can fall back
49-
to a default.
49+
Returns ``None`` when the file is missing, unreadable, not valid JSON,
50+
or the shape isn't recognized; callers that still want to attempt a
51+
load can fall back to a default.
5052
"""
51-
if path.lower().endswith(".jsonl"):
52-
return OTLP_JSON
53-
5453
try:
5554
with open(path) as f:
55+
if path.lower().endswith(".jsonl"):
56+
return OTLP_JSON
5657
data = json.load(f)
5758
except (OSError, json.JSONDecodeError):
5859
return None

tests/test_loader_auto.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,12 @@ def test_invalid_json_returns_none(self):
148148
def test_missing_file_returns_none(self):
149149
assert detect_format("/nonexistent/path/that/should/not/exist.json") is None
150150

151+
def test_missing_jsonl_file_returns_none(self):
152+
# The ``.jsonl`` shortcut must not bypass the existence check;
153+
# otherwise a missing file would lie about its format and confuse
154+
# downstream loaders with a worse error message.
155+
assert detect_format("/nonexistent/path/that/should/not/exist.jsonl") is None
156+
151157
def test_unrecognized_shape_returns_none(self):
152158
path = _write_tmp(json.dumps({"foo": "bar"}))
153159
try:

ui/src/lib/trace-loader.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,24 @@ interface OtlpAttribute {
4747
};
4848
}
4949

50+
// OTLP/JSON encodes int64 values as strings to preserve precision past
51+
// Number.MAX_SAFE_INTEGER (2^53 - 1). Convert only when the value still
52+
// fits a JavaScript safe integer; otherwise keep the original string so
53+
// large IDs/counters/timestamps round-trip without silent corruption.
54+
function parseOtlpIntValue(value: number | string): number | string {
55+
if (typeof value === 'number') return value;
56+
if (!/^-?\d+$/.test(value)) return value;
57+
const parsed = Number(value);
58+
return Number.isSafeInteger(parsed) ? parsed : value;
59+
}
60+
5061
function extractOtlpAttributes(attrs: OtlpAttribute[] | undefined): Record<string, any> {
5162
const tags: Record<string, any> = {};
5263
for (const attr of attrs || []) {
5364
const v = attr.value;
5465
if (!v) continue;
5566
if (v.stringValue !== undefined) tags[attr.key] = v.stringValue;
56-
else if (v.intValue !== undefined) tags[attr.key] = typeof v.intValue === 'string' ? parseInt(v.intValue) : v.intValue;
67+
else if (v.intValue !== undefined) tags[attr.key] = parseOtlpIntValue(v.intValue);
5768
else if (v.doubleValue !== undefined) tags[attr.key] = v.doubleValue;
5869
else if (v.boolValue !== undefined) tags[attr.key] = v.boolValue;
5970
}

0 commit comments

Comments
 (0)