responses feedback items: whitelist input-shape fields — api rejects response-only fields like status as unknown parameters (live 400)

This commit is contained in:
Oleksandr Kozachuk
2026-07-17 19:45:36 +02:00
parent 144aa38ace
commit 5e564522a0
3 changed files with 43 additions and 7 deletions
+27 -2
View File
@@ -304,6 +304,31 @@ class OpenAIResponder(AIResponder, LeonardoAIDrawMixIn):
items.append({"role": role, "content": str(content)})
return items
# Only these item types travel back as input; response-only fields like `status`
# are rejected by the API as unknown parameters (live 400, 2026-07-17)
_RESPONSES_FEEDBACK_FIELDS = {
"reasoning": ("id", "summary", "encrypted_content"),
"function_call": ("id", "call_id", "name", "arguments"),
}
@classmethod
def _responses_feedback(cls, output: List[Any]) -> List[Dict[str, Any]]:
"""Reasoning + function_call items in input shape — keeps the chain of thought (ENV-23)."""
items: List[Dict[str, Any]] = []
for item in output or []:
fields = cls._RESPONSES_FEEDBACK_FIELDS.get(getattr(item, "type", None) or "")
if not fields:
continue # message items need not travel back
data: Dict[str, Any] = {"type": item.type}
for field in fields:
value = getattr(item, field, None)
if field == "summary" and isinstance(value, list):
value = [part if isinstance(part, dict) else part.model_dump() for part in value]
if value is not None:
data[field] = value
items.append(data)
return items
@staticmethod
def _responses_refused(result: Any) -> bool:
for item in getattr(result, "output", []) or []:
@@ -350,8 +375,8 @@ class OpenAIResponder(AIResponder, LeonardoAIDrawMixIn):
return answer, limit
tool_names = [call.name for call in calls]
logging.info(f"🔧 OpenAI requested function calls: {tool_names}")
# Pass ALL output items back — reasoning items keep the chain of thought (ENV-23)
context = context + [item if isinstance(item, dict) else item.model_dump() for item in result.output]
# Pass reasoning + function_call items back — keeps the chain of thought (ENV-23)
context = context + self._responses_feedback(result.output)
for call in calls:
function_args = json.loads(call.arguments) if call.arguments else {}
logging.info(f"🔧 Executing tool: {call.name} with args: {function_args}")