withSpan or @span decorators needed. To make those runs replayable, a thin run wrapper (wrapRun / wrap_run) records a root span carrying the run input; see Replayable runs with the run wrapper.
Canonical signatures: TypeScript reference · Python reference
Supported Languages
Quick Start
Use
addTraceProcessor / add_trace_processor (shown above) to add the Bitfab processor alongside any existing ones. The OpenAI Agents SDK also exposes setTraceProcessors / set_trace_processors, which replaces the entire processor list, including the SDK’s default exporter to the OpenAI platform dashboard. Only use the set form if you want Bitfab to be the sole destination and intend to disable OpenAI’s own tracing.TypeScript
Installation
Method Signature
BitfabOpenAITracingProcessor instance that implements the OpenAI Agents SDK TracingProcessor interface.
Usage
What Gets Captured
The processor implements theTracingProcessor interface and captures:
Span types from the OpenAI Agents SDK (agent, function, generation, guardrail, handoff, etc.) are mapped to Bitfab span data automatically.
Nesting with Core Tracing
If you wrap an agent invocation withwithSpan, the OpenAI Agents spans nest as children:
Error Handling
All processor callbacks are wrapped in try/catch - errors are logged but never thrown. Your agent execution is never affected by tracing failures.Python
Installation
openai-tracing extra installs openai-agents as a dependency.
Method Signature
BitfabOpenAITracingProcessor instance that implements the OpenAI Agents SDK TracingProcessor interface.
Usage
What Gets Captured
Same as TypeScript - the processor implements theTracingProcessor interface:
Nesting with Core Tracing
Error Handling
All processor callbacks are wrapped in try/except - errors are logged but never raised. Your agent execution is never affected by tracing failures. Traces flush automatically viaatexit hook.
Replayable runs with the run wrapper
The tracing processor captures the agent run for observability, but the processor alone records a root span with no input. The OpenAI Agents agent span is the trace root, and the run input never lands on it (only a response child span carries the model-request input). Replay re-runs the trace’s root span against its recorded input, so a processor-only trace would replay with nothing to feed it. The run wrapper makes a run replayable with no hand-written root.getOpenAiAgentHandler(key).wrapRun (TS) / get_openai_agent_handler(key).wrap_run (Python) is a drop-in for the run call: it opens a keyed root span carrying the run input and final output, and the processor’s auto-captured spans nest underneath. Keep the processor registered for the internals; swap the run call for the wrapper.
@span/withSpan-decorated function needs to exist. Rebuild runtime wiring inside the callable (agent construction, tools, API keys). Put unsafe calls behind replay-mockable marked spans; use a no-op only for a replay-only callback slot with no recorded call to mock.
Alternative: a hand-written root. When there is meaningful work around the run (input prep, orchestration, post-processing), wrap the whole workflow in a withSpan / @span root that takes the workflow input (the same wrap shown in Nesting with Core Tracing). The processor’s spans nest underneath it, and replay re-runs the root against its recorded input. Full details in the Python SDK and TypeScript SDK Replay sections.
Streaming runs
Streamed runs are also traced: the run input lands on the root span and the final output is captured once the stream drains, so first-byte latency is untouched.wrapRun returns the streamed run result (drained by the caller) and records the root in the background once it completes. In Python, wrap_run_streamed is itself an async generator that yields each event from Runner.run_streamed(...).stream_events(); the span stays open for the whole iteration so the processor’s spans nest beneath the root.
To replay a recorded run as a regression with
bitfab.replay(), use the non-streaming wrapper (wrapRun / wrap_run), which replay re-runs directly. bitfab.replay() does not drive the Python wrap_run_streamed async generator.Trace metadata
This integration exports its own trace under the same canonical trace id as the traced function, and that export carries metadata of its own. Metadata the caller recorded, throughseedTrace / seed_trace or setMetadata / set_metadata, is merged onto that export and takes precedence per key, so a seeded case’s provenance survives and reaches a later replay’s adaptInputs / adapt_inputs hook as ctx.metadata / ctx["metadata"].
Keys the integration set that the caller did not are kept, so ctx.metadata can carry keys the caller never wrote. A key set on both sides to different values keeps the caller’s value and warns once per trace.
The merge needs both sides on the same canonical trace id, which is what running the integration nested inside a traced function gives them. A processor-only setup, with no enclosing traced function, resolves its own trace id and has no caller metadata to merge. An export that lands after the traced function returned, as a streamed run’s does, still merges. Requires the TypeScript or Python SDK v0.52.3 or later.