Skip to content

Commit 1a428e7

Browse files
authored
normalize messages from sub-LLM calls to prevent errors (#664)
1 parent 77ccb16 commit 1a428e7

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

verifiers/envs/experimental/rlm_env.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,15 +664,43 @@ async def _call_sub_tool(
664664
"tool_call_id": tool_call_id,
665665
}
666666

667+
def _normalize_message_content(self, messages: list[dict]) -> list[dict]:
668+
"""Normalize message content fields to formats the API accepts.
669+
670+
The API expects content to be: string, array of objects, or None.
671+
Handles several malformed cases:
672+
1. Content is a nested message dict (has 'role' and 'content' keys) - extract inner content
673+
2. Content is a content part object (has 'type' key) - wrap in array
674+
"""
675+
normalized = []
676+
for msg in messages:
677+
msg_copy = dict(msg)
678+
content = msg_copy.get("content")
679+
680+
if content is not None and isinstance(content, dict):
681+
# Check if content is a nested message dict (has 'role' and 'content' keys)
682+
# This happens when model passes message dicts to llm_batch instead of strings
683+
if "role" in content and "content" in content:
684+
msg_copy["content"] = content["content"]
685+
elif "type" in content:
686+
# Content part object (e.g. {"type": "text", "text": "..."}) - wrap in array
687+
msg_copy["content"] = [content]
688+
else:
689+
# Unknown dict structure - try wrapping in array as fallback
690+
msg_copy["content"] = [content]
691+
normalized.append(msg_copy)
692+
return normalized
693+
667694
async def _call_sub_llm_api(
668695
self, client: Any, model: str, messages: list[dict], tools: list | None = None
669696
) -> Any | None:
670697
"""Make a single sub-LLM API call with timeout. Returns None on timeout."""
698+
normalized_messages = self._normalize_message_content(messages)
671699
try:
672700
return await asyncio.wait_for(
673701
client.chat.completions.create(
674702
model=model,
675-
messages=messages,
703+
messages=normalized_messages,
676704
tools=tools,
677705
logprobs=self._sub_llm_supports_logprobs or None,
678706
),

0 commit comments

Comments
 (0)