gateway/modules/workflows/processing/shared/promptGenerationTaskplan.py
2026-01-22 17:00:29 +01:00

182 lines
8.1 KiB
Python

# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""
Task Planning Prompt Generation
Handles prompt templates and extraction functions for task planning phase.
"""
import logging
from typing import Dict, Any, List
from modules.features.aichat.datamodelFeatureAiChat import PromptBundle, PromptPlaceholder
from modules.workflows.processing.shared.placeholderFactory import (
extractUserPrompt,
extractAvailableDocumentsSummary,
extractWorkflowHistory,
extractUserIntent,
extractNormalizedRequest,
)
logger = logging.getLogger(__name__)
def generateTaskPlanningPrompt(services, context: Any) -> PromptBundle:
"""Define placeholders first, then the template; return PromptBundle."""
# Extract user language from services
# Prefer currentUserLanguage (set from user intention analysis), fallback to user.language, then 'en'
userLanguage = getattr(services, 'currentUserLanguage', None)
if not userLanguage:
userLanguage = getattr(services.user, 'language', None) if hasattr(services, 'user') and services.user else None
if not userLanguage:
userLanguage = 'en'
logger.debug(f"Task planning prompt using user language: {userLanguage}")
# Extract workflowIntent from workflow object if available
workflowIntent = {}
if hasattr(services, 'workflow') and services.workflow:
workflowIntent = getattr(services.workflow, '_workflowIntent', {}) or {}
# Format workflow intent fields for prompt context
workflowIntentText = ""
if workflowIntent:
workflowIntentText = f"""Workflow-level intent (can be overridden by task-specific needs):
- Data Type: {workflowIntent.get('dataType', 'unknown')}
- Expected Formats: {workflowIntent.get('expectedFormats', [])}
- Quality Requirements: {workflowIntent.get('qualityRequirements', {})}
Note: Tasks can override these if task-specific needs differ (e.g., workflow wants PDF, but task needs CSV for intermediate step).
"""
placeholders: List[PromptPlaceholder] = [
PromptPlaceholder(label="NORMALIZED_REQUEST", content=extractNormalizedRequest(services), summaryAllowed=False),
PromptPlaceholder(label="USER_INTENT", content=extractUserIntent(services), summaryAllowed=False),
PromptPlaceholder(label="AVAILABLE_DOCUMENTS_SUMMARY", content=extractAvailableDocumentsSummary(services, context), summaryAllowed=True),
PromptPlaceholder(label="WORKFLOW_HISTORY", content=extractWorkflowHistory(services), summaryAllowed=True),
PromptPlaceholder(label="USER_LANGUAGE", content=userLanguage, summaryAllowed=False),
PromptPlaceholder(label="WORKFLOW_INTENT", content=workflowIntentText, summaryAllowed=False),
]
template = """# Task Planning
Break down user requests into logical, executable task steps.
**IMPORTANT**: If the user asks for ONE complete business objective, create ONLY ONE task that accomplishes the entire objective. Do NOT split it into multiple micro-tasks.
## 📋 Context
### Normalized User Request
The following is the user's full normalized request (preserves all constraints and details):
```
{{KEY:NORMALIZED_REQUEST}}
```
### User Intent
The following is the user's intent (concise objective):
```
{{KEY:USER_INTENT}}
```
### Workflow Intent
{{KEY:WORKFLOW_INTENT}}
### Available Documents
{{KEY:AVAILABLE_DOCUMENTS_SUMMARY}}
### Previous Workflow Rounds
{{KEY:WORKFLOW_HISTORY}}
## 📝 Task Planning Rules
### Strategic Task Grouping
- **GROUP RELATED ACTIONS** - Combine all actions for the same business topic into ONE task
- **ONE TOPIC PER TASK** - Each task should handle one complete business objective
- **HIGH-LEVEL FOCUS** - Plan strategic outcomes, not implementation steps
- **AVOID MICRO-TASKS** - Don't create separate tasks for each small action
- **CRITICAL**: If the user asks for ONE thing (like "analyse document list and produce summary"), create ONLY ONE task that does the complete job
### Task Grouping Examples
- **Research + Analysis + Report** → ONE task: "Web research report"
- **Data Collection + Processing + Visualization** → ONE task: "Collect and present data"
- **Document splitting** (analyze + extract + create files) → ONE task: "Split document into separate files"
- **Different topics** (email + flowers) → SEPARATE tasks: "Send formal email..." + "Order flowers from Fleurop for delivery to 123 Main St, include card message"
### Common Single-Task Scenarios
- **"Split document into sections"** → ONE task: "Split document into separate files"
- **"Extract data and create report"** → ONE task: "Extract data and create report"
- **"Analyze and summarize document"** → ONE task: "Analyze and summarize document"
- **"Convert file to different format"** → ONE task: "Convert file to different format"
### Retry Handling
- **If retry request**: Analyze previous rounds to understand what failed
- **Learn from mistakes**: Improve the plan based on previous failures
## 📊 Required JSON Structure
```json
{{
"overview": "Brief description of the overall plan",
"userMessage": "User-friendly message explaining the task plan in language '{{KEY:USER_LANGUAGE}}'",
"tasks": [
{{
"id": "task_1",
"objective": "Clear business objective focusing on what to deliver",
"dependencies": ["task_0"],
"successCriteria": ["measurable criteria 1", "measurable criteria 2"],
"estimatedComplexity": "low|medium|high",
"userMessage": "What this task will accomplish in language '{{KEY:USER_LANGUAGE}}'",
"dataType": "numbers|text|documents|analysis|code|unknown",
"expectedFormats": ["pdf", "docx", "xlsx", "txt", "json", "csv", "html", "md"],
"qualityRequirements": {{
"accuracyThreshold": 0.0-1.0,
"completenessThreshold": 0.0-1.0
}}
}}
],
}}
```
**Task Intent Fields**:
- **dataType**: Inherit from workflow intent if not task-specific, or override if task needs different type
- **expectedFormats**: Inherit from workflow intent if not task-specific, or override if task needs different format (e.g., workflow wants PDF, task needs CSV)
- **qualityRequirements**: Inherit from workflow intent if not task-specific, or override if task has different quality needs
## 🎯 Task Structure Guidelines
### Task ID Format
- Use sequential numbering: `task_1`, `task_2`, `task_3`
- Keep IDs simple and clear
### Objective Writing
- **Be VERY SPECIFIC** - Include exact details needed for action planning
- **Include all requirements** - recipient, attachments, format, recipients, etc.
- **State the complete deliverable** - What exactly will be produced
- **Include context and constraints** - When, where, how, with what
- **Make it actionable** - Clear enough to plan specific actions
### Specific Objective Examples
- **Good**: "Send formal email to ceo and board of directors with annual report as attachment"
- **Bad**: "Handle email communication"
- **Good**: "Order flowers from Fleurop for delivery to 123 Main St, include card message 'Happy Birthday', deliver on March 15th"
- **Bad**: "Order flowers"
### Action Planning Requirements
- **Include all necessary details** - The objective must contain everything needed to plan actions
- **Specify recipients and destinations** - Who should receive what
- **Include file names and formats** - What documents to use/create
- **State timing and deadlines** - When things need to be done
- **Include context and constraints** - Any special requirements or limitations
### Success Criteria
- **Make them measurable** - specific, quantifiable outcomes
- **Focus on deliverables** - what the user will receive
- **Keep criteria realistic** - achievable within the task scope
- **Include all related actions** - success means completing the entire business objective
- **Be specific about requirements** - Include exact details like recipients, formats, deadlines
- **State clear completion criteria** - How to know the task is fully done
### Complexity Estimation
- **Low**: Simple, single-action tasks (1-2 actions)
- **Medium**: Multi-action tasks for one topic (3-5 actions)
- **High**: Complex strategic tasks (6+ actions)
"""
return PromptBundle(prompt=template, placeholders=placeholders)