fix(agent): remove duplicate runtime context injection in mid-turn drain

_drain_pending injected a full runtime context block (including goal
state) into every injected user message, but the initial message already
carries runtime context via build_messages(). This caused goal state to
appear multiple times in the LLM context window within a single turn,
wasting tokens (up to 4000 chars per duplicate).

Now _drain_pending only passes the raw user content without runtime
context. The initial turn message remains the sole carrier.
This commit is contained in:
chengyongru 2026-05-16 19:28:11 +08:00 committed by Xubin Ren
parent 45eacc3a98
commit 8a819dda1e

View File

@ -33,7 +33,6 @@ from nanobot.config.schema import AgentDefaults, ModelPresetConfig
from nanobot.providers.base import LLMProvider
from nanobot.providers.factory import ProviderSnapshot
from nanobot.session.goal_state import (
goal_state_runtime_lines,
goal_state_ws_blob,
runner_wall_llm_timeout_s,
)
@ -728,19 +727,7 @@ class AgentLoop:
content, media = extract_documents(content, media)
media = media or None
user_content = self.context._build_user_content(content, media)
extra = goal_state_runtime_lines(session.metadata) if session is not None else []
runtime_ctx = self.context._build_runtime_context(
pending_msg.channel,
self._runtime_chat_id(pending_msg),
self.context.timezone,
sender_id=pending_msg.sender_id,
supplemental_lines=extra or None,
)
if isinstance(user_content, str):
merged: str | list[dict[str, Any]] = f"{user_content}\n\n{runtime_ctx}"
else:
merged = user_content + [{"type": "text", "text": runtime_ctx}]
return {"role": "user", "content": merged}
return {"role": "user", "content": user_content}
items: list[dict[str, Any]] = []
while len(items) < limit: