Skip to content

fix: merge responses developer messages into system prompt - #26884

Closed
samrusani wants to merge 1 commit into
BerriAI:litellm_internal_stagingfrom
samrusani:fix/issue-26879-merge-responses-system-messages
Closed

samrusani wants to merge 1 commit into
BerriAI:litellm_internal_stagingfrom
samrusani:fix/issue-26879-merge-responses-system-messages

Conversation

@samrusani

@samrusani samrusani commented Apr 30, 2026

Copy link
Copy Markdown

Relevant issues

Fixes #26879

Pre-Submission checklist

  • I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

Screenshots / Proof of Fix

uv run pytest tests/test_litellm/responses/litellm_completion_transformation/test_litellm_completion_responses.py -q
# 65 passed in 0.24s

uv run pytest tests/test_litellm/responses/litellm_completion_transformation/test_litellm_completion_responses.py --cov=litellm.responses.litellm_completion_transformation.transformation --cov-report=term-missing -q
# 65 passed in 0.30s
# The new merge helper lines are not listed as missing.

make lint-ruff
# All checks passed!

uv run black --check litellm/responses/litellm_completion_transformation/transformation.py tests/test_litellm/responses/litellm_completion_transformation/test_litellm_completion_responses.py
# 2 files would be left unchanged.

Type

🐛 Bug Fix
✅ Test

Changes

  • Merge Responses API instructions and developer role input items into one leading chat-completion system message before the Responses-to-chat bridge forwards the request.
  • Extract text from string and input_text/text content blocks so Codex-style developer messages are preserved in the merged system prompt.
  • Add regression tests covering instructions plus multiple developer messages, requests without system content, and supported/ignored text block extraction so non-OpenAI providers no longer receive multiple system messages.

Notes

make format-check currently reports unrelated formatting drift in existing enterprise files outside this PR's diff. The two changed files pass Black directly.

@samrusani

Copy link
Copy Markdown
Author

@greptileai

@codecov

codecov Bot commented Apr 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@greptile-apps

greptile-apps Bot commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a bug where Responses API developer-role input items were forwarded as-is to non-OpenAI providers that don't recognize the role. The fix introduces _merge_responses_system_messages, which collects all system and developer role messages (including the top-level instructions field) and merges them into a single leading system message before the Responses-to-chat-completion bridge dispatches the request.

  • _get_text_from_message_content extracts text from bare strings, text and input_text content blocks, and falls back to str() for other non-None values; image_url and unsupported block types are intentionally ignored.
  • _merge_responses_system_messages coalesces every system/developer message in order into one ChatCompletionSystemMessage, with a short-circuit that returns the original list unchanged when no system content is present.
  • Three regression tests cover the merged-instructions path, the no-system-content path, and the text-extraction edge cases; all are pure unit tests with no network calls.

Confidence Score: 5/5

Safe to merge; the change is narrowly scoped to the Responses-API-to-chat-completion transformation path and does not touch authentication, routing, or database access.

The core merging logic is correct for all typical inputs: string content, list-of-content-blocks, and the instructions field are all handled and tested. No new issues beyond those already raised in prior review threads were found. The fix resolves the original bug (developer-role messages reaching providers that reject the role) for the common case.

No files require special attention beyond what has already been discussed in prior review comments on transformation.py.

Important Files Changed

Filename Overview
litellm/responses/litellm_completion_transformation/transformation.py Adds _get_text_from_message_content and _merge_responses_system_messages helpers, then wires them into transform_responses_api_input_to_messages so all system/developer role messages are coalesced into a single leading system message before the chat-completion bridge; logic is correct for the happy path but has edge-case fragility around empty-content system messages and non-dict message objects (flagged in prior review threads).
tests/test_litellm/responses/litellm_completion_transformation/test_litellm_completion_responses.py Adds three new unit tests: merging instructions + developer messages, preserving messages without system content, and text-block extraction; all are pure mocked tests with no network calls, satisfying the repo's test-isolation rule.

Reviews (2): Last reviewed commit: "fix: merge responses developer messages ..." | Re-trigger Greptile

@samrusani
samrusani force-pushed the fix/issue-26879-merge-responses-system-messages branch from 2cc9940 to 7356b87 Compare April 30, 2026 13:33
@krrish-berri-2

Copy link
Copy Markdown
Contributor

@samrusani — could you add a screenshot or short video showing that this change works as expected? It really helps reviewers verify the fix quickly. Thanks!

@samrusani

Copy link
Copy Markdown
Author

Thanks. This is a backend Responses API transformation fix, so there is no UI flow to capture.

I added proof in the PR body with the targeted regression test and coverage command output. The regression test verifies that Responses API instructions plus multiple developer messages are transformed into exactly one leading system message before forwarding to non-OpenAI providers.

Commands run:

uv run pytest tests/test_litellm/responses/litellm_completion_transformation/test_litellm_completion_responses.py -q
# 65 passed in 0.24s

uv run pytest tests/test_litellm/responses/litellm_completion_transformation/test_litellm_completion_responses.py --cov=litellm.responses.litellm_completion_transformation.transformation --cov-report=term-missing -q
# 65 passed in 0.30s
# The new merge helper lines are not listed as missing.

Codecov also now reports: All modified and coverable lines are covered by tests.

@samrusani

Copy link
Copy Markdown
Author

Hi maintainers, just checking in on this one. This PR is intentionally scoped to the Responses API bridge path for #26879, with CI passing, Codecov passing, Veria passing, and Greptile at 5/5. Happy to adjust if you prefer a different shape for the fix.

@samrusani

Copy link
Copy Markdown
Author

Withdrawing this PR to reduce stale contributor backlog. It may be reopened if maintainers want the work continued.

@samrusani samrusani closed this Sep 9, 2026
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] Multiple system messages sent to non-OpenAI providers when using Responses API with developer role messages

3 participants