Migrated ruby-openai instrumentation to new integration API #78
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Purpose
This PR migrates the
ruby-openaigem (alexrudall) instrumentation from the legacy monolithicwrap()API to the new Integration API framework. This brings ruby-openai in line with the officialopenaigem integration and establishes a consistent instrumentation interface across all OpenAI-compatible providers. It also enables us to enable auto-instrumentation for this library.Key goals:
Braintrust.instrument!(:ruby_openai)interface for both class-level and instance-level instrumentationopenaiandruby-openaiintegrations to reduce code duplicationBraintrust::Trace::AlexRudall::RubyOpenAI.wrap()API with a clear migration pathArchitectural Overview
New Modular Structure
Three-Layer Design
Integration Layer (
integration.rb): Manages gem detection, version requirements, and delegates to patchers viainstrument!Patcher Layer (
patcher.rb): Thread-safe patching at both class and instance levels:ChatPatcher- patchesOpenAI::Client#chatResponsesPatcher- patchesOpenAI::Responses#createInstrumentation Modules (
instrumentation/*.rb): Method wrappers that create OpenTelemetry spans with input/output/metrics attributesShared Support Utilities
Common code extracted to
lib/braintrust/contrib/support/:Support::OpenAI.parse_usage_tokens: Normalizes token usage from both Chat Completions API (prompt_tokens,completion_tokens) and Responses API (input_tokens,output_tokens)Support::OTel.set_json_attr: Safely sets JSON-serialized span attributesThis eliminates duplication between
openaiandruby-openaiintegrations.Usage Examples
Class-Level Instrumentation (All Clients)
Instrument all
OpenAI::Clientinstances created after theinstrument!call:Instance-Level Instrumentation (Specific Client)
Instrument only a specific client instance, leaving others untraced:
Streaming Support
Both chat and responses streaming are fully supported:
Migration from Legacy API
The old
wrap()API is deprecated but continues to work:A deprecation warning is logged when using the old API.
Changes Summary
Added
lib/braintrust/contrib/ruby_openai/- New modular integration structurelib/braintrust/contrib/support/openai.rb- Shared token parsing utilitieslib/braintrust/contrib/support/otel.rb- Shared OTel span utilitiesexamples/contrib/ruby_openai/- Updated examples for new APIChanged
lib/braintrust/contrib/openai/- Now uses shared support utilitiesexamples/contrib/ruby_openai/Removed
lib/braintrust/trace/contrib/github.com/alexrudall/ruby-openai/ruby-openai.rb(377 lines)lib/braintrust/trace/tokens.rb- OpenAI token parsing moved to shared supportlib/braintrust/trace.rb