Add SEO fields to Tasks model, improve content generation response handling, and enhance progress bar animation
- Added primary_keyword, secondary_keywords, tags, and categories fields to Tasks model - Updated generate_content function to handle full JSON response with all SEO fields - Improved progress bar animation: smooth 1% increments every 300ms - Enhanced step detection for content generation vs clustering vs ideas - Fixed progress modal to show correct messages for each function type - Added comprehensive logging to Keywords and Tasks pages for AI functions - Fixed error handling to show meaningful error messages instead of generic failures
This commit is contained in:
@@ -1049,10 +1049,17 @@ Make sure each prompt is detailed enough for image generation, describing the vi
|
||||
account=None,
|
||||
response_steps=None,
|
||||
progress_callback=None,
|
||||
tracker=None, # Optional ConsoleStepTracker for logging
|
||||
**kwargs
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Cluster keywords using AI-based semantic similarity.
|
||||
[DEPRECATED] Cluster keywords using AI-based semantic similarity.
|
||||
|
||||
⚠️ WARNING: This method is deprecated. Use the new AI framework instead:
|
||||
- New path: views.py -> run_ai_task -> AIEngine -> AutoClusterFunction
|
||||
- This method uses the old prompt system and does not use PromptRegistry
|
||||
- Console logging may not work correctly in this path
|
||||
|
||||
Based on reference plugin's clustering prompt.
|
||||
|
||||
Args:
|
||||
@@ -1063,6 +1070,7 @@ Make sure each prompt is detailed enough for image generation, describing the vi
|
||||
Returns:
|
||||
Dict with 'clusters' (list of cluster dicts with name, description, keywords)
|
||||
"""
|
||||
logger.warning("AIProcessor.cluster_keywords is deprecated. Use the new AI framework (AutoClusterFunction) instead.")
|
||||
if not keywords:
|
||||
return {
|
||||
'clusters': [],
|
||||
@@ -1075,20 +1083,41 @@ Make sure each prompt is detailed enough for image generation, describing the vi
|
||||
for kw in keywords
|
||||
])
|
||||
|
||||
if tracker:
|
||||
tracker.prep(f"Formatted {len(keywords)} keywords for prompt")
|
||||
|
||||
account_obj = account or self.account
|
||||
|
||||
# Get prompt template from database or default
|
||||
# NOTE: This is legacy code. New code should use PromptRegistry.get_prompt()
|
||||
# Keeping this for backward compatibility with old tasks
|
||||
prompt_template = self.get_prompt('clustering', account=account_obj)
|
||||
|
||||
# Replace placeholders in prompt template
|
||||
if '[IGNY8_KEYWORDS]' not in prompt_template:
|
||||
error_msg = "Prompt template missing [IGNY8_KEYWORDS] placeholder"
|
||||
logger.error(error_msg)
|
||||
if tracker:
|
||||
tracker.error('Prompt', error_msg)
|
||||
return {
|
||||
'clusters': [],
|
||||
'error': error_msg,
|
||||
}
|
||||
|
||||
prompt = prompt_template.replace('[IGNY8_KEYWORDS]', keywords_text)
|
||||
|
||||
if tracker:
|
||||
tracker.prep(f"Prompt prepared: {len(prompt)} characters (keywords: {len(keywords_text)} chars)")
|
||||
|
||||
if sector_name:
|
||||
prompt += f"\n\nNote: These keywords are for the '{sector_name}' sector."
|
||||
|
||||
logger.info(f"Clustering {len(keywords)} keywords using AI")
|
||||
logger.info(f"AIProcessor.cluster_keywords: About to call OpenAI API with {len(keywords)} keywords")
|
||||
|
||||
if tracker:
|
||||
tracker.ai_call(f"Calling OpenAI API with model: {self.default_model}")
|
||||
|
||||
# Initialize response_steps if not provided
|
||||
if response_steps is None:
|
||||
response_steps = []
|
||||
@@ -1109,6 +1138,12 @@ Make sure each prompt is detailed enough for image generation, describing the vi
|
||||
response_format=response_format,
|
||||
response_steps=response_steps
|
||||
)
|
||||
|
||||
if tracker:
|
||||
if result.get('error'):
|
||||
tracker.error('AI_CALL', f"OpenAI API error: {result['error']}")
|
||||
else:
|
||||
tracker.ai_call(f"Received response: {result.get('total_tokens', 0)} tokens")
|
||||
logger.info(f"AIProcessor.cluster_keywords: OpenAI API call completed. Error: {result.get('error')}, Has content: {bool(result.get('content'))}")
|
||||
except Exception as e:
|
||||
logger.error(f"AIProcessor.cluster_keywords: Exception calling OpenAI API: {type(e).__name__}: {str(e)}", exc_info=True)
|
||||
@@ -1141,11 +1176,16 @@ Make sure each prompt is detailed enough for image generation, describing the vi
|
||||
}
|
||||
|
||||
# Step 11: JSON Extraction & Parsing
|
||||
if tracker:
|
||||
tracker.parse("Extracting JSON from AI response")
|
||||
step_start = time.time()
|
||||
json_data = self._extract_json_from_response(result['content'])
|
||||
|
||||
if not json_data:
|
||||
logger.error(f"Failed to parse clustering response: {result.get('content', '')[:200]}")
|
||||
error_msg = f"Failed to parse clustering response: {result.get('content', '')[:200]}"
|
||||
logger.error(error_msg)
|
||||
if tracker:
|
||||
tracker.error('Parse', error_msg)
|
||||
if response_steps is not None:
|
||||
response_steps.append({
|
||||
'stepNumber': 11,
|
||||
@@ -1194,7 +1234,10 @@ Make sure each prompt is detailed enough for image generation, describing the vi
|
||||
clusters = json_data
|
||||
|
||||
if not clusters:
|
||||
logger.error(f"No clusters found in response: {json_data}")
|
||||
error_msg = f"No clusters found in response: {json_data}"
|
||||
logger.error(error_msg)
|
||||
if tracker:
|
||||
tracker.error('Parse', error_msg)
|
||||
if response_steps is not None:
|
||||
response_steps.append({
|
||||
'stepNumber': 12,
|
||||
@@ -1216,6 +1259,10 @@ Make sure each prompt is detailed enough for image generation, describing the vi
|
||||
'response_steps': response_steps
|
||||
}
|
||||
|
||||
logger.info(f"Successfully parsed {len(clusters)} clusters from AI response")
|
||||
if tracker:
|
||||
tracker.parse(f"Successfully extracted {len(clusters)} clusters from response")
|
||||
|
||||
if response_steps is not None:
|
||||
response_steps.append({
|
||||
'stepNumber': 12,
|
||||
|
||||
Reference in New Issue
Block a user