Skip to content

add OpenAI responses support#3901

Closed
M-Hietala wants to merge 12 commits intoopen-telemetry:mainfrom
johanste:copilot/add-openai-responses-support
Closed

add OpenAI responses support#3901
M-Hietala wants to merge 12 commits intoopen-telemetry:mainfrom
johanste:copilot/add-openai-responses-support

Conversation

@M-Hietala
Copy link

Summary

This PR adds instrumentation support for the OpenAI Responses API (structured outputs) to the opentelemetry-instrumentation-openai-v2 library, following the same monkeypatching pattern used for chat completions.

Background

The OpenAI SDK introduced the Responses API (client.responses.create) for structured outputs in version 1.66.0. This API was not previously instrumented, meaning calls to it would not generate telemetry data (spans, logs, or metrics).

Changes

This PR instruments both synchronous and asynchronous versions of the Responses API:

from openai import OpenAI
from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor

OpenAIInstrumentor().instrument()

client = OpenAI()

# Now automatically instrumented!
response = client.responses.create(
    model="gpt-4o-mini",
    input="Write a short poem on open telemetry.",
)

client.conversations.create()

items = client.conversations.items.list(conversation_id=conversation.id)
# Print all the items
for item in items:
    display_conversation_item(item)

Implementation Details

Version Checking:

  • Added _is_responses_api_supported() function to detect if OpenAI SDK >= 1.66.0
  • Instrumentation only wraps responses API when supported version is detected
  • Chat completions instrumentation is always enabled (no version requirement)
  • Uses packaging.version for reliable version comparison

New wrapper functions in patch.py:

  • responses_create() - Wraps synchronous Responses.create method
  • async_responses_create() - Wraps asynchronous AsyncResponses.create method
  • _set_responses_attributes() - Sets span attributes for responses
  • _record_responses_metrics() - Records metrics for responses API calls

Instrumentation hooks in __init__.py:

  • Added conditional wrap_function_wrapper calls for openai.resources.responses.responses.Responses.create
  • Added conditional wrap_function_wrapper calls for openai.resources.responses.responses.AsyncResponses.create
  • Added corresponding conditional unwrap calls in _uninstrument() method

Telemetry Captured

The instrumentation captures (when responses API is available):

  • Spans with attributes including operation name, model, response ID, service tier, and token usage
  • Span events for input/output messages (when OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true)
  • Metrics for operation duration and token usage (input/output tokens)

Tests

Added comprehensive test coverage with version-aware skipping:

  • test_responses.py - Tests for synchronous responses API with/without content capture (skipped if OpenAI < 1.66.0)
  • test_async_responses.py - Tests for asynchronous responses API with/without content capture (skipped if OpenAI < 1.66.0)
  • 'test_conversations.py' - Tests for synchronous conversations API with/without content capture (skipped if OpenAI < 1.101.0)
  • 'test_async_conversations.py' - Tests for asynchronous conversations API with/without content capture (skipped if OpenAI < 1.101.0)

Documentation

Updated documentation to include responses API examples:

  • README.rst - Added usage example showing both chat completions and responses API
  • Module docstring in __init__.py - Added responses API example

Bug Fixes

  • Fixed ChatCompletion imports to use openai.types.chat instead of openai.resources.chat.completions

Testing

Verified that:

  • All methods are correctly wrapped after instrumentation
  • All methods are correctly unwrapped after uninstrumentation
  • Spans capture correct attributes (model, tokens, service tier)
  • Events capture input/output based on content capture setting
  • Metrics are recorded for duration and token usage
  • Implementation follows existing code patterns and style
  • Version checking correctly detects supported/unsupported OpenAI versions (1.66.0 threshold)
  • Tests are automatically skipped when OpenAI version doesn't support responses API
  • ChatCompletion imports are correct and use the proper type location

Compatibility

  • OpenAI SDK: >= 1.26.0 (minimum version), >= 1.66.0 (for responses API support)
  • Python: >= 3.9
  • OpenTelemetry API: ~= 1.37

Backward Compatibility

This implementation maintains full backward compatibility. Users with OpenAI SDK versions < 1.66.0 will continue to have chat completions instrumented while responses API instrumentation is gracefully skipped.

Original prompt

Add support to the openai v2 instrumentation library for the openai responses API. Use the same pattern (monkeypatching) as is done for the chat completions.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 12 commits October 14, 2025 23:51
Co-authored-by: johanste <15110018+johanste@users.noreply.github.com>
Co-authored-by: johanste <15110018+johanste@users.noreply.github.com>
Co-authored-by: johanste <15110018+johanste@users.noreply.github.com>
Co-authored-by: johanste <15110018+johanste@users.noreply.github.com>
…version)

Co-authored-by: johanste <15110018+johanste@users.noreply.github.com>
….resources.chat.completions

Co-authored-by: johanste <15110018+johanste@users.noreply.github.com>
…onversation_support

updated responses and conversation support
@M-Hietala M-Hietala requested a review from a team as a code owner October 28, 2025 17:25
@linux-foundation-easycla
Copy link

CLA Not Signed

@shuwpan
Copy link

shuwpan commented Dec 16, 2025

Just a thought, the patch.py is getting bigger and bigger...anyone think we should split it up ? I assume we will keep adding things in the future. so...just wondering...

@JWinermaSplunk
Copy link

Agree with the previous comment, responses itself could probably be a separate file. Also didn't look too deeply into it, but I think there is a bit of code here that can be moved into helper functions (to prevent duplicate code, decrease clutter, etc).

@iamemilio
Copy link

Just a thought, the patch.py is getting bigger and bigger...anyone think we should split it up ? I assume we will keep adding things in the future. so...just wondering...

There is a style check in one of the test suites that enforces a 1000 line limit for any file otherwise a set of changes will fail to score a 10/10 and the test will get marked fail. I believe a refactor will be necessary to pass CI for these changes.

Comment on lines +38 to +39
response = await async_openai_client.responses.create(
input=input_value, model=llm_model_value
Copy link

@iamemilio iamemilio Dec 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
response = await async_openai_client.responses.create(
input=input_value, model=llm_model_value
response = await async_openai_client.responses.create(
input=input_value,
model=llm_model_value,
stream_options={"include_usage": True}

This will make sure that token usage gets returned, so that we can test that the instrument captures it. That said, I do see usage in your cassettes, so this is more of a nit.

@JWinermaSplunk
Copy link

Hi, is there any progress on this?

@iamemilio
Copy link

I no longer have the capacity to work on this, I'm sorry. Can we mark this is stale so someone else can pick it up? It has been stale for a very long time.

@JWinermaSplunk
Copy link

Hi @iamemilio,

I don't mind picking it up, I was just wondering if there has been any communication from the original author, @M-Hietala?

@iamemilio
Copy link

None that I am aware of, no :(

@xrmx
Copy link
Contributor

xrmx commented Feb 5, 2026

Closing in favor of #4166

@xrmx xrmx closed this Feb 5, 2026
@github-project-automation github-project-automation bot moved this from Reviewed PRs that need fixes to Done in @xrmx's Python PR digest Feb 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.