# promptFactory.py # Contains all prompt creation functions extracted from managerChat.py import json import logging from typing import Any, Dict from modules.interfaces.interfaceChatModel import TaskContext, ReviewContext # Set up logger logger = logging.getLogger(__name__) # Prompt creation helpers extracted from managerChat.py def createTaskPlanningPrompt(context: TaskContext, service) -> str: """Create enhanced prompt for task planning with user-friendly message generation""" # Get user language directly from service.user.language user_language = service.user.language if service and service.user else 'en' # Extract user request from context - use Pydantic model directly user_request = context.task_step.objective if context.task_step else 'No request specified' # Extract available documents from context - use Pydantic model directly available_documents = context.available_documents or [] return f"""You are a task planning AI that analyzes user requests and creates structured task plans with user-friendly feedback messages. USER REQUEST: {user_request} AVAILABLE DOCUMENTS: {', '.join(available_documents)} INSTRUCTIONS: 1. Analyze the user request and available documents 2. Break down the request into 2-4 meaningful high-level task steps 3. Focus on business outcomes, not technical operations 4. Each task should produce meaningful, usable outputs 5. Ensure proper handover between tasks using result labels 6. Generate user-friendly messages for each task in the user's language ({user_language}) 7. Return a JSON object with the exact structure shown below TASK PLANNING PRINCIPLES: - Break down complex requests into logical, sequential steps - Focus on business value and outcomes - Keep tasks at a meaningful level of abstraction - Each task should produce results that can be used by subsequent tasks - Ensure clear dependencies and handovers between tasks - Provide clear, actionable user messages in the user's language ({user_language}) REQUIRED JSON STRUCTURE: {{ "overview": "Brief description of the overall plan", "userMessage": "User-friendly message explaining the task plan in {user_language}", "tasks": [ {{ "id": "task_1", "objective": "Clear business objective this task accomplishes", "dependencies": ["task_0"], // IDs of tasks that must complete first "success_criteria": ["criteria1", "criteria2"], "estimated_complexity": "low|medium|high", "userMessage": "User-friendly message explaining what this task will accomplish in {user_language}" }} ] }} EXAMPLES OF GOOD TASK OBJECTIVES: - "Analyze documents and extract key insights for business communication" - "Create professional business communication incorporating analyzed information" - "Execute business communication using specified channels" - "Document and store all business communication outcomes" EXAMPLES OF GOOD SUCCESS CRITERIA: - "Key insights extracted and ready for business use" - "Professional communication created with clear business value" - "Business communication successfully delivered" - "All outcomes properly documented and accessible" EXAMPLES OF BAD TASK OBJECTIVES: - "Read the PDF file" (too granular - should be "Analyze document content") - "Convert data to CSV" (implementation detail - should be "Structure data for analysis") - "Send email" (too specific - should be "Deliver business communication") NOTE: Respond with ONLY the JSON object. Do not include any explanatory text.""" async def createActionDefinitionPrompt(context: TaskContext, service) -> str: """Create enhanced prompt for action generation with user-friendly messages and enhanced document context""" methodList = service.getMethodsList() method_actions = {} for sig in methodList: if '.' in sig: method, rest = sig.split('.', 1) action = rest.split('(')[0] method_actions.setdefault(method, []).append((action, sig)) messageSummary = await service.summarizeChat(context.workflow.messages) if context.workflow else "" # Get enhanced document context using the new method available_documents_str = service.getEnhancedDocumentContext() connRefs = service.getConnectionReferenceList() # Debug logging for connections logging.debug(f"Connection references retrieved: {connRefs}") logging.debug(f"Connection references type: {type(connRefs)}") logging.debug(f"Connection references length: {len(connRefs) if connRefs else 0}") # Log document availability for debugging logging.debug(f"Enhanced document context length: {len(available_documents_str)}") available_methods_str = '' for method, actions in method_actions.items(): available_methods_str += f"- {method}:\n" for action, sig in actions: available_methods_str += f" - {action}: {sig}\n" retry_context = "" if context.retry_count and context.retry_count > 0: retry_context = f""" RETRY CONTEXT (Attempt {context.retry_count}): Previous action results that failed or were incomplete: """ for i, result in enumerate(context.previous_action_results or []): retry_context += f"- Action {i+1}: ActionResult\n" retry_context += f" Status: {result.success and 'success' or 'failed'}\n" retry_context += f" Error: {result.error or 'None'}\n" # Check if result has documents and show document info if result.documents: doc_info = f"Documents: {len(result.documents)} document(s)" if result.documents[0].documentName: doc_info += f" - {result.documents[0].documentName}" retry_context += f" {doc_info}\n" else: retry_context += f" Documents: None\n" if context.previous_review_result: retry_context += f""" Previous review feedback: - Status: {context.previous_review_result.get('status', 'unknown') or 'unknown'} - Reason: {context.previous_review_result.get('reason', 'No reason provided') or 'No reason provided'} - Quality Score: {context.previous_review_result.get('quality_score', 0) or 0}/10 - Unmet Criteria: {', '.join(context.previous_review_result.get('unmet_criteria', []) or [])} """ # Use Pydantic model directly - no need for getattr success_criteria_str = ', '.join(context.task_step.success_criteria) if context.task_step and context.task_step.success_criteria else 'No criteria specified' previous_results_str = ', '.join(context.previous_results) if context.previous_results else 'None' improvements_str = str(context.improvements) if context.improvements else 'None' available_connections_str = '\n'.join(f"- {conn}" for conn in connRefs) # Get user language from service - this is the correct way user_language = service.user.language if service and service.user else 'en' prompt = f""" You are an action generation AI that creates specific actions to accomplish a task step with user-friendly messages. DOCUMENT REFERENCE TYPES: - docItem: Reference to a single document. Format: "docItem::