fix(memory): expose media references to session consolidation (#5157)

Co-authored-by: shakewingo <yaoyingshakewin@gmail.com>
Co-authored-by: bingqilinweimaotai <111987281+bingqilinweimaotai@users.noreply.github.com>
This commit is contained in:
chengyongru
2026-07-29 15:18:44 +08:00
committed by GitHub
co-authored by shakewingo bingqilinweimaotai
parent 393d429e0a
commit e703481755
5 changed files with 96 additions and 9 deletions
+35
View File
@@ -75,6 +75,41 @@ def _tool_round(call_id: str) -> list[dict]:
class TestConsolidatorSummarize:
async def test_archive_prompt_includes_media_breadcrumb(
self, consolidator, mock_provider, store, runtime
):
path = "/home/user/.nanobot/media/websocket/upload_photo.png"
summary = "User uploaded a photo."
mock_provider.chat_with_retry.return_value = MagicMock(
content=summary,
finish_reason="stop",
)
result = await consolidator.archive(
[{"role": "user", "content": "please inspect this", "media": [path]}],
runtime=runtime,
)
prompt = mock_provider.chat_with_retry.call_args.kwargs["messages"][1]["content"]
entries = store.read_unprocessed_history(since_cursor=0)
assert f"[image: {path}]" in prompt
assert result == summary
assert [entry["content"] for entry in entries] == [summary]
def test_format_messages_keeps_media_only_user_turn(self):
path = "/home/user/.nanobot/media/websocket/clip.mp4"
formatted = MemoryStore._format_messages([
{
"role": "user",
"content": "",
"media": [path],
"timestamp": "2026-07-27",
}
])
assert formatted == f"[2026-07-27] USER: [image: {path}]"
async def test_archive_excludes_model_only_runtime_context(
self, consolidator, mock_provider, runtime
):
+28
View File
@@ -7,6 +7,7 @@ import tiktoken
from nanobot.utils import helpers
from nanobot.utils.helpers import (
_write_text_atomic,
content_with_media_breadcrumbs,
current_time_str,
split_message,
truncate_text_to_tokens,
@@ -55,6 +56,33 @@ def test_current_time_str_rejects_unknown_timezone():
current_time_str("Not/AZone")
def test_content_with_media_breadcrumbs_preserves_valid_paths():
assert content_with_media_breadcrumbs(
"user",
"review these",
["/media/report.pdf", "/media/clip.mp4"],
) == (
"review these\n"
"[image: /media/report.pdf]\n"
"[image: /media/clip.mp4]"
)
def test_content_with_media_breadcrumbs_only_rewrites_plain_user_content():
structured = [{"type": "text", "text": "hello"}]
assert content_with_media_breadcrumbs(
"assistant",
"done",
["/media/output.png"],
) == "done"
assert content_with_media_breadcrumbs(
"user",
structured,
["/media/input.png"],
) is structured
def test_write_text_atomic_fsyncs_file_and_parent_directory(
tmp_path: Path, monkeypatch
) -> None: