CheddahBot/cheddahbot/router.py

75 lines
2.6 KiB
Python

"""Message formatting and system prompt construction."""
from __future__ import annotations
from pathlib import Path
def build_system_prompt(
identity_dir: Path,
memory_context: str = "",
tools_description: str = "",
) -> str:
"""Build the system prompt from identity files + memory + tools."""
parts = []
# 1. Identity: SOUL.md
soul_path = identity_dir / "SOUL.md"
if soul_path.exists():
parts.append(soul_path.read_text(encoding="utf-8").strip())
# 2. Identity: USER.md
user_path = identity_dir / "USER.md"
if user_path.exists():
parts.append(user_path.read_text(encoding="utf-8").strip())
# 3. Memory context (injected by memory system)
if memory_context:
parts.append(f"# Relevant Memory\n{memory_context}")
# 4. Available tools
if tools_description:
parts.append(f"# Available Tools\n{tools_description}")
# 5. Core instructions
parts.append(
"# Instructions\n"
"- Use tools when they would help answer the user's request.\n"
"- If you learn something important about the user, save it to memory.\n"
"- Be concise but thorough. Don't pad responses unnecessarily.\n"
"- When uncertain, ask for clarification.\n"
"- Reference memories naturally when relevant.\n"
"- IMPORTANT: Do NOT call the same tool twice with the same arguments. "
"If a tool already returned a result, use that result — do not re-call it.\n"
"- After using tools, always respond to the user with a final answer. "
"Do not end your turn with only tool calls and no text.\n"
"- For tasks requiring shell commands, file edits, or system access, "
"use the delegate_task tool instead of trying to do it yourself."
)
return "\n\n---\n\n".join(parts)
def format_messages_for_llm(
system_prompt: str,
history: list[dict],
max_messages: int = 50,
) -> list[dict]:
"""Format conversation history into LLM message format."""
messages = [{"role": "system", "content": system_prompt}]
# Take the most recent messages up to the limit
recent = history[-max_messages:] if len(history) > max_messages else history
for msg in recent:
role = msg.get("role", "user")
content = msg.get("content", "")
if role in ("user", "assistant", "system"):
messages.append({"role": role, "content": content})
elif role == "tool":
# Tool results go as a user message with context
tool_name = msg.get("tool_result", "unknown")
messages.append({"role": "user", "content": f'[Tool "{tool_name}" result]\n{content}'})
return messages