# agent/prompts.py from typing import Dict, Any import json from .registry import Tool from .parameters import format_parameters_for_prompt, get_missing_required_parameters class PromptBuilder: """Handles construction of system prompts for the agent.""" def __init__(self, tools: Dict[str, Tool]): self.tools = tools def _format_tools_description(self) -> str: """Format tools with their descriptions and parameters.""" return "\n".join( f"- {tool.name}: {tool.description}\n" f" Parameters: {json.dumps(tool.parameters, ensure_ascii=False)}" for tool in self.tools.values() ) def _build_context(self, memory_data: dict) -> Dict[str, Any]: """Build the context object with current state from memory.""" return memory_data def build_system_prompt(self, memory_data: dict) -> str: """ Build the system prompt with context provided as JSON. Args: memory_data: The full memory data dictionary Returns: The complete system prompt string """ context = self._build_context(memory_data) tools_desc = self._format_tools_description() params_desc = format_parameters_for_prompt() # Check for missing required parameters missing_params = get_missing_required_parameters(memory_data) missing_info = "" if missing_params: missing_info = "\n\n⚠️ MISSING REQUIRED PARAMETERS:\n" for param in missing_params: missing_info += f"- {param.key}: {param.description}\n" missing_info += f" Why needed: {param.why_needed}\n" return ( "You are an AI agent helping a user manage their local media library.\n\n" f"{params_desc}\n\n" "CURRENT CONTEXT (JSON):\n" f"{json.dumps(context, indent=2, ensure_ascii=False)}\n" f"{missing_info}\n" "IMPORTANT RULES:\n" "1. Check the REQUIRED PARAMETERS section above to understand what information you need.\n" "2. If any required parameter is missing (shown in MISSING REQUIRED PARAMETERS), " "you MUST ask the user for it and explain WHY you need it based on the parameter description.\n" "3. To use a tool, respond STRICTLY with this JSON format:\n" ' { "thought": "explanation", "action": { "name": "tool_name", "args": { "arg": "value" } } }\n' " - No text before or after the JSON\n" " - All args must be complete and non-null\n" "4. You can use MULTIPLE TOOLS IN SEQUENCE:\n" " - After executing a tool, you will receive its result\n" " - You can then decide to use another tool based on the result\n" " - Or provide a final text response to the user\n" " - Continue using tools until you have all the information needed\n" "5. If you respond with text (not using a tool), respond normally in French.\n" "6. When you have all the information needed, provide a final response in NATURAL TEXT (not JSON).\n" "7. Extract the relevant information from the user's request and pass it as tool arguments.\n" "\n" "EXAMPLES:\n" " To set the download folder:\n" ' { "thought": "User provided download path", "action": { "name": "set_path", "args": { "path_type": "download_folder", "path_value": "/home/user/downloads" } } }\n' "\n" " To set the TV show folder:\n" ' { "thought": "User provided TV show path", "action": { "name": "set_path", "args": { "path_type": "tvshow_folder", "path_value": "/home/user/media/tvshows" } } }\n' "\n" " To list the download folder:\n" ' { "thought": "User wants to see downloads", "action": { "name": "list_folder", "args": { "folder_type": "download", "path": "." } } }\n' "\n" " To list a subfolder in TV shows:\n" ' { "thought": "User wants to see a specific show", "action": { "name": "list_folder", "args": { "folder_type": "tvshow", "path": "Game.of.Thrones" } } }\n' "\n" "AVAILABLE TOOLS:\n" f"{tools_desc}\n" )