feat: v0.4.1 — ChatGPT tool-output content types and conv_id fix
First real-data export against v0.4.0 surfaced 66 unknown blocks across three content types — captured live and added. Added: - execution_output (Code Interpreter / container.exec / python tool output) → tool_result block. output=content.text, tool_name=author.name, is_error=metadata.aggregate_result.status, summary=metadata.reasoning_title - system_error → error tool_result with tool_name=author.name - tether_browsing_display: spinner placeholders (empty result+summary) skip silently with DEBUG log; defensive populated-case branch maps to tool_result (untested in real data) - tool_result block schema: optional `summary` field rendered as italic line between header and fence - tool_result rendering: tool_name appears in header when present (e.g. `📤 Result: container.exec`); existing tool_name=None calls unchanged - _ROLE_LABELS["tool"] = ("🔧 Tool", "tool") Fixed: - chatgpt.normalize_conversation reads `conversation_id` as fallback for `id`. Live API uses conversation_id; fixtures use id. Pre-fix: empty id in YAML frontmatter and missing context in WARNING logs. Tests: 11 new (192 total, 0 failures). Fixture extended with 4 tool-output cases (execution_output success, empty execution_output that should skip, system_error, tether_browsing_display spinner). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -80,13 +80,19 @@ def make_tool_result_block(
|
||||
output: str,
|
||||
tool_name: str | None = None,
|
||||
is_error: bool = False,
|
||||
summary: str | None = None,
|
||||
) -> dict:
|
||||
"""Return a tool_result block."""
|
||||
"""Return a tool_result block.
|
||||
|
||||
``summary`` is an optional short human label rendered between header and
|
||||
fence (e.g. ChatGPT's ``metadata.reasoning_title`` for execution_output).
|
||||
"""
|
||||
return {
|
||||
"type": BLOCK_TYPE_TOOL_RESULT,
|
||||
"tool_name": tool_name,
|
||||
"output": output if isinstance(output, str) else str(output),
|
||||
"is_error": bool(is_error),
|
||||
"summary": summary,
|
||||
}
|
||||
|
||||
|
||||
@@ -217,10 +223,21 @@ def _render_one(block: dict) -> str:
|
||||
if btype == BLOCK_TYPE_TOOL_RESULT:
|
||||
output = block.get("output", "")
|
||||
is_error = bool(block.get("is_error"))
|
||||
header = "❌ **Result (error)**" if is_error else "📤 **Result**"
|
||||
tool_name = block.get("tool_name") or ""
|
||||
summary = block.get("summary") or ""
|
||||
icon = "❌" if is_error else "📤"
|
||||
label = "Result (error)" if is_error else "Result"
|
||||
if tool_name:
|
||||
header = f"{icon} **{label}: {tool_name}**"
|
||||
else:
|
||||
header = f"{icon} **{label}**"
|
||||
fence = _safe_fence(output)
|
||||
body = f"{fence}\n{output}\n{fence}"
|
||||
return _blockquote_prefix(f"{header}\n{body}")
|
||||
if summary:
|
||||
inner = f"{header}\n*{summary}*\n{body}"
|
||||
else:
|
||||
inner = f"{header}\n{body}"
|
||||
return _blockquote_prefix(inner)
|
||||
if btype == BLOCK_TYPE_CITATION:
|
||||
url = block.get("url", "")
|
||||
title = block.get("title") or url
|
||||
|
||||
Reference in New Issue
Block a user