From 0133459ce95a495948ed8ed49b6c2d118d7df6c8 Mon Sep 17 00:00:00 2001 From: Fabian Schindler Date: Tue, 5 May 2026 11:20:44 +0200 Subject: [PATCH 1/2] feat(integrations): pass along the conversation ID for openai `responses` calls --- sentry_sdk/integrations/openai.py | 12 +++++++ tests/integrations/openai/test_openai.py | 43 ++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/sentry_sdk/integrations/openai.py b/sentry_sdk/integrations/openai.py index 480db9132d..c901b1130a 100644 --- a/sentry_sdk/integrations/openai.py +++ b/sentry_sdk/integrations/openai.py @@ -347,6 +347,18 @@ def _set_responses_api_input_data( if top_p is not None and _is_given(top_p): span.set_data(SPANDATA.GEN_AI_REQUEST_TOP_P, top_p) + conversation = kwargs.get("conversation") + if conversation is not None and _is_given(conversation): + conversation_id: "Optional[str]" + if isinstance(conversation, str): + conversation_id = conversation + elif isinstance(conversation, dict): + conversation_id = conversation.get("id") + else: + conversation_id = getattr(conversation, "id", None) + if conversation_id is not None: + span.set_data(SPANDATA.GEN_AI_CONVERSATION_ID, conversation_id) + if not should_send_default_pii() or not integration.include_prompts: set_data_normalized(span, SPANDATA.GEN_AI_OPERATION_NAME, "responses") return diff --git a/tests/integrations/openai/test_openai.py b/tests/integrations/openai/test_openai.py index 20bbf2adf5..a415021f86 100644 --- a/tests/integrations/openai/test_openai.py +++ b/tests/integrations/openai/test_openai.py @@ -2836,6 +2836,49 @@ def test_ai_client_span_responses_api( assert spans[0]["data"] == expected_data +@pytest.mark.parametrize( + "conversation, expected_id", + [ + pytest.param(omit, None, id="omit"), + pytest.param(None, None, id="none"), + pytest.param("conv_abc123", "conv_abc123", id="string"), + pytest.param({"id": "conv_abc123"}, "conv_abc123", id="dict"), + pytest.param( + mock.Mock(spec=["id"], id="conv_abc123"), + "conv_abc123", + id="object_with_id_attr", + ), + ], +) +@pytest.mark.skipif(SKIP_RESPONSES_TESTS, reason="Responses API not available") +def test_responses_api_conversation_id( + sentry_init, capture_events, conversation, expected_id +): + sentry_init( + integrations=[OpenAIIntegration()], + traces_sample_rate=1.0, + ) + events = capture_events() + + client = OpenAI(api_key="z") + client.responses._post = mock.Mock(return_value=EXAMPLE_RESPONSE) + + with start_transaction(name="openai tx"): + client.responses.create( + model="gpt-4o", + input="hello", + conversation=conversation, + ) + + (transaction,) = events + (span,) = transaction["spans"] + + if expected_id is None: + assert "gen_ai.conversation.id" not in span["data"] + else: + assert span["data"]["gen_ai.conversation.id"] == expected_id + + @pytest.mark.skipif(SKIP_RESPONSES_TESTS, reason="Responses API not available") def test_error_in_responses_api(sentry_init, capture_events): sentry_init( From 9f88ee7150cb576e38119b2ab3b1a92806dc77b9 Mon Sep 17 00:00:00 2001 From: Fabian Schindler Date: Tue, 5 May 2026 12:06:49 +0200 Subject: [PATCH 2/2] fix: conversation can only be either `str` or `dict` --- sentry_sdk/integrations/openai.py | 4 +--- tests/integrations/openai/test_openai.py | 5 ----- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/sentry_sdk/integrations/openai.py b/sentry_sdk/integrations/openai.py index c901b1130a..45aac3d410 100644 --- a/sentry_sdk/integrations/openai.py +++ b/sentry_sdk/integrations/openai.py @@ -349,13 +349,11 @@ def _set_responses_api_input_data( conversation = kwargs.get("conversation") if conversation is not None and _is_given(conversation): - conversation_id: "Optional[str]" + conversation_id: "Optional[str]" = None if isinstance(conversation, str): conversation_id = conversation elif isinstance(conversation, dict): conversation_id = conversation.get("id") - else: - conversation_id = getattr(conversation, "id", None) if conversation_id is not None: span.set_data(SPANDATA.GEN_AI_CONVERSATION_ID, conversation_id) diff --git a/tests/integrations/openai/test_openai.py b/tests/integrations/openai/test_openai.py index a415021f86..677beb5681 100644 --- a/tests/integrations/openai/test_openai.py +++ b/tests/integrations/openai/test_openai.py @@ -2843,11 +2843,6 @@ def test_ai_client_span_responses_api( pytest.param(None, None, id="none"), pytest.param("conv_abc123", "conv_abc123", id="string"), pytest.param({"id": "conv_abc123"}, "conv_abc123", id="dict"), - pytest.param( - mock.Mock(spec=["id"], id="conv_abc123"), - "conv_abc123", - id="object_with_id_attr", - ), ], ) @pytest.mark.skipif(SKIP_RESPONSES_TESTS, reason="Responses API not available")