aether-rides / creative_agent.py
lattmamb's picture
Upload 134 files (#2)
ad160e7 verified
"""
Creative Agent - Handles creative content generation
"""
import os
import sys
import json
import logging
import tempfile
from typing import Dict, List, Any, Optional, Union
from pathlib import Path
from llm.llm_manager import LLMManager
from memory.memory_manager import MemoryManager
logger = logging.getLogger("vision_os.creative_agent")
class CreativeAgent:
"""
Agent for handling creative content generation.
Provides capabilities for generating various types of creative content,
including text, ideas, and structured content.
"""
def __init__(self, llm_manager: LLMManager, memory_manager: MemoryManager):
"""
Initialize the creative agent
Args:
llm_manager: LLM manager instance
memory_manager: Memory manager instance
"""
self.llm_manager = llm_manager
self.memory_manager = memory_manager
# Content types
self.content_types = {
"story": "a creative narrative with characters and plot",
"poem": "a poetic composition with rhythm and imagery",
"essay": "a structured analytical composition on a specific topic",
"blog_post": "an informative article for online publication",
"social_media": "short, engaging content for social platforms",
"business_idea": "a concept for a new business venture",
"product_description": "compelling text describing a product's features and benefits",
"marketing_copy": "persuasive text designed to promote a product or service",
"email": "a professional or personal email communication",
"presentation": "content structured for a slide presentation",
"script": "dialogue and directions for a video or performance",
"technical_document": "detailed technical information or instructions"
}
logger.info("Creative Agent initialized")
def process(self, user_input: str, context: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""
Process a user request related to creative content generation
Args:
user_input: The user's natural language input
context: Optional context information
Returns:
Dictionary containing the response and any additional data
"""
# Analyze the user input to determine the requested action
content_type, parameters = self._determine_content_type(user_input)
# Generate the requested content
result = self.generate_content(content_type, parameters)
if result["success"]:
# For shorter content, include it directly in the response
if len(result["content"]) < 1000:
return {
"response": f"Here's the {content_type} you requested:\n\n{result['content']}",
"action": "generate_content",
"content_type": content_type,
"content": result["content"],
"success": True
}
else:
# For longer content, save to a file and provide a summary
file_path = self._save_content_to_file(content_type, result["content"])
return {
"response": f"I've generated the {content_type} you requested and saved it to {file_path}. Here's a preview:\n\n{result['content'][:500]}...",
"action": "generate_content",
"content_type": content_type,
"content": result["content"],
"file_path": file_path,
"success": True
}
else:
return {
"response": f"I couldn't generate the {content_type}. {result['error']}",
"action": "generate_content",
"content_type": content_type,
"success": False,
"error": result["error"]
}
def generate_content(self, content_type: str, parameters: Dict[str, Any]) -> Dict[str, Any]:
"""
Generate creative content
Args:
content_type: Type of content to generate
parameters: Parameters for content generation
Returns:
Dictionary with generated content or error message
"""
try:
# Check if content type is supported
if content_type not in self.content_types and content_type != "custom":
return {
"success": False,
"error": f"Content type '{content_type}' is not supported. Supported types: {', '.join(self.content_types.keys())}."
}
# Build the prompt based on content type and parameters
prompt = self._build_generation_prompt(content_type, parameters)
# Generate the content
content = self.llm_manager.generate(prompt, max_tokens=2000)
return {
"success": True,
"content": content
}
except Exception as e:
logger.error(f"Error generating {content_type}: {str(e)}")
return {
"success": False,
"error": str(e)
}
def _determine_content_type(self, user_input: str) -> tuple:
"""
Determine the type of content to generate and extract parameters
Args:
user_input: User's natural language input
Returns:
Tuple of (content_type, parameters)
"""
# Use LLM to extract content type and parameters
prompt = f"""
Analyze this request for creative content generation: "{user_input}"
Determine the type of content requested and extract relevant parameters.
Format your response as JSON with the following structure:
{{
"content_type": "one of {list(self.content_types.keys())} or 'custom'",
"parameters": {{
"topic": "main topic or subject",
"style": "requested style or tone",
"length": "requested length (short, medium, long)",
"additional_requirements": "any other specific requirements"
}}
}}
"""
response = self.llm_manager.generate(prompt)
try:
# Try to parse as JSON
content_info = json.loads(response)
content_type = content_info.get("content_type", "custom")
parameters = content_info.get("parameters", {})
# Ensure required parameters
if "topic" not in parameters:
parameters["topic"] = "general"
if "style" not in parameters:
parameters["style"] = "standard"
if "length" not in parameters:
parameters["length"] = "medium"
return content_type, parameters
except:
# Fallback if JSON parsing fails
logger.warning("Failed to parse content info as JSON. Using fallback extraction.")
# Simple content type detection
input_lower = user_input.lower()
# Check for explicit content type mentions
detected_type = "custom"
for content_type in self.content_types:
if content_type.replace("_", " ") in input_lower:
detected_type = content_type
break
# Extract basic parameters
parameters = {
"topic": "general",
"style": "standard",
"length": "medium",
"additional_requirements": user_input
}
return detected_type, parameters
def _build_generation_prompt(self, content_type: str, parameters: Dict[str, Any]) -> str:
"""
Build a prompt for content generation
Args:
content_type: Type of content to generate
parameters: Parameters for content generation
Returns:
Generation prompt
"""
# Extract parameters
topic = parameters.get("topic", "general")
style = parameters.get("style", "standard")
length = parameters.get("length", "medium")
additional_requirements = parameters.get("additional_requirements", "")
# Map length to approximate word count
length_map = {
"short": "approximately 200-300 words",
"medium": "approximately 500-700 words",
"long": "approximately 1000-1500 words"
}
length_description = length_map.get(length.lower(), "appropriate length")
# Build the prompt based on content type
if content_type == "story":
prompt = f"""
Write a creative story with the following parameters:
Topic/Theme: {topic}
Style/Tone: {style}
Length: {length_description}
Additional Requirements: {additional_requirements}
Create a compelling narrative with well-developed characters and an engaging plot.
"""
elif content_type == "poem":
prompt = f"""
Write a poem with the following parameters:
Topic/Theme: {topic}
Style/Tone: {style}
Length: {length_description}
Additional Requirements: {additional_requirements}
Create a poetic composition with rhythm, imagery, and emotional resonance.
"""
elif content_type == "essay":
prompt = f"""
Write an essay with the following parameters:
Topic: {topic}
Style/Tone: {style}
Length: {length_description}
Additional Requirements: {additional_requirements}
Create a well-structured analytical composition with a clear thesis, supporting arguments, and conclusion.
"""
elif content_type == "blog_post":
prompt = f"""
Write a blog post with the following parameters:
Topic: {topic}
Style/Tone: {style}
Length: {length_description}
Additional Requirements: {additional_requirements}
Create an informative and engaging article suitable for online publication, with a compelling headline, introduction, and well-organized sections.
"""
elif content_type == "social_media":
prompt = f"""
Write social media content with the following parameters:
Topic: {topic}
Style/Tone: {style}
Platform: {additional_requirements if additional_requirements else "general"}
Create short, engaging content optimized for social media, with appropriate hashtags and calls to action.
"""
elif content_type == "business_idea":
prompt = f"""
Generate a business idea with the following parameters:
Industry/Domain: {topic}
Innovation Style: {style}
Detail Level: {length_description}
Additional Requirements: {additional_requirements}
Create a comprehensive business concept including the value proposition, target market, revenue model, and potential challenges.
"""
elif content_type == "product_description":
prompt = f"""
Write a product description with the following parameters:
Product Type: {topic}
Style/Tone: {style}
Length: {length_description}
Additional Requirements: {additional_requirements}
Create compelling text describing the product's features, benefits, and unique selling points.
"""
elif content_type == "marketing_copy":
prompt = f"""
Write marketing copy with the following parameters:
Product/Service: {topic}
Style/Tone: {style}
Length: {length_description}
Additional Requirements: {additional_requirements}
Create persuasive text designed to promote the product or service, highlighting benefits and including effective calls to action.
"""
elif content_type == "email":
prompt = f"""
Write an email with the following parameters:
Subject/Purpose: {topic}
Style/Tone: {style}
Length: {length_description}
Additional Requirements: {additional_requirements}
Create a professional email communication with appropriate greeting, body, and closing.
"""
elif content_type == "presentation":
prompt = f"""
Create presentation content with the following parameters:
Topic: {topic}
Style/Tone: {style}
Number of Slides: {length.lower() if length.lower() in ["short", "medium", "long"] else "10-15"}
Additional Requirements: {additional_requirements}
Structure the content for a slide presentation, including an introduction, main points, and conclusion. Format as slide titles followed by bullet points or brief paragraphs.
"""
elif content_type == "script":
prompt = f"""
Write a script with the following parameters:
Topic/Scenario: {topic}
Style/Tone: {style}
Length: {length_description}
Additional Requirements: {additional_requirements}
Create dialogue and directions for a video or performance, with proper formatting for characters, dialogue, and action descriptions.
"""
elif content_type == "technical_document":
prompt = f"""
Write a technical document with the following parameters:
Subject: {topic}
Style/Tone: {style}
Length: {length_description}
Additional Requirements: {additional_requirements}
Create detailed technical information or instructions, with appropriate sections, terminology, and clarity for the intended audience.
"""
else: # custom or unsupported type
prompt = f"""
Generate creative content based on the following parameters:
Content Type: {content_type}
Topic: {topic}
Style/Tone: {style}
Length: {length_description}
Additional Requirements: {additional_requirements}
Create high-quality content that meets these specifications.
"""
return prompt
def _save_content_to_file(self, content_type: str, content: str) -> str:
"""
Save generated content to a file
Args:
content_type: Type of content
content: Generated content
Returns:
Path to the saved file
"""
try:
# Create a file name based on content type and timestamp
import time
timestamp = int(time.time())
file_name = f"{content_type}_{timestamp}.txt"
# Save to Documents folder
documents_dir = os.path.expanduser("~/Documents/VisionOS")
os.makedirs(documents_dir, exist_ok=True)
file_path = os.path.join(documents_dir, file_name)
# Write the content
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
# Store file info in memory
self.memory_manager.store_file_info(file_path)
return file_path
except Exception as e:
logger.error(f"Error saving content to file: {str(e)}")
# Fallback to temp file
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".txt")
temp_file.write(content.encode('utf-8'))
temp_file.close()
return temp_file.name