From 4f2e321c233d55ee8e7187792da743970661c818 Mon Sep 17 00:00:00 2001 From: Ritiz Tambi Date: Fri, 27 Feb 2026 09:16:15 -0500 Subject: [PATCH] fix(openai-agents): capture response.instructions as system prompt on generation spans --- .../instrumentation/openai_agents/_hooks.py | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/_hooks.py b/packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/_hooks.py index e3805cb209..2f03caac3f 100644 --- a/packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/_hooks.py +++ b/packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/_hooks.py @@ -310,6 +310,19 @@ def _extract_response_attributes(otel_span, response, trace_content: bool): return model_settings +def _prepend_system_instruction(input_data, response, trace_content: bool): + """Prepend response.instructions as a system message to input data if available.""" + if not ( + trace_content + and response + and hasattr(response, "instructions") + and response.instructions + ): + return input_data + system_msg = {"role": "system", "content": response.instructions} + return [system_msg] + (input_data if input_data else []) + + class OpenTelemetryTracingProcessor(TracingProcessor): """ A tracing processor that creates OpenTelemetry spans for OpenAI Agents. @@ -622,10 +635,13 @@ def on_span_end(self, span): ): # Extract prompt data from input input_data = getattr(span_data, "input", []) - _extract_prompt_attributes(otel_span, input_data, trace_content) - # Add function/tool specifications to the request using OpenAI semantic conventions + # Prepend system instructions from the response if available + # (the vanilla openai instrumentor already does this in responses_wrappers.py) response = getattr(span_data, "response", None) + input_data = _prepend_system_instruction(input_data, response, trace_content) + + _extract_prompt_attributes(otel_span, input_data, trace_content) if ( response and hasattr(response, "tools") @@ -672,9 +688,11 @@ def on_span_end(self, span): # Legacy fallback for other span types elif span_data: input_data = getattr(span_data, "input", []) - _extract_prompt_attributes(otel_span, input_data, trace_content) response = getattr(span_data, "response", None) + input_data = _prepend_system_instruction(input_data, response, trace_content) + + _extract_prompt_attributes(otel_span, input_data, trace_content) if response: model_settings = _extract_response_attributes(otel_span, response, trace_content) self._last_model_settings = model_settings