fix(image): prevent duplicate delivery and replay artifacts

This commit is contained in:
Xubin Ren
2026-05-09 05:45:13 +00:00
parent 4d168c571c
commit 3231aaf9ee
9 changed files with 128 additions and 32 deletions
+12
View File
@@ -289,6 +289,18 @@ def test_build_messages_passes_channel_to_system_prompt(tmp_path) -> None:
assert "messaging app" in system
def test_system_prompt_keeps_message_tool_out_of_current_chat_replies(tmp_path) -> None:
workspace = _make_workspace(tmp_path)
builder = ContextBuilder(workspace)
prompt = builder.build_system_prompt(channel="slack")
assert "Do not use the 'message' tool for normal replies in the current chat" in prompt
assert "the runtime attaches those artifacts to the final assistant reply automatically" in prompt
assert "do not call 'message' just to announce or resend them" in prompt
assert "Wait for the tool results, then answer once" in prompt
def test_subagent_result_does_not_create_consecutive_assistant_messages(tmp_path) -> None:
workspace = _make_workspace(tmp_path)
builder = ContextBuilder(workspace)
+38 -9
View File
@@ -245,14 +245,8 @@ def test_get_history_annotates_user_turns_but_not_assistant_turns():
]
def test_get_history_annotates_proactive_assistant_deliveries_with_timestamps():
"""Cron / heartbeat assistant pushes still carry a timestamp prefix.
These proactive deliveries can sit hours away from the next user reply,
so the model needs to know when they fired. They are rare enough that
they don't act as in-context demonstrations encouraging the model to
prefix its own normal replies with ``[Message Time: ...]``.
"""
def test_get_history_does_not_annotate_proactive_assistant_deliveries_with_timestamps():
"""Assistant-side timestamp examples can leak back into future replies."""
session = Session(key="test:proactive-timestamps")
session.messages.append({
"role": "assistant",
@@ -271,7 +265,7 @@ def test_get_history_annotates_proactive_assistant_deliveries_with_timestamps():
assert history == [
{
"role": "assistant",
"content": "[Message Time: 2026-04-26T15:00:00]\n记得喝水",
"content": "记得喝水",
},
{
"role": "user",
@@ -370,6 +364,41 @@ def test_get_history_ignores_media_kwarg_on_non_user_rows():
assert history[0]["content"] == [{"type": "text", "text": "structured"}]
def test_get_history_does_not_paste_assistant_media_paths_into_replay():
session = Session(key="test:assistant-media")
session.messages.append(
{
"role": "assistant",
"content": "来了 🎨",
"media": ["/home/user/.nanobot/media/generated/img_abc.png"],
}
)
history = session.get_history(max_messages=500)
assert history == [{"role": "assistant", "content": "来了 🎨"}]
def test_get_history_sanitizes_existing_assistant_replay_artifacts():
session = Session(key="test:polluted-assistant")
session.messages.append(
{
"role": "assistant",
"content": (
"[Message Time: 2026-05-09 00:33:48]\n"
"来了 🎨\n"
"[image: /home/user/.nanobot/media/generated/img_old.png]\n\n"
"generate_image(\"16:9\")\n"
"message(\"来了 🎨\")"
),
}
)
history = session.get_history(max_messages=500, include_timestamps=True)
assert history == [{"role": "assistant", "content": "来了 🎨"}]
def test_get_history_respects_max_tokens(monkeypatch):
session = Session(key="test:token-cap")
session.messages.extend(