Skip to main content

pydantic-ai-trace

Use pydantic-ai-trace when you need to inspect an agent run from a JSON dump. Give it a pydantic-ai list[ModelMessage] dump and it opens the run in a browser view.

It is a lightweight local tool. Point it at a trace or a directory of traces and it reads the files from disk, reloads them when they change, and exports individual traces as self-contained HTML files. Your traces stay on disk, with no hosted service or account.

image

What you can inspect

  • The full request and response sequence, including prompts, text, thinking, tool calls, tool results, and unknown parts
  • Tool calls paired with their results, including results in later messages
  • Model, provider, timing, and token usage
  • A searchable directory tree for .json and .jsonl traces
  • Collapsible large values, rendered Markdown, and keyboard navigation
  • One-click copying as a compact text transcript that preserves request and response order
  • CLI rendering of the same compact transcript for use by people, scripts, and AI agents

Run from a checkout

This project uses pixi. Build the bundled frontend once, then run paitrace with a trace file or directory.

pixi run build-frontend
pixi run paitrace trace.json

Usage

# View one trace
pixi run paitrace trace.json

# Browse a directory tree of traces
pixi run paitrace ./my-traces/

# Browse an explicit collection of trace files with live reload
pixi run paitrace first.json second.json runs/multi.jsonl

# Write one trace to a standalone HTML file
pixi run paitrace export trace.json -o trace.html

# Choose a trace line when exporting a multi-trace JSONL file
pixi run paitrace export runs.jsonl --line 2

# Print the browser's compact text representation to stdout
pixi run paitrace text trace.json

# Print a compact, structured trajectory for jq and other tools
pixi run paitrace json trace.json

# Read a trace from stdin; `-` can also be used explicitly
curl https://example.test/my-traj.json | pixi run paitrace json | jq '.messages[]'
curl https://example.test/my-traj.json | pixi run paitrace text

# Select a trace from JSONL, or write the text to a file
pixi run paitrace text runs.jsonl --line 2
pixi run paitrace text trace.json -o trace.txt

# JSON output supports the same selection and output options
pixi run paitrace json runs.jsonl --line 2
pixi run paitrace json trace.json -o compact.json

# Convert every trace in JSONL to one compact JSON object per line
pixi run paitrace json runs.jsonl --all -o compact.jsonl

# Convert multiple JSON files to compact JSONL in argument order
pixi run paitrace json first.json second.json -o compact.jsonl

# Mix JSON and JSONL inputs; --all expands every JSONL source
pixi run paitrace json first.json runs.jsonl --all -o compact.jsonl

# Indent one compact trajectory for direct inspection
pixi run paitrace json trace.json --pretty

# Export or view a trace received on stdin
curl https://example.test/my-traj.json | pixi run paitrace export -o trace.html
curl https://example.test/my-traj.json | pixi run paitrace --no-open

paitrace text writes only the transcript to stdout by default, so it can be piped directly into another command. Repeated request instructions are omitted until they change. Multi-trace JSONL files require --line, just as HTML export does.

paitrace json emits a token-efficient trajectory document. It preserves request and response order, native tool arguments and results, tool-call IDs, model and token metadata, and unknown variants. It omits display headings, repeated instructions, provider response identifiers, and binary payloads. It retains the provider name. Tool calls and results remain separate events linked by id.

Pass --all to convert every trace in a JSONL file or stream. The output remains JSONL, with one compact trajectory per line. --all cannot be combined with --line or --pretty. Pass --pretty to indent single-trace output by two spaces.

Multiple .json inputs also produce compact JSONL, in argument order. When multiple inputs include JSONL, pass --all to expand each JSONL source. Multiple inputs cannot use stdin, --line, or --pretty. The browser also accepts multiple explicit .json and .jsonl files and watches each source for changes. text and export remain single-input commands.

Query compact JSON with jq

# Extract the final assistant text
pixi run paitrace json trace.json \
  | jq -r '[.messages[].parts[] | select(.type == "text") | .content] | last'

# Extract tool calls, results, and retries in chronological order
pixi run paitrace json trace.json \
  | jq '[.messages[].parts[] | select(.type == "tool_call" or .type == "tool_result" or .type == "retry")]'

# Pair tool calls with their result or retry by call ID
pixi run paitrace json trace.json | jq '
  [.messages[].parts[]] as $parts
  | [$parts[] | select(.type == "tool_result" or .type == "retry")] as $results
  | [$parts[] | select(.type == "tool_call")
      | . as $call
      | {
          id,
          name,
          args,
          result: ($results | map(select(.id == $call.id)) | first)
        }
    ]
'

# Read aggregate model-call and token statistics
pixi run paitrace json trace.json | jq '.stats'

# Collect several compact trajectories into one JSON array
pixi run paitrace json first.json second.json | jq -s '.'

The viewer, text, json, and export commands accept a trace from piped stdin when their input is omitted. Pass - to request stdin explicitly. Stdin can contain one JSON trace or JSONL traces; use --line to select from multi-trace JSONL. HTML export from stdin requires -o.

The viewer binds to 127.0.0.1:1205 and opens your browser. Pass --port, --host, or --no-open to change that behavior.

Trace files

The viewer reads the JSON emitted by ModelMessagesTypeAdapter.dump_json(messages):

  • .json: one bare JSON array of ModelMessage objects
  • .jsonl: one such array per line

When you open a directory, each line in a multi-trace .jsonl file is available as a separate trace.

Development

Run the API and frontend in separate terminals while working on the viewer.

pixi run dev-api ./trace.json  # API with reload on port 1205
pixi run dev-web               # Vite with HMR, proxying /api
pixi run test        # pytest and vitest
pixi run lint        # ruff, prettier, and eslint
pixi run typecheck   # pyright and TypeScript
pixi run build       # bundled frontend plus sdist and wheel

Releasing

Create and publish a GitHub release with a vX.Y.Z tag. The package version is derived from that tag, so no source file needs a version bump. Publishing the release triggers GitHub Actions to run the full check suite, build the frontend into the wheel and source distribution, publish both to PyPI using trusted publishing, and attach them to the GitHub release. Configure a pypi environment in GitHub and add this repository as a trusted publisher for the pydantic-ai-trace project on PyPI before the first release.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pydantic_ai_trace-0.1.8.tar.gz (193.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pydantic_ai_trace-0.1.8-py3-none-any.whl (84.7 kB view details)

Uploaded Python 3

File details

Details for the file pydantic_ai_trace-0.1.8.tar.gz.

File metadata

  • Download URL: pydantic_ai_trace-0.1.8.tar.gz
  • Upload date:
  • Size: 193.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for pydantic_ai_trace-0.1.8.tar.gz
Algorithm Hash digest
SHA256 16756617e38b3f892d5901cf9d3279d4daeb1b1768be8b55400748498c77948a
MD5 28fcd4fed46869267433bd87e10b1ca2
BLAKE2b-256 87897fa59b843cbde992191a0a9008b7be68d58f410f01f2903f87dfd0ecdf2a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydantic_ai_trace-0.1.8.tar.gz:

Publisher: release.yml on moritzwilksch/pydantic-ai-trace

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydantic_ai_trace-0.1.8-py3-none-any.whl.

File metadata

File hashes

Hashes for pydantic_ai_trace-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 f0e6ce9659c687ec94776f8230c357d7a54da87a24c4bfe11302ca7f7a1b3024
MD5 c174e9abdbf5bbaf9fe0ae5cad980816
BLAKE2b-256 38b657ac74f66ccfbd592ae1760a8fd07863f6ef08a14f17e3b0eee0af9f6f9a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydantic_ai_trace-0.1.8-py3-none-any.whl:

Publisher: release.yml on moritzwilksch/pydantic-ai-trace

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page