From 03b83fb79ee91833accd47ef9cf81d68eedcde62 Mon Sep 17 00:00:00 2001 From: Re-bin Date: Tue, 3 Mar 2026 05:13:17 +0000 Subject: [PATCH] fix(agent): skip empty multimodal user entries after runtime-context strip --- nanobot/agent/loop.py | 2 ++ tests/test_loop_save_turn.py | 41 ++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/test_loop_save_turn.py diff --git a/nanobot/agent/loop.py b/nanobot/agent/loop.py index 825b11a..65a62e5 100644 --- a/nanobot/agent/loop.py +++ b/nanobot/agent/loop.py @@ -480,6 +480,8 @@ class AgentLoop: filtered.append({"type": "text", "text": "[image]"}) else: filtered.append(c) + if not filtered: + continue entry["content"] = filtered entry.setdefault("timestamp", datetime.now().isoformat()) session.messages.append(entry) diff --git a/tests/test_loop_save_turn.py b/tests/test_loop_save_turn.py new file mode 100644 index 0000000..aec6d1a --- /dev/null +++ b/tests/test_loop_save_turn.py @@ -0,0 +1,41 @@ +from nanobot.agent.context import ContextBuilder +from nanobot.agent.loop import AgentLoop +from nanobot.session.manager import Session + + +def _mk_loop() -> AgentLoop: + loop = AgentLoop.__new__(AgentLoop) + loop._TOOL_RESULT_MAX_CHARS = 500 + return loop + + +def test_save_turn_skips_multimodal_user_when_only_runtime_context() -> None: + loop = _mk_loop() + session = Session(key="test:runtime-only") + runtime = ContextBuilder._RUNTIME_CONTEXT_TAG + "\nCurrent Time: now (UTC)" + + loop._save_turn( + session, + [{"role": "user", "content": [{"type": "text", "text": runtime}]}], + skip=0, + ) + assert session.messages == [] + + +def test_save_turn_keeps_image_placeholder_after_runtime_strip() -> None: + loop = _mk_loop() + session = Session(key="test:image") + runtime = ContextBuilder._RUNTIME_CONTEXT_TAG + "\nCurrent Time: now (UTC)" + + loop._save_turn( + session, + [{ + "role": "user", + "content": [ + {"type": "text", "text": runtime}, + {"type": "image_url", "image_url": {"url": "data:image/png;base64,abc"}}, + ], + }], + skip=0, + ) + assert session.messages[0]["content"] == [{"type": "text", "text": "[image]"}]