Skip to main content
Bitfab records requests your code sends to the OpenAI Responses API through the official openai client: the prompt, the model, token counts, and latency. Bitfab works out the cost from the model and the token counts, or keeps the cost the response reports when it carries one. Canonical signatures: TypeScript wrapOpenAIResponses · Python wrap_openai_responses

Language Support

Under a trace root

Beneath a trace root, every non-streaming responses.create call on an openai client is recorded with no wrapper, whatever its base URL, as its own llm span named Responses.create (Python’s async client: AsyncResponses.create). The span attaches under the function that made the call.
The trace shows detect, then classify, then an llm span named Responses.create carrying the prompt, tokens, and cost. In TypeScript, the build transform rewrites each .responses.create(...) call site in your code, so it works in bundled apps and the SDK never loads or patches openai. The client’s own APIPromise is handed back, so .withResponse() keeps working. In Python, the SDK patches the openai responses classes when a trace() root is set up. exclude: ["create"] on the root skips these calls, and withNode() / node() on a wrapper (below) configures the one span.

Wrapping a call

Use wrapOpenAIResponses() / wrap_openai_responses() when you trace with withSpan() / span() instead of a trace root. It wraps the function that sends the request and writes the prompt and usage into the span that is current when the call starts. It opens no span of its own.
Beneath a trace root, a wrapper around a call that is already recorded as Responses.create records nothing more. onResponse / on_response receives each response after it is recorded.

No duplicate spans

Each model call is recorded once:
  • A wrapper around a call the trace root already recorded adds nothing.
  • A call the OpenAI Agents SDK integration is recording as a generation or response span, or the LangChain callback handler is recording as an LLM run, is not recorded a second time. This includes a call made inside your own LangChain chat model class or inside your own Agents model class that opens a generation span. A call made alongside a LangChain run in the same trace is still recorded, except beside the first LangChain run in a TypeScript process (see Limitations).
  • In TypeScript, calls made inside framework libraries in node_modules are never rewritten by the build transform, so only the framework’s own integration records them. The built-in OpenAIResponsesModel opens a response span, so its calls are left to that integration.
A custom OpenAI Agents SDK model class that calls responses.create directly opens no generation or response span, so its calls are recorded as Responses.create spans under the agent run.

What gets captured

The context fields go in one context entry on the span. A key the response does not carry is left out. Without costUsd, Bitfab works out the cost from model and the token counts.

Limitations

  • Streaming calls are not recorded. A call with stream: true / stream=True runs normally and records nothing.
  • Calls outside any trace are not recorded. A wrapper used outside a span or trace records nothing and never starts a trace of its own.
  • TypeScript automatic capture needs the build transform. Code the transform does not compile (for example a call made from a dependency) is not rewritten; wrap it instead.
  • TypeScript: calls beside the first LangChain run in a process. The SDK hooks into LangChain in the background when the first Bitfab LangChain handler or withTrace() root is created. If a LangChain run starts before that finishes, calls made inside it are still recorded once, but a call made at the same time outside it (for example in Promise.all) is not recorded while that first run is open. Later runs are not affected.
  • Python automatic capture needs Python 3.12+, the same as trace() subtree capture.
  • Only responses.create. The responses.parse and responses.stream helpers are not recorded. For chat completions sent to OpenRouter, see OpenRouter.