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:
co-authored by
shakewingo
bingqilinweimaotai
parent
393d429e0a
commit
e703481755
@@ -19,6 +19,7 @@ from nanobot.runtime_context import public_history_messages
|
||||
from nanobot.session.manager import Session, SessionManager
|
||||
from nanobot.utils.gitstore import GitStore
|
||||
from nanobot.utils.helpers import (
|
||||
content_with_media_breadcrumbs,
|
||||
ensure_dir,
|
||||
estimate_message_tokens,
|
||||
estimate_prompt_tokens_chain,
|
||||
@@ -695,11 +696,17 @@ class MemoryStore:
|
||||
def _format_messages(messages: list[dict]) -> str:
|
||||
lines = []
|
||||
for message in messages:
|
||||
if not message.get("content"):
|
||||
content = content_with_media_breadcrumbs(
|
||||
message.get("role"),
|
||||
message.get("content", ""),
|
||||
message.get("media"),
|
||||
)
|
||||
if not content:
|
||||
continue
|
||||
tools = f" [tools: {', '.join(message['tools_used'])}]" if message.get("tools_used") else ""
|
||||
lines.append(
|
||||
f"[{message.get('timestamp', '?')[:16]}] {message['role'].upper()}{tools}: {message['content']}"
|
||||
f"[{message.get('timestamp', '?')[:16]}] "
|
||||
f"{message['role'].upper()}{tools}: {content}"
|
||||
)
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@ from nanobot.runtime_context import (
|
||||
public_history_message,
|
||||
)
|
||||
from nanobot.utils.helpers import (
|
||||
content_with_media_breadcrumbs,
|
||||
ensure_dir,
|
||||
estimate_message_tokens,
|
||||
find_legal_message_start,
|
||||
image_placeholder_text,
|
||||
recent_message_start_index,
|
||||
safe_filename,
|
||||
strip_think,
|
||||
@@ -214,12 +214,11 @@ class Session:
|
||||
# image used to be. Without this, an image-only user turn
|
||||
# replays as an empty user message — the assistant's reply then
|
||||
# looks like it's responding to nothing.
|
||||
media = message.get("media")
|
||||
if role == "user" and isinstance(media, list) and media and isinstance(content, str):
|
||||
breadcrumbs = "\n".join(
|
||||
image_placeholder_text(p) for p in media if isinstance(p, str) and p
|
||||
)
|
||||
content = f"{content}\n{breadcrumbs}" if content else breadcrumbs
|
||||
content = content_with_media_breadcrumbs(
|
||||
role,
|
||||
content,
|
||||
message.get("media"),
|
||||
)
|
||||
cli_apps = message.get("cli_apps")
|
||||
if (
|
||||
include_runtime_context
|
||||
|
||||
@@ -367,6 +367,24 @@ def image_placeholder_text(path: str | None, *, empty: str = "[image]") -> str:
|
||||
return f"[image: {path}]" if path else empty
|
||||
|
||||
|
||||
def content_with_media_breadcrumbs(
|
||||
role: str | None,
|
||||
content: Any,
|
||||
media: Any,
|
||||
) -> Any:
|
||||
"""Append persisted user-media breadcrumbs to plain-text content."""
|
||||
if role != "user" or not isinstance(content, str) or not isinstance(media, list):
|
||||
return content
|
||||
breadcrumbs = "\n".join(
|
||||
image_placeholder_text(path)
|
||||
for path in media
|
||||
if isinstance(path, str) and path
|
||||
)
|
||||
if not breadcrumbs:
|
||||
return content
|
||||
return f"{content}\n{breadcrumbs}" if content else breadcrumbs
|
||||
|
||||
|
||||
def truncate_text(text: str, max_chars: int) -> str:
|
||||
"""Truncate text with a stable suffix."""
|
||||
if max_chars <= 0 or len(text) <= max_chars:
|
||||
|
||||
Reference in New Issue
Block a user