Skip to main content

A unified read, query, and export layer for LLM and AI-agent traces.

Project description

traceport

Read agent conversations from any supported observability provider through one consistent API.

Trace providers store the same conversation in very different shapes: runs, records, observations, spans, and cumulative message histories. traceport normalizes those records into sessions with one readable, chronological transcript:

from traceport import TraceClient

client = TraceClient.from_env("langsmith")

sessions = client.list_sessions(project="Branna", since="7d")
session = client.get_session(sessions[0].id, project="Branna")

for event in session.agent_traces:
    print(event.time, event.name, event.type, event.content)

session.agent_traces removes repeated cumulative histories while preserving system prompts, human messages, paired tool calls, AI messages, and the timestamp where each event first appeared.

Install

Use uv and install only the provider extras you need:

uv add 'traceport[langsmith]'
uv add 'traceport[logfire]'
uv add 'traceport[langfuse]'
uv add 'traceport[phoenix]'

Install MCP support alongside a provider:

uv add 'traceport[mcp,langsmith]'

Helicone uses the core httpx dependency and does not require an extra.

When developing Traceport itself:

cd packages/traceport
uv sync --extra langsmith

Inspect from the CLI

List trace executions or grouped agent sessions, then show a readable transcript:

traceport traces list --provider langsmith --project Branna --since 30d
traceport traces show TRACE_ID --provider langsmith --project Branna

traceport sessions list --provider langsmith --project Branna --since 30d
traceport sessions show SESSION_ID --provider langsmith --project Branna

Transcript output is bounded by default so a large system prompt does not flood the terminal. System messages show up to 1,500 characters and other messages show up to 2,000 characters. Every truncated message preserves both its beginning and end. Every message includes its stable index, original character count, omitted count, and full-content SHA-256 hash.

Expand only the messages you need:

traceport traces show TRACE_ID --provider langsmith --project Branna --expand 0
traceport traces show TRACE_ID --provider langsmith --project Branna --expand 0,3
traceport traces show TRACE_ID --provider langsmith --project Branna --max-chars 5000
traceport traces show TRACE_ID --provider langsmith --project Branna --full
traceport traces show TRACE_ID --provider langsmith --project Branna --json

--expand and --full expose complete provider message content in the terminal, so use them only in an appropriate environment. Traceport Agent uses the same traceport.inspection service with an additional redaction transform and separate model-facing budgets.

The original commands remain compatible: traceport traces and traceport sessions still list, while singular traceport trace TRACE_ID and traceport session SESSION_ID retain their original summary/transcript output.

Core Model

Traceport's primary hierarchy is:

Session
├── agent_traces     readable, deduplicated conversation
└── full_traces      complete provider executions
    └── spans        full normalized telemetry

session.agent_traces

Despite the name, agent_traces is a flat list[AgentSpan]. Each event has four fields:

class AgentSpan:
    name: str
    type: Literal[
        "system_prompt",
        "human_message",
        "tool_call",
        "ai_message",
    ]
    content: str | AgentToolCall
    time: datetime | None

For example:

2026-06-21 23:12:05+00:00  System      system_prompt  You are a concise assistant.
2026-06-21 23:12:05+00:00  Human       human_message  Count to three in Spanish.
2026-06-21 23:12:05+00:00  ChatOpenAI  ai_message     uno, dos, tres
2026-06-21 23:12:11+00:00  Human       human_message  And in German?
2026-06-21 23:12:11+00:00  ChatOpenAI  ai_message     eins, zwei, drei

Providers such as LangSmith often include the complete conversation history in every later trace. Traceport runs transcript extraction across the whole session, deduplicates repeated messages, and keeps the timestamp from the first trace where each event appeared.

Tool invocations and results are paired into one event:

for event in session.agent_traces:
    if event.type == "tool_call":
        call = event.content
        print(call.name)
        print(call.input)
        print(call.output)

AgentToolCall contains:

class AgentToolCall:
    name: str
    input: Any | None
    output: Any | None

session.full_traces

Use full traces only when you need observability details:

for trace in session.full_traces:
    print(trace.id, trace.name, trace.status, trace.latency_ms)

    for span in trace.spans:
        print(span.id, span.name, span.span_kind, span.model)

Full traces preserve supporting HTTP, database, chain, and infrastructure spans. Untouched provider records remain available through each model's raw escape hatch, but raw is excluded from normal model serialization.

session.model_dump() returns the lightweight session summary. It intentionally excludes both the computed transcript and the potentially large full_traces payload.

Sessions

list_sessions() returns lightweight summaries and defaults to sessions containing agent activity:

sessions = client.list_sessions(
    project="Branna",
    since="7d",
    agent_only=True,
    limit=100,
    scan_limit=500,
)

for ref in sessions:
    print(ref.id, ref.trace_count, ref.agent_span_count, ref.status)

get_session() hydrates the selected session:

session = client.get_session(sessions[0].id, project="Branna")

Traceport uses provider-native session, thread, or conversation identifiers when available. If a provider does not expose one, the trace becomes a synthetic session with ID trace:<trace-id>.

Some providers can identify agent sessions natively. Others use a bounded candidate scan. Set scan_limit to control the maximum work. Traceport emits ScanLimitWarning if the bound may have truncated the result set.

Individual Traces

Use trace-level APIs when you need one specific provider execution rather than the entire conversation:

refs = client.list_traces(
    project="Branna",
    since="24h",
    agent_only=True,
    error=False,
    limit=50,
)

trace = client.get_trace(refs[0].id, project="Branna")

for event in trace.agent_spans:
    print(event.time, event.type, event.content)

trace.agent_spans applies the same readable extraction to one trace. trace.spans contains its complete telemetry.

Provider-independent filtering is available through F:

from traceport import F

traces = client.query_traces(
    F.project("Branna")
    & F.since("24h")
    & F.has_agent_spans()
    & F.model_contains("gpt"),
    limit=100,
)

Supported filters include project, time range, status, model, latency, cost, metadata, name, and agent-span presence. Unsupported native predicates are post-filtered after normalization rather than silently ignored.

Provider Configuration

Provider Required environment variables Optional Extra
LangSmith LANGSMITH_API_KEY LANGSMITH_ENDPOINT, LANGSMITH_WORKSPACE_ID langsmith
Logfire LOGFIRE_READ_TOKEN LOGFIRE_BASE_URL, LOGFIRE_PROJECT, LOGFIRE_ENVIRONMENT logfire
Langfuse LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY LANGFUSE_HOST, LANGFUSE_PROJECT langfuse
Phoenix PHOENIX_COLLECTOR_ENDPOINT, PHOENIX_PROJECT_NAME PHOENIX_API_KEY phoenix
Braintrust BRAINTRUST_API_KEY BRAINTRUST_API_URL, BRAINTRUST_PROJECT_ID braintrust
Weave WANDB_API_KEY, WEAVE_PROJECT weave
Helicone HELICONE_API_KEY HELICONE_BASE_URL core
Datadog DD_API_KEY, DD_APP_KEY DD_SITE datadog

Example:

export LANGSMITH_API_KEY=...
export LANGSMITH_PROJECT=Branna
client = TraceClient.from_env("langsmith")
sessions = client.list_sessions(project="Branna", since="7d")

Provider Capabilities

Provider Read method Session identity Agent discovery
memory In-memory Native or synthetic Complete reference behavior
langsmith Runs SDK Thread metadata Bounded hydration
logfire SQL records OTel/GenAI attributes Native SQL child-record query
langfuse SDK and observations API Native session ID Bounded hydration
phoenix Spans API session.id OpenInference kinds
braintrust BTQL Session/thread metadata Bounded hydration
weave Calls SDK Session/thread metadata or synthetic Bounded hydration
helicone REST requests Native session ID Native; every request is an LLM call
datadog Planned Planned Planned

All active adapters preserve complete telemetry after an agent session is selected. Filtering a session for agent activity never removes its supporting spans from full_traces.

MCP Server

The MCP server is intentionally small and transcript-focused. Each server process reads one provider and one project and exposes exactly two read-only tools:

  • list_sessions(since="7d", until=None, error=None, limit=20)
  • get_session(session_id)

get_session returns the session summary and one flat agent_traces transcript. MCP never exposes full_traces, normalized spans, raw provider records, trace filters, or exporters.

Install MCP with the provider extra:

uv add 'traceport[mcp,langsmith]'

The generic stdio command is:

export TRACEPORT_PROVIDER=langsmith
export TRACEPORT_PROJECT=Branna
export LANGSMITH_API_KEY=...
uv run traceport-mcp

FastMCP uses stdio by default. An MCP stdio process must write only MCP protocol messages to stdout; diagnostic logging belongs on stderr.

Codex with a local checkout

Add a server with the Codex CLI:

codex mcp add traceport-langsmith \
  --env TRACEPORT_PROVIDER=langsmith \
  --env TRACEPORT_PROJECT=Branna \
  --env LANGSMITH_API_KEY=... \
  -- uv run \
    --directory /absolute/path/to/packages/traceport \
    --extra mcp \
    --extra langsmith \
    traceport-mcp

Or add the equivalent TOML from examples/mcp.codex.toml to ~/.codex/config.toml or a trusted project's .codex/config.toml.

Codex with the published package

codex mcp add traceport-langsmith \
  --env TRACEPORT_PROVIDER=langsmith \
  --env TRACEPORT_PROJECT=Branna \
  --env LANGSMITH_API_KEY=... \
  -- uvx --from 'traceport[mcp,langsmith]' traceport-mcp

Run one named MCP server per provider/project combination:

traceport-branna-langsmith
traceport-production-logfire

The server instructs clients to list sessions before hydration, starts with a seven-day window, defaults to 20 results, caps requests at 100, and warns clients not to repeat identical calls because observability providers may rate-limit reads.

Export Full Traces

Export is available through the Python API for full observability workflows:

trace = session.full_traces[0]

client.export_trace(trace, format="json")
client.export_trace(trace, format="otel")
client.export_trace(trace, format="openinference")

OpenInference is the default format and emits OTLP JSON with normalized OpenInference attributes.

Local Testing

The memory adapter provides deterministic offline behavior:

from traceport import Span, SpanKind, Trace, TraceClient
from traceport.adapters.memory import MemoryAdapter

trace = Trace(
    id="trace-1",
    session_id="session-1",
    provider="memory",
    spans=[
        Span(
            id="span-1",
            trace_id="trace-1",
            name="chat.completion",
            span_kind=SpanKind.LLM,
            inputs=[{"role": "user", "content": "hello"}],
            outputs=[{"role": "assistant", "content": "hi"}],
        )
    ],
)

client = TraceClient(adapter=MemoryAdapter([trace]))
session = client.get_session("session-1")
print(session.agent_traces)

Development

cd packages/traceport
UV_CACHE_DIR=/tmp/uv-cache uv sync
UV_CACHE_DIR=/tmp/uv-cache uv run ruff format src tests
UV_CACHE_DIR=/tmp/uv-cache uv run ruff check src tests
UV_CACHE_DIR=/tmp/uv-cache uv run mypy src
UV_CACHE_DIR=/tmp/uv-cache uv run pytest
UV_CACHE_DIR=/tmp/uv-cache uv build

No live provider calls run in CI. Provider behavior is covered with scrubbed fixtures.

Third-party adapters can register through the traceport.adapters entry point:

[project.entry-points."traceport.adapters"]
acme = "acme_traceport:AcmeAdapter"

Adapters must subclass traceport.adapters.BaseAdapter. Unsupported filters must be translated, post-filtered against normalized traces, or rejected with UnsupportedFilterError.

Project details


Download files

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

Source Distribution

traceport-0.2.0.tar.gz (48.8 kB view details)

Uploaded Source

Built Distribution

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

traceport-0.2.0-py3-none-any.whl (64.1 kB view details)

Uploaded Python 3

File details

Details for the file traceport-0.2.0.tar.gz.

File metadata

  • Download URL: traceport-0.2.0.tar.gz
  • Upload date:
  • Size: 48.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for traceport-0.2.0.tar.gz
Algorithm Hash digest
SHA256 445b765a499b821767d6d80f740213644c66e0db0246dd89a68976e7d92b8ed1
MD5 cbc410889d68e52cd40a7beb5c1fe0e4
BLAKE2b-256 6058ec7666bab824697ab128975023e8f458780a89ebd21a5cc3f1ee70792d7a

See more details on using hashes here.

Provenance

The following attestation bundles were made for traceport-0.2.0.tar.gz:

Publisher: publish.yml on TheValmarAI/traceport

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

File details

Details for the file traceport-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: traceport-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 64.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for traceport-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 126c0faf94d821e70e9f5845c7a1f258e2352e109ef7b56365ccd22a6e620330
MD5 3193a5b8d64f9eed6bbe0bb8c3321259
BLAKE2b-256 09a031aa45f7f815d6b88faa3b7eba9d1cfb6e78b8e4b4836335f47a63afea52

See more details on using hashes here.

Provenance

The following attestation bundles were made for traceport-0.2.0-py3-none-any.whl:

Publisher: publish.yml on TheValmarAI/traceport

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 Pingdom Monitoring Sentry Error logging StatusPage Status page