agentx-python 0.8.3__tar.gz → 0.8.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of agentx-python might be problematic. Click here for more details.
- {agentx_python-0.8.3/agentx_python.egg-info → agentx_python-0.8.4}/PKG-INFO +1 -1
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/runner.py +15 -1
- agentx_python-0.8.4/agentx/tracing/eval_scope.py +44 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/tracing/tracer.py +20 -2
- agentx_python-0.8.4/agentx/version.py +1 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4/agentx_python.egg-info}/PKG-INFO +1 -1
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx_python.egg-info/SOURCES.txt +2 -0
- agentx_python-0.8.4/tests/test_eval_scope.py +116 -0
- agentx_python-0.8.3/agentx/version.py +0 -1
- {agentx_python-0.8.3 → agentx_python-0.8.4}/LICENSE +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/README.md +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/__init__.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/agentx.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/cli.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/__init__.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/_term.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/adapters/__init__.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/adapters/http_endpoint.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/adapters/precomputed.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/adapters/raw.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/client.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/datasets.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/evaluation_settings.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/models.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/prompts.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/reporting.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/results.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/tool_schemas.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/evaluations/tracing.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/exceptions.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/export.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/feedback.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/integrations/__init__.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/integrations/_traced_call.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/integrations/anthropic.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/integrations/autogen.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/integrations/crewai.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/integrations/databricks.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/integrations/google_adk.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/integrations/google_genai.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/integrations/langchain.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/integrations/litellm.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/integrations/llamaindex.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/integrations/moveworks.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/integrations/openai.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/integrations/openai_agents.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/monitor/__init__.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/monitor/agents.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/monitor/client.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/monitor/judge_scorers.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/monitor/models.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/monitor/online_evaluators.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/monitor/patterns.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/monitor/profile.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/monitor/scorers.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/monitor/sessions.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/monitor/signals.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/outcomes.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/projects.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/py.typed +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/resources/__init__.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/resources/agent.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/resources/conversation.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/resources/workforce.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/testing.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/traces.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/tracing/__init__.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/tracing/ci_types.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/tracing/ingest_client.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx/util.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx_python.egg-info/dependency_links.txt +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx_python.egg-info/entry_points.txt +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx_python.egg-info/not-zip-safe +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx_python.egg-info/requires.txt +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/agentx_python.egg-info/top_level.txt +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/setup.cfg +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/setup.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/tests/test_deep_dive_fixes.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/tests/test_docs_match_sdk.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/tests/test_integration.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/tests/test_integrations.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/tests/test_judge_scorers.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/tests/test_pairwise.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/tests/test_selfhost_analysis_fallback.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/tests/test_span_tree.py +0 -0
- {agentx_python-0.8.3 → agentx_python-0.8.4}/tests/test_testing.py +0 -0
|
@@ -119,7 +119,21 @@ class EvaluationRunContext:
|
|
|
119
119
|
# ------------------------------------------------------------------
|
|
120
120
|
|
|
121
121
|
def execute(self, adapter: AdapterLike) -> "EvaluationRunContext":
|
|
122
|
-
"""Run all cases locally and submit batches to AgentX.
|
|
122
|
+
"""Run all cases locally and submit batches to AgentX.
|
|
123
|
+
|
|
124
|
+
The whole loop runs inside the eval-run scope (tracing/eval_scope.py): any trace the
|
|
125
|
+
agent function creates is stamped source="eval-run" + monitor=False automatically, so
|
|
126
|
+
eval traffic never skews production monitoring and no one has to remember a flag.
|
|
127
|
+
"""
|
|
128
|
+
from agentx.tracing.eval_scope import enter_eval_run, exit_eval_run
|
|
129
|
+
|
|
130
|
+
scope_token = enter_eval_run(self._run.run_id)
|
|
131
|
+
try:
|
|
132
|
+
return self._execute_inner(adapter)
|
|
133
|
+
finally:
|
|
134
|
+
exit_eval_run(scope_token)
|
|
135
|
+
|
|
136
|
+
def _execute_inner(self, adapter: AdapterLike) -> "EvaluationRunContext":
|
|
123
137
|
normalized = _wrap_adapter(adapter)
|
|
124
138
|
cases = _build_cases(self._dataset, self._run, self._evaluation_settings)
|
|
125
139
|
max_batch = self._run.limits.max_batch_size
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""The eval-run scope: how traces created inside an evaluation stop passing as production.
|
|
2
|
+
|
|
3
|
+
An offline run executes the user's own agent function, and an instrumented agent traces itself -
|
|
4
|
+
which is exactly what makes trajectory matching and retrieval-context extraction work. But those
|
|
5
|
+
traces are not production traffic, and before this scope existed the burden of saying so sat on
|
|
6
|
+
every caller: remember ``monitor=False`` on every ``tracer.trace(...)`` inside an eval, or the
|
|
7
|
+
engine would double-judge each case, raise signals on synthetic questions, and count the run's
|
|
8
|
+
latencies into production KPIs. Nobody remembered - including our own samples.
|
|
9
|
+
|
|
10
|
+
``EvaluationRunContext.execute()`` enters this scope around the whole run. While it is active,
|
|
11
|
+
every trace the tracer sends is stamped:
|
|
12
|
+
|
|
13
|
+
- ``source="eval-run"`` - the engine files it as eval traffic (excluded from monitor KPIs,
|
|
14
|
+
metrics, sessions and the Live Traces default view; cost keeps it, split out)
|
|
15
|
+
- ``monitor=False`` - unless the caller explicitly passed ``monitor=True``, which is
|
|
16
|
+
respected as a deliberate choice
|
|
17
|
+
- ``metadata.evalRunId`` - so a trace can always be walked back to the run that produced it
|
|
18
|
+
|
|
19
|
+
A ``contextvars.ContextVar`` rather than tracer state: it nests correctly, cannot leak across
|
|
20
|
+
concurrent runs in async code, and costs nothing when no run is active. The one known limit is
|
|
21
|
+
threads the agent function spawns itself - a context var does not cross a bare ``Thread()`` -
|
|
22
|
+
which matches the tracer's existing documented posture for user-managed threads.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from contextvars import ContextVar
|
|
26
|
+
from typing import Optional
|
|
27
|
+
|
|
28
|
+
EVAL_RUN_SOURCE = "eval-run"
|
|
29
|
+
|
|
30
|
+
_current_eval_run_id: ContextVar[Optional[str]] = ContextVar("agentx_eval_run_id", default=None)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def enter_eval_run(run_id: str):
|
|
34
|
+
"""Mark the current context as inside an eval run. Returns the token for ``exit_eval_run``."""
|
|
35
|
+
return _current_eval_run_id.set(run_id)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def exit_eval_run(token) -> None:
|
|
39
|
+
_current_eval_run_id.reset(token)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def current_eval_run_id() -> Optional[str]:
|
|
43
|
+
"""The run id when inside ``execute()``, else None."""
|
|
44
|
+
return _current_eval_run_id.get()
|
|
@@ -13,6 +13,7 @@ from uuid import uuid4
|
|
|
13
13
|
from agentx.exceptions import CIGateFailure
|
|
14
14
|
from agentx.tracing.ingest_client import IngestClient
|
|
15
15
|
from agentx.tracing.ci_types import CIRun, CIRunResult, CIRunStatus, CIQuestionScore
|
|
16
|
+
from agentx.tracing.eval_scope import EVAL_RUN_SOURCE, current_eval_run_id
|
|
16
17
|
|
|
17
18
|
F = TypeVar("F", bound=Callable[..., Any])
|
|
18
19
|
|
|
@@ -167,9 +168,21 @@ class _TraceSpan:
|
|
|
167
168
|
# flush() uses; child-only spans keep their async fire-and-forget behavior.
|
|
168
169
|
self._tracer.flush(timeout=5.0)
|
|
169
170
|
|
|
171
|
+
# Inside an eval run (evaluations' execute()), every trace states what it is: eval
|
|
172
|
+
# traffic. monitor=False unless the caller explicitly said True; the run id rides in
|
|
173
|
+
# metadata so the trace can be walked back to its run. See tracing/eval_scope.py.
|
|
174
|
+
eval_run_id = current_eval_run_id()
|
|
175
|
+
monitor = self._monitor
|
|
176
|
+
metadata = self._metadata
|
|
177
|
+
source = None
|
|
178
|
+
if eval_run_id is not None:
|
|
179
|
+
source = EVAL_RUN_SOURCE
|
|
180
|
+
if monitor is not True:
|
|
181
|
+
monitor = False
|
|
182
|
+
metadata = {**(metadata or {}), "evalRunId": eval_run_id}
|
|
170
183
|
self._trace_id = self._tracer._send(
|
|
171
184
|
sync=self._sync,
|
|
172
|
-
monitor=
|
|
185
|
+
monitor=monitor,
|
|
173
186
|
pattern_ids=self._pattern_ids,
|
|
174
187
|
name=self.name,
|
|
175
188
|
agent_id=self._agent_id,
|
|
@@ -177,7 +190,7 @@ class _TraceSpan:
|
|
|
177
190
|
output=_safe_serialize(self.output) if self.output is not None else None,
|
|
178
191
|
latency_ms=latency_ms,
|
|
179
192
|
error=self._error,
|
|
180
|
-
metadata=
|
|
193
|
+
metadata=metadata,
|
|
181
194
|
framework=self._framework or self._captured_framework,
|
|
182
195
|
model=self._model or self._captured_model,
|
|
183
196
|
tool_calls=self.tool_calls or None,
|
|
@@ -189,6 +202,7 @@ class _TraceSpan:
|
|
|
189
202
|
span_id=self._span_id,
|
|
190
203
|
parent_span_id=self._parent_span_id,
|
|
191
204
|
span_kind=self._span_kind,
|
|
205
|
+
source=source,
|
|
192
206
|
started_at_unix_nano=str(int(self._start * 1_000_000_000)) if self._start else None,
|
|
193
207
|
)
|
|
194
208
|
return False # never suppress exceptions
|
|
@@ -332,6 +346,8 @@ class _TraceSpan:
|
|
|
332
346
|
wire["span_kind"] = span_kind
|
|
333
347
|
if child._session_id:
|
|
334
348
|
wire["session_id"] = child._session_id
|
|
349
|
+
if current_eval_run_id() is not None:
|
|
350
|
+
wire["source"] = EVAL_RUN_SOURCE
|
|
335
351
|
wire["span_id"] = child._span_id
|
|
336
352
|
if child._parent_span_id:
|
|
337
353
|
wire["parent_span_id"] = child._parent_span_id
|
|
@@ -1148,6 +1164,8 @@ class Tracer:
|
|
|
1148
1164
|
wire["started_at_unix_nano"] = payload["started_at_unix_nano"]
|
|
1149
1165
|
if "agent_id" in payload:
|
|
1150
1166
|
wire["agent_id"] = payload["agent_id"]
|
|
1167
|
+
if "source" in payload:
|
|
1168
|
+
wire["source"] = payload["source"]
|
|
1151
1169
|
if "span_kind" in payload:
|
|
1152
1170
|
wire["span_kind"] = payload["span_kind"]
|
|
1153
1171
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VERSION = "0.8.4"
|
|
@@ -61,6 +61,7 @@ agentx/resources/conversation.py
|
|
|
61
61
|
agentx/resources/workforce.py
|
|
62
62
|
agentx/tracing/__init__.py
|
|
63
63
|
agentx/tracing/ci_types.py
|
|
64
|
+
agentx/tracing/eval_scope.py
|
|
64
65
|
agentx/tracing/ingest_client.py
|
|
65
66
|
agentx/tracing/tracer.py
|
|
66
67
|
agentx_python.egg-info/PKG-INFO
|
|
@@ -72,6 +73,7 @@ agentx_python.egg-info/requires.txt
|
|
|
72
73
|
agentx_python.egg-info/top_level.txt
|
|
73
74
|
tests/test_deep_dive_fixes.py
|
|
74
75
|
tests/test_docs_match_sdk.py
|
|
76
|
+
tests/test_eval_scope.py
|
|
75
77
|
tests/test_integration.py
|
|
76
78
|
tests/test_integrations.py
|
|
77
79
|
tests/test_judge_scorers.py
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""The eval-run scope: traces created inside execute() stop passing as production.
|
|
2
|
+
|
|
3
|
+
Before this, the burden sat on every caller: remember monitor=False on every trace inside an
|
|
4
|
+
eval or the engine double-judges, raises signals on synthetic questions, and counts eval
|
|
5
|
+
latencies into production KPIs. These pin that the stamping is automatic, respects an explicit
|
|
6
|
+
monitor=True, and vanishes completely outside the scope.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from agentx.tracing.eval_scope import current_eval_run_id, enter_eval_run, exit_eval_run
|
|
10
|
+
from agentx.tracing.tracer import Tracer
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class _CaptureTracer(Tracer):
|
|
14
|
+
"""A tracer whose network is a list."""
|
|
15
|
+
|
|
16
|
+
def __init__(self): # noqa: D401 - bypass real client setup
|
|
17
|
+
self.sent = []
|
|
18
|
+
self._active_spans = []
|
|
19
|
+
self._pending_tool_calls = []
|
|
20
|
+
self._pending_retrievals = []
|
|
21
|
+
|
|
22
|
+
def _send(self, sync=False, **kwargs):
|
|
23
|
+
self.sent.append({k: v for k, v in kwargs.items() if v is not None})
|
|
24
|
+
return "trace-1"
|
|
25
|
+
|
|
26
|
+
def _dispatch(self, wire, *, sync=False):
|
|
27
|
+
self.sent.append(wire)
|
|
28
|
+
return "trace-child"
|
|
29
|
+
|
|
30
|
+
# The bits of Tracer the span touches.
|
|
31
|
+
def _push_active_span(self, span):
|
|
32
|
+
self._active_spans.append(span)
|
|
33
|
+
|
|
34
|
+
def _pop_active_span(self, span):
|
|
35
|
+
if span in self._active_spans:
|
|
36
|
+
self._active_spans.remove(span)
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def current_span(self):
|
|
40
|
+
return self._active_spans[-1] if self._active_spans else None
|
|
41
|
+
|
|
42
|
+
def flush(self, timeout=5.0):
|
|
43
|
+
return True
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_outside_the_scope_nothing_changes():
|
|
47
|
+
tracer = _CaptureTracer()
|
|
48
|
+
with tracer.trace("prod-agent", input={"q": "hi"}) as span:
|
|
49
|
+
span.output = "hello"
|
|
50
|
+
wire = tracer.sent[-1]
|
|
51
|
+
assert "source" not in wire
|
|
52
|
+
assert "monitor" not in wire # None is filtered out, same as before
|
|
53
|
+
assert current_eval_run_id() is None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_inside_the_scope_traces_are_stamped():
|
|
57
|
+
tracer = _CaptureTracer()
|
|
58
|
+
token = enter_eval_run("run-42")
|
|
59
|
+
try:
|
|
60
|
+
with tracer.trace("agent-under-eval", input={"q": "case 1"}) as span:
|
|
61
|
+
span.output = "answer"
|
|
62
|
+
finally:
|
|
63
|
+
exit_eval_run(token)
|
|
64
|
+
wire = tracer.sent[-1]
|
|
65
|
+
assert wire["source"] == "eval-run"
|
|
66
|
+
assert wire["monitor"] is False
|
|
67
|
+
assert wire["metadata"]["evalRunId"] == "run-42"
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_explicit_monitor_true_is_respected():
|
|
71
|
+
# Someone deliberately pointing checks at eval traffic is a choice, not a mistake.
|
|
72
|
+
tracer = _CaptureTracer()
|
|
73
|
+
token = enter_eval_run("run-42")
|
|
74
|
+
try:
|
|
75
|
+
with tracer.trace("agent-under-eval", monitor=True) as span:
|
|
76
|
+
span.output = "x"
|
|
77
|
+
finally:
|
|
78
|
+
exit_eval_run(token)
|
|
79
|
+
wire = tracer.sent[-1]
|
|
80
|
+
assert wire["source"] == "eval-run"
|
|
81
|
+
assert wire["monitor"] is True
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_child_spans_are_eval_traffic_too():
|
|
85
|
+
tracer = _CaptureTracer()
|
|
86
|
+
token = enter_eval_run("run-42")
|
|
87
|
+
try:
|
|
88
|
+
with tracer.trace("agent-under-eval") as span:
|
|
89
|
+
span.child_span("kb_search", output=["chunk"])
|
|
90
|
+
span.output = "x"
|
|
91
|
+
finally:
|
|
92
|
+
exit_eval_run(token)
|
|
93
|
+
child = next(w for w in tracer.sent if w.get("name") == "kb_search")
|
|
94
|
+
assert child["source"] == "eval-run"
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def test_the_scope_does_not_leak():
|
|
98
|
+
tracer = _CaptureTracer()
|
|
99
|
+
token = enter_eval_run("run-42")
|
|
100
|
+
exit_eval_run(token)
|
|
101
|
+
with tracer.trace("prod-again") as span:
|
|
102
|
+
span.output = "y"
|
|
103
|
+
assert "source" not in tracer.sent[-1]
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def test_caller_metadata_survives_the_stamp():
|
|
107
|
+
tracer = _CaptureTracer()
|
|
108
|
+
token = enter_eval_run("run-42")
|
|
109
|
+
try:
|
|
110
|
+
with tracer.trace("agent", metadata={"promptName": "support-v3"}) as span:
|
|
111
|
+
span.output = "x"
|
|
112
|
+
finally:
|
|
113
|
+
exit_eval_run(token)
|
|
114
|
+
md = tracer.sent[-1]["metadata"]
|
|
115
|
+
assert md["promptName"] == "support-v3"
|
|
116
|
+
assert md["evalRunId"] == "run-42"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
VERSION = "0.8.3"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|