From e5893075f9b5eb10a5dcc1736851ef8f80615888 Mon Sep 17 00:00:00 2001 From: teknium1 Date: Sun, 1 Mar 2026 20:03:03 -0800 Subject: [PATCH] feat(agent): add summary handling for reasoning items Enhanced the AIAgent class to capture and normalize summary information for reasoning items. Implemented logic to handle summaries as lists, ensuring proper formatting for API interactions. Updated tests to validate the inclusion of summaries in reasoning items, both for existing and default cases. --- run_agent.py | 14 ++++++++++++++ tests/test_provider_parity.py | 5 ++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/run_agent.py b/run_agent.py index 7d9d5a2c..155c6f8c 100644 --- a/run_agent.py +++ b/run_agent.py @@ -1596,6 +1596,11 @@ class AIAgent: item_id = item.get("id") if isinstance(item_id, str) and item_id: reasoning_item["id"] = item_id + summary = item.get("summary") + if isinstance(summary, list): + reasoning_item["summary"] = summary + else: + reasoning_item["summary"] = [] normalized.append(reasoning_item) continue @@ -1828,6 +1833,15 @@ class AIAgent: item_id = getattr(item, "id", None) if isinstance(item_id, str) and item_id: raw_item["id"] = item_id + # Capture summary — required by the API when replaying reasoning items + summary = getattr(item, "summary", None) + if isinstance(summary, list): + raw_summary = [] + for part in summary: + text = getattr(part, "text", None) + if isinstance(text, str): + raw_summary.append({"type": "summary_text", "text": text}) + raw_item["summary"] = raw_summary reasoning_items_raw.append(raw_item) elif item_type == "function_call": if item_status in {"queued", "in_progress", "incomplete"}: diff --git a/tests/test_provider_parity.py b/tests/test_provider_parity.py index 5b8508e6..00fc4dd9 100644 --- a/tests/test_provider_parity.py +++ b/tests/test_provider_parity.py @@ -539,7 +539,8 @@ class TestCodexReasoningPreflight: base_url="https://chatgpt.com/backend-api/codex") raw_input = [ {"role": "user", "content": "hello"}, - {"type": "reasoning", "encrypted_content": "abc123encrypted", "id": "r_001"}, + {"type": "reasoning", "encrypted_content": "abc123encrypted", "id": "r_001", + "summary": [{"type": "summary_text", "text": "Thinking about it"}]}, {"role": "assistant", "content": "hi there"}, ] normalized = agent._preflight_codex_input_items(raw_input) @@ -547,6 +548,7 @@ class TestCodexReasoningPreflight: assert len(reasoning_items) == 1 assert reasoning_items[0]["encrypted_content"] == "abc123encrypted" assert reasoning_items[0]["id"] == "r_001" + assert reasoning_items[0]["summary"] == [{"type": "summary_text", "text": "Thinking about it"}] def test_reasoning_item_without_id(self, monkeypatch): agent = _make_agent(monkeypatch, "openai-codex", api_mode="codex_responses", @@ -557,6 +559,7 @@ class TestCodexReasoningPreflight: normalized = agent._preflight_codex_input_items(raw_input) assert len(normalized) == 1 assert "id" not in normalized[0] + assert normalized[0]["summary"] == [] # default empty summary def test_reasoning_item_empty_encrypted_skipped(self, monkeypatch): agent = _make_agent(monkeypatch, "openai-codex", api_mode="codex_responses",