Repository navigation
[opentelemetry-instrumentation-genai-openai] Record gen_ai.conversation.compacted on Responses spans - #900
Conversation
Set the attribute when the request input or the response output contains a compaction item. Assisted-by: Claude Opus 5.5
Assisted-by: Claude Opus 5.5
Pull request dashboard statusWaiting on the author · refreshed 2026-10-17 01:45 UTC Respond to 3 review items (e.g. link a commit, explain why not, ask a follow-up): Status above doesn't look right?
|
There was a problem hiding this comment.
🟡 Changes recommended
Streams closed or interrupted after an observed compaction item lose the compaction attribute.
1 open finding
What changed in this PR
Adds compaction detection to OpenAI Responses telemetry, independently of content capture.
Changes:
- Sets
gen_ai.conversation.compactedwhen request or response items contain compaction. - Adds extractor, sync, async, and streaming coverage with recorded responses.
- Documents the addition in a changelog fragment.
Paths below are relative to instrumentation/opentelemetry-instrumentation-genai-openai/.
| File | Description |
|---|---|
tests/test_utils.py |
Adds shared compaction fixtures. |
tests/test_responses.py |
Tests synchronous compaction detection. |
tests/test_response_extractors.py |
Tests detection and unset behavior. |
tests/test_async_responses.py |
Tests asynchronous compaction detection. |
tests/cassettes/test_responses_create_streaming_records_server_compaction[content_mode0].yaml |
Supplies streaming compaction events. |
tests/cassettes/test_responses_create_records_server_compaction[content_mode0].yaml |
Supplies a compacted response. |
src/opentelemetry/instrumentation/genai/openai/response_extractors.py |
Detects request and response compaction items. |
.changelog/900.added |
Announces the telemetry addition. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Assisted-by: Claude Opus 5.5
A stream closed or interrupted before the terminal response never delivers it, so record a streamed compaction item as it arrives. Assisted-by: Claude Opus 5.5
| if set_stream_event_attributes is not None: | ||
| set_stream_event_attributes(self._self_invocation, event) |
There was a problem hiding this comment.
nit: FetchResponseStreamWrapper inherits process_event, so a streamed responses.retrieve replay sets conversation_compacted on a FetchResponseInvocation. It has no such field.
Consider adding attribute to fetch span or separating inference from fetching response here.
| _skip_if_not_latest() | ||
|
|
||
| response = openai_client.responses.create( | ||
| model=REASONING_MODEL, |
There was a problem hiding this comment.
nit: both compaction cassettes were recorded with gpt-5.4 (and an AsyncOpenAI user agent), but the sync/async tests send REASONING_MODEL (gpt-5.1). They only pass because VCR doesn't match on body. Maybe use gpt-5.4 here, like the conformance scenario does?
| _requires_context_management = pytest.mark.skipif( | ||
| not _has_context_management_param, | ||
| reason="openai SDK too old to support 'context_management' on Responses.create", | ||
| ) |
There was a problem hiding this comment.
nit: _requires_context_management is defined after the first two compaction tests, which repeat the same skipif inline. Same thing in test_async_responses.py. Maybe define it once, above those tests, and use it everywhere?

Sets
gen_ai.conversation.compactedtotrueon OpenAI Responses API spans when the request input or the response output contains acompactionitem. Covers sync, async, and streaming, and is independent of content capture. Per semconv, the attribute is left unset rather thanfalsewhen no compaction is seen.Anthropic compaction support is handled with the
beta.messagesinstrumentation in #781, which maps compaction blocks toCompactionPart. Anthropic compaction exists only in the beta API, so the non-beta wrapper is unchanged.Known gaps:
opentelemetry-semantic-conventionsships the constant.CompactionPartin captured OpenAI messages; that will be a follow-up PR.🤖 Generated with Claude Code