fix: assistant input content must be output_text, not input_text

Live /v1/responses rejects input_text for the assistant role
(input[N].content[0] -> "Supported values are: 'output_text' and
'refusal'"). Revert the previous review-driven change: encode assistant
turns as output_text and user/system turns as input_text. The SDK type
union suggested input_* only, but the API enforces output_text per-role —
confirmed against the live endpoint.
This commit is contained in:
Alex committed 2026-06-03 15:00:14 +01:00
1 parent 27f9ddc8e0
commit 9a69e89096
2 files changed
+8 -9

No files matched your search

+5 -8
View File
@@ -461,15 +461,12 @@ class OpenAILLM(BaseLLM):
@staticmethod
def _responses_content_parts(role, content):
"""Translate a cleaned chat ``content`` value into Responses content
parts (``input_text``/``input_image``/``input_file``).
Assistant text from prior turns is replayed as ``input_text`` too: a
Responses easy-input message only accepts the input_* content types
regardless of role (``output_text`` is reserved for full
output-message items, which carry id/status/annotations).
parts. The Responses API enforces the content-part type by message
role: assistant turns require ``output_text`` (``input_text`` is
rejected with a 400), while user/system turns require ``input_text``.
Images/files use ``input_image``/``input_file``.
"""
_ = role
text_type = "input_text"
text_type = "output_text" if role == "assistant" else "input_text"
parts = []
if content is None:
return parts
+3 -1
View File
@@ -102,7 +102,9 @@ def test_to_responses_input_tool_roundtrip(monkeypatch):
"arguments": '{"q":"x"}',
},
{"type": "function_call_output", "call_id": "call_1", "output": "result"},
{"role": "assistant", "content": [{"type": "input_text", "text": "final"}]},
# The Responses API requires output_text (not input_text) for the
# assistant role; input_text 400s. Locked in here so it can't regress.
{"role": "assistant", "content": [{"type": "output_text", "text": "final"}]},
]