Skip to content

fix(openai-agents): capture response.instructions as system prompt in generation spans#4131

Open
dvirski wants to merge 1 commit into
mainfrom
dr/fix(openai-agents)-capture-response.instructions-as-system-prompt-in-generation-spans
Open

fix(openai-agents): capture response.instructions as system prompt in generation spans#4131
dvirski wants to merge 1 commit into
mainfrom
dr/fix(openai-agents)-capture-response.instructions-as-system-prompt-in-generation-spans

Conversation

@dvirski
Copy link
Copy Markdown

@dvirski dvirski commented May 12, 2026

Fixes #3738.

Problem:
When an OpenAI Agent had instructions set, the system prompt was silently dropped from generation spans — only the conversation history was recorded, with no role: system message.

Fix:
Prepend response.instructions as a role: system message to the input messages array in _end_generation_span() before passing to _extract_prompt_attributes(). Consistent with how responses_wrappers.py handles it in the plain openai instrumentation.

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced tracing to properly capture agent instructions in trace data when trace content is enabled.
  • Tests

    • Updated test assertions to verify correct message ordering in traced content.
    • Added new tests for instruction handling in trace generation.

Review Change Stack

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Dvir Rezenman seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 73aa64ca-c1fc-4711-bb06-944986884d48

📥 Commits

Reviewing files that changed from the base of the PR and between 6d3e696 and c2d4b1d.

⛔ Files ignored due to path filters (2)
  • packages/opentelemetry-instrumentation-openai-agents/uv.lock is excluded by !**/*.lock
  • packages/sample-app/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/_hooks.py
  • packages/opentelemetry-instrumentation-openai-agents/tests/test_openai_agents.py
  • packages/opentelemetry-instrumentation-openai-agents/tests/test_tracing_processor.py

📝 Walkthrough

Walkthrough

The PR fixes a bug where OpenAI Agents instrumentation did not capture response.instructions as a system message in traced prompts. The implementation prepends instructions as the first system message when content tracing is enabled, with corresponding unit and integration tests validating the behavior under both tracing conditions.

Changes

Capture response.instructions as system message

Layer / File(s) Summary
System message injection in _end_generation_span
opentelemetry/instrumentation/openai_agents/_hooks.py
_end_generation_span now extracts response early and conditionally prepends response.instructions as a system message to input_data when trace_content is enabled, then passes the modified list to _extract_prompt_attributes.
Unit tests for response.instructions handling
tests/test_tracing_processor.py
Two new test methods validate that response.instructions is inserted as the first system message in GEN_AI_INPUT_MESSAGES when trace_content=True, and omitted when trace_content=False.
Integration test assertions for message ordering
tests/test_openai_agents.py
Updated test_agent_spans to locate the system message at index 0 and find the user message by role, ensuring the new system message injection is reflected in end-to-end test assertions.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A system message hops into place,
First in the trace, taking its space,
Instructions now heard, no longer lost,
Agent wisdom captured—the bug is crossed! 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and accurately summarizes the main change: capturing response.instructions as a system prompt in generation spans for OpenAI Agents instrumentation.
Linked Issues check ✅ Passed The code changes fully implement the fix specified in issue #3738: prepending response.instructions as a system message to input_data before calling _extract_prompt_attributes when trace_content is enabled.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing issue #3738. The modifications to _hooks.py, test_openai_agents.py, and test_tracing_processor.py are all scoped to implementing the response.instructions capture feature.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dr/fix(openai-agents)-capture-response.instructions-as-system-prompt-in-generation-spans

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@dvirski dvirski changed the title fix(openai-agents): capture response.instructions as system prompt in fix(openai-agents): capture response.instructions as system prompt in generation spans May 12, 2026
@doronkopit5
Copy link
Copy Markdown
Member

Overall looks good — clean, targeted fix that mirrors the pattern in responses_wrappers.py. Two small suggestions before merge:

  1. Defensive normalization of input_data — at _hooks.py:946, if input_data is ever a str (the Responses API allows input: str), list + str will TypeError. Today the agents SDK passes a list, but a cheap guard avoids a future footgun:

    existing = input_data if isinstance(input_data, list) else []
    input_data = [{"role": "system", "content": response.instructions}] + existing

    This also keeps the line under the lint length limit.

  2. Two tiny edge-case tests worth adding alongside the existing ones:

    • input_data == [] with only instructions → asserts single system-message output.
    • instructions == "" → asserts the empty/falsy case is skipped (locks in the current getattr(..., None) truthy check).

Otherwise LGTM 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 Bug Report: OpenAI Agents instrumentor does not capture response.instructions (system prompt)

3 participants