Skip to content

Commit 43211ba

Browse files
fix(tracing): keep list-shaped eval spans searchable and drop stale eval attrs
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 parent d718f78 commit 43211ba

4 files changed

Lines changed: 19 additions & 4 deletions

File tree

‎src/agentex/lib/core/temporal/workers/worker.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ async def run(
275275
build_id=str(uuid.uuid4()),
276276
debug_mode=debug_enabled, # Disable deadlock detection in debug mode
277277
# Temporal inherits client tracing before these business interceptors.
278-
interceptors=[*self.interceptors, SGPEvalsInterceptor()],
278+
interceptors=[SGPEvalsInterceptor(), *self.interceptors],
279279
)
280280

281281
logger.info(f"Starting workers for task queue: {self.task_queue}")

‎src/agentex/lib/core/tracing/processors/sgp_tracing_processor.py‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,19 @@ def _sgp_metadata(span: Span) -> Any:
8383
leak like that today. Left as-is: changing five long-shipped fields is not
8484
this change's business.)
8585
"""
86-
extra: dict[str, Any] = dict(sgp_evals.attrs_for_span(span))
86+
eval_attrs = sgp_evals.attrs_for_span(span)
87+
extra: dict[str, Any] = dict(eval_attrs)
8788
commit_sha = code_revision.commit_sha()
8889
if commit_sha is not None:
8990
extra[code_revision.COMMIT_SHA_KEY] = commit_sha
9091
if not extra:
9192
return span.data
9293
if isinstance(span.data, dict):
9394
return {**span.data, **extra}
94-
# List-shaped data is an accepted `data` shape and has nowhere to put a
95-
# metadata key; leave it untouched rather than dropping the caller's data.
95+
# List-shaped data has nowhere to put a key. Eval spans must stay searchable by run and row,
96+
# so their list moves under "data". Otherwise it is left untouched rather than reshaped.
97+
if eval_attrs and isinstance(span.data, list):
98+
return {**extra, "data": span.data}
9699
return span.data
97100

98101

‎src/agentex/lib/core/tracing/sgp_evals.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ def register_task_metadata(task_id: str, task_metadata: Any) -> dict[str, Any] |
5252
attrs = span_attrs_from_task_metadata(task_metadata)
5353
if attrs is not None:
5454
register_task(task_id, attrs)
55+
elif _attrs_by_task:
56+
with _lock:
57+
_attrs_by_task.pop(task_id, None)
5558
return attrs
5659

5760

‎tests/lib/core/tracing/test_sgp_evals.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ def test_other_tasks_and_non_eval_tasks_are_untouched(self) -> None:
9898
assert _sgp_metadata(_span(trace_id="task-2", data={"k": 1})) == {"k": 1}
9999
assert _sgp_metadata(_span(trace_id="task-3", data={"k": 1})) == {"k": 1}
100100

101+
def test_eval_span_with_list_data_keeps_list_and_gains_the_ids(self) -> None:
102+
sgp_evals.register_task_metadata("task-1", EVAL_METADATA)
103+
assert _sgp_metadata(_span(data=[{"a": 1}])) == {**EXPECTED_ATTRS, "data": [{"a": 1}]}
104+
105+
def test_task_that_stops_being_an_eval_task_stops_being_stamped(self) -> None:
106+
sgp_evals.register_task_metadata("task-1", EVAL_METADATA)
107+
sgp_evals.register_task_metadata("task-1", {"team": "x"})
108+
assert _sgp_metadata(_span(data={"k": 1})) == {"k": 1}
109+
101110
def test_registry_is_bounded(self) -> None:
102111
with patch.object(sgp_evals, "_MAX_TASKS", 2):
103112
for i in range(3):

0 commit comments

Comments
 (0)