"""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