mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-05-19 16:12:30 +00:00
refactor(agent): extract ContextBuilder.build_user_content() as public method
Consolidates _build_user_content + _build_runtime_context + merge logic into a single public method. Both build_messages() and loop._drain_pending._to_user_message now call it, eliminating cross-module coupling to private methods.
This commit is contained in:
parent
e804f2fddb
commit
96afdbcfcb
@ -157,23 +157,14 @@ class ContextBuilder:
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Build the complete message list for an LLM call."""
|
||||
extra = goal_state_runtime_lines(session_metadata)
|
||||
runtime_ctx = self._build_runtime_context(
|
||||
channel,
|
||||
chat_id,
|
||||
self.timezone,
|
||||
merged = self.build_user_content(
|
||||
current_message,
|
||||
media=media,
|
||||
channel=channel,
|
||||
chat_id=chat_id,
|
||||
sender_id=sender_id,
|
||||
supplemental_lines=extra or None,
|
||||
)
|
||||
user_content = self._build_user_content(current_message, media)
|
||||
|
||||
# Merge runtime context and user content into a single user message
|
||||
# to avoid consecutive same-role messages that some providers reject.
|
||||
# Runtime context is appended to keep the user-content prefix stable
|
||||
# for prompt-cache hits (the context changes every turn due to time).
|
||||
if isinstance(user_content, str):
|
||||
merged = f"{user_content}\n\n{runtime_ctx}"
|
||||
else:
|
||||
merged = user_content + [{"type": "text", "text": runtime_ctx}]
|
||||
messages = [
|
||||
{"role": "system", "content": self.build_system_prompt(skill_names, channel=channel, session_summary=session_summary)},
|
||||
*history,
|
||||
@ -186,6 +177,25 @@ class ContextBuilder:
|
||||
messages.append({"role": current_role, "content": merged})
|
||||
return messages
|
||||
|
||||
def build_user_content(
|
||||
self,
|
||||
text: str,
|
||||
media: list[str] | None = None,
|
||||
channel: str | None = None,
|
||||
chat_id: str | None = None,
|
||||
sender_id: str | None = None,
|
||||
supplemental_lines: Sequence[str] | None = None,
|
||||
) -> str | list[dict[str, Any]]:
|
||||
"""Build user content with media and runtime context merged into one payload."""
|
||||
raw = self._build_user_content(text, media)
|
||||
runtime_ctx = self._build_runtime_context(
|
||||
channel, chat_id, self.timezone,
|
||||
sender_id=sender_id, supplemental_lines=supplemental_lines,
|
||||
)
|
||||
if isinstance(raw, str):
|
||||
return f"{raw}\n\n{runtime_ctx}"
|
||||
return raw + [{"type": "text", "text": runtime_ctx}]
|
||||
|
||||
def _build_user_content(self, text: str, media: list[str] | None) -> str | list[dict[str, Any]]:
|
||||
"""Build user message content with optional base64-encoded images."""
|
||||
if not media:
|
||||
|
||||
@ -727,19 +727,15 @@ class AgentLoop:
|
||||
if media:
|
||||
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,
|
||||
merged = self.context.build_user_content(
|
||||
content,
|
||||
media=media,
|
||||
channel=pending_msg.channel,
|
||||
chat_id=self._runtime_chat_id(pending_msg),
|
||||
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}
|
||||
|
||||
items: list[dict[str, Any]] = []
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user