tracewright
Capture Pydantic AI OpenTelemetry model spans as local, versionable
pydantic-evals datasets.
Tracewright removes the manual step between observing a useful agent run and turning it into an eval case. It preserves the prompt, expected output, model, token usage, timing, and trace identity. Pydantic Evals continues to own dataset storage, evaluators, execution, and reports.
Pydantic AI run -> OpenTelemetry model span -> Pydantic Evals Case
Quick start
The example uses Pydantic AI's TestModel, so it needs no provider key or
hosted observability service.
pip install "tracewright[pydantic-ai,pydantic-evals]"
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from pydantic_ai import Agent, InstrumentationSettings
from pydantic_ai.capabilities import Instrumentation
from pydantic_ai.models.test import TestModel
from tracewright import PydanticAITraceExporter, to_pydantic_evals_dataset
exporter = PydanticAITraceExporter()
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(exporter))
agent = Agent(
TestModel(),
instructions="Answer concisely.",
capabilities=[Instrumentation(settings=InstrumentationSettings(tracer_provider=provider))],
)
agent.run_sync("What is 2+2?")
dataset = to_pydantic_evals_dataset(exporter.rows, name="agent-regression")
dataset.to_file("agent-regression.yaml")
print(exporter.stats)
The resulting file is a normal Pydantic Evals dataset. Review it, commit it with the code it protects, and evaluate future agent versions against it.
The complete runnable example is
examples/pydantic_ai_to_evals.py.
Contract
PydanticAITraceExporter is a standard OpenTelemetry SpanExporter. Attach it
to the tracer provider already used by Pydantic AI. Its rows property returns
an immutable snapshot suitable for to_pydantic_evals_dataset.
Each replayable model span becomes one pydantic_evals.Case:
| Case field | Source |
|---|---|
inputs |
Last user message |
expected_output |
Assistant text output |
metadata |
The complete TraceRow, including system instructions, model, tokens, timing, and trace IDs |
Non-model spans are ignored. Model spans with missing, redacted, or malformed
content are counted in exporter.stats and are never silently promoted into
eval cases.
Content capture is a privacy decision. Pydantic AI instrumentation with
include_content=False still produces useful telemetry, but it cannot produce
replayable prompt and output pairs.
Boundaries
Tracewright deliberately does not:
- replace Pydantic Evals evaluators, execution, or reports;
- replace Logfire trace storage or hosted datasets;
- query the Logfire API or decode OTLP payloads;
- reconstruct tool calls, full multi-turn state, or
SpanTreeobjects.
parse_pydantic_ai_jsonl remains available for files containing exactly one
serialized span object per line. It is not a generic Logfire export or OTLP
reader. Enriched Tracewright/f3dx JSONL and the original replay CLI remain as
compatibility surfaces.
tracewright replay traces.jsonl \
--candidate myapp.replay:my_candidate \
--candidate-model candidate-v2 \
--report html=report.html \
--budget "pass_rate=>=1.0,latency_p95=+10%"
New integrations should use PydanticAITraceExporter and Pydantic Evals.
Development
python -m pip install -e ".[dev]"
ruff check src tests examples
mypy src
pytest -q
python examples/pydantic_ai_to_evals.py
CI runs on Linux, macOS, and Windows with Python 3.10 and 3.12. It also
replays Tracewright's serialized TraceRow contract across supported Pydantic
versions using Pydantic Canary.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tracewright-0.1.1.tar.gz.
File metadata
- Download URL: tracewright-0.1.1.tar.gz
- Upload date:
- Size: 27.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e99270394a39d59cae78a6cf68ab75514eb6cab91b55b0f5d3f2072dfd074a19
|
|
| MD5 |
c484104bf22bacf5924861c8f08cdd0a
|
|
| BLAKE2b-256 |
3431670de5a104e8cc0e5400a0466e7e21feffeac0d256424ec59de393e8cc1c
|
Provenance
The following attestation bundles were made for tracewright-0.1.1.tar.gz:
Publisher:
release.yml on smigolsmigol/tracewright
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tracewright-0.1.1.tar.gz -
Subject digest:
e99270394a39d59cae78a6cf68ab75514eb6cab91b55b0f5d3f2072dfd074a19 - Sigstore transparency entry: 2567160836
- Sigstore integration time:
-
Permalink:
smigolsmigol/tracewright@08348ea46c7d0387ae17566bcc242651365c8c27 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/smigolsmigol
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@08348ea46c7d0387ae17566bcc242651365c8c27 -
Trigger Event:
push
-
Statement type:
File details
Details for the file tracewright-0.1.1-py3-none-any.whl.
File metadata
- Download URL: tracewright-0.1.1-py3-none-any.whl
- Upload date:
- Size: 25.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
92a1ea2ca555b1d50c5e6a35721b00fb63e5906e6ce867afc6dffaf9d4f639d9
|
|
| MD5 |
a94e2e256574d6b17ad6e0f8713c2b9b
|
|
| BLAKE2b-256 |
650f2b51954782d66d3456bc1e8f572eb53e546f04c0894c1b594995d9103802
|
Provenance
The following attestation bundles were made for tracewright-0.1.1-py3-none-any.whl:
Publisher:
release.yml on smigolsmigol/tracewright
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tracewright-0.1.1-py3-none-any.whl -
Subject digest:
92a1ea2ca555b1d50c5e6a35721b00fb63e5906e6ce867afc6dffaf9d4f639d9 - Sigstore transparency entry: 2567160892
- Sigstore integration time:
-
Permalink:
smigolsmigol/tracewright@08348ea46c7d0387ae17566bcc242651365c8c27 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/smigolsmigol
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@08348ea46c7d0387ae17566bcc242651365c8c27 -
Trigger Event:
push
-
Statement type: