[inkling] Render tool-result media instead of coercing content to str (#33898)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Eric Zhang
2026-08-08 14:39:19 +08:00
committed by GitHub
co-authored by Claude Opus 5
parent 6185ed8011
commit c69d59395b
2 changed files with 147 additions and 20 deletions
+19 -20
View File
@@ -99,17 +99,26 @@ def render_inkling_messages(
append_effort()
role = _expect_role(message)
if role == "tool":
tool_name = message.get("name") or tool_call_id_to_name.get(
message.get("tool_call_id") or "", ""
)
_append_message(
input_ids,
tokenizer,
"tool",
"text",
_expect_string_content(message.get("content", "")),
author_name=str(tool_name),
tool_name = str(
message.get("name")
or tool_call_id_to_name.get(message.get("tool_call_id") or "", "")
)
# The MM processor harvests media from tool messages, so coercing content
# to one string would drop images and desync the placeholder count.
tool_parts = list(_iter_render_parts(message.get("content", "")))
if not tool_parts:
tool_parts = [("text", "")] # else the answered tool_call dangles
for kind, text in tool_parts:
if kind == "thinking":
raise ValueError("Inkling thinking parts require role='assistant'")
_append_message(
input_ids,
tokenizer,
"tool",
kind,
text,
author_name=tool_name,
)
continue
parts = list(_iter_render_parts(message.get("content", "")))
@@ -249,16 +258,6 @@ def _format_reasoning_effort(reasoning_effort: float) -> str:
return f"{round(value, 2):g}"
def _expect_string_content(content: Any) -> str:
if content is None:
return ""
if not isinstance(content, str):
raise TypeError(
f"message content must be a string for this Inkling role, got {type(content).__name__}"
)
return content
def _expect_role(message: Mapping[str, Any]) -> str:
role = message.get("role")
if role not in ROLE_MESSAGE_TOKENS: