diff --git a/src/takopi/runners/codex.py b/src/takopi/runners/codex.py index 111cea3..ff7d595 100644 --- a/src/takopi/runners/codex.py +++ b/src/takopi/runners/codex.py @@ -129,8 +129,15 @@ def _summarize_tool_result(result: Any) -> dict[str, Any] | None: summary["content_blocks"] = len(content) elif content is not None: summary["content_blocks"] = 1 - if "structured" in result: - summary["has_structured"] = bool(result.get("structured")) + + structured_key: str | None = None + if "structured_content" in result: + structured_key = "structured_content" + elif "structured" in result: + structured_key = "structured" + + if structured_key is not None: + summary["has_structured"] = result.get(structured_key) is not None return summary or None diff --git a/tests/test_codex_tool_result_summary.py b/tests/test_codex_tool_result_summary.py new file mode 100644 index 0000000..b93e194 --- /dev/null +++ b/tests/test_codex_tool_result_summary.py @@ -0,0 +1,69 @@ +from takopi.model import ActionEvent +from takopi.runners.codex import translate_codex_event + + +def test_translate_mcp_tool_call_summarizes_structured_content() -> None: + evt = { + "type": "item.completed", + "item": { + "id": "item_1", + "type": "mcp_tool_call", + "server": "docs", + "tool": "search", + "arguments": {"q": "hi"}, + "result": { + "content": [{"type": "text", "text": "ok"}], + "structured_content": {"matches": 3}, + }, + "error": None, + "status": "completed", + }, + } + + out = translate_codex_event(evt, title="Codex") + assert len(out) == 1 + assert isinstance(out[0], ActionEvent) + summary = out[0].action.detail["result_summary"] + assert summary["content_blocks"] == 1 + assert summary["has_structured"] is True + + +def test_translate_mcp_tool_call_summarizes_null_structured_content() -> None: + evt = { + "type": "item.completed", + "item": { + "id": "item_2", + "type": "mcp_tool_call", + "server": "docs", + "tool": "search", + "result": {"content": [], "structured_content": None}, + "error": None, + "status": "completed", + }, + } + + out = translate_codex_event(evt, title="Codex") + assert len(out) == 1 + assert isinstance(out[0], ActionEvent) + assert out[0].action.detail["result_summary"]["has_structured"] is False + + +def test_translate_mcp_tool_call_summarizes_legacy_structured_key() -> None: + evt = { + "type": "item.completed", + "item": { + "id": "item_3", + "type": "mcp_tool_call", + "server": "docs", + "tool": "search", + "result": {"structured": {"matches": 3}}, + "error": None, + "status": "completed", + }, + } + + out = translate_codex_event(evt, title="Codex") + assert len(out) == 1 + assert isinstance(out[0], ActionEvent) + assert out[0].action.detail["result_summary"]["has_structured"] is True +