feat(feedback): Add content improvement feedback system
Frontend (frontend/app.js): - Add textarea for improvement feedback - Add submit button with loading state - Handle API response and display improved content Backend (backend/copywriter.py): - Add improve_copy() method using Cohere API - Integrate retry mechanism for API calls Backend (backend/main.py): - Add /improve-content POST endpoint - Implement error handling and return improved content with metadata Testing: - Verified feedback submission flow - Confirmed improved content generation - Tested error scenarios and loading states
This commit is contained in:
+137
-47
@@ -18,6 +18,104 @@ class BrandStyleManager:
|
||||
"""Initialize the BrandStyleManager with default or stored style guidelines."""
|
||||
self.style_path = Path(config.DATA_DIR) / "style_guidelines" / "brand_style.json"
|
||||
self.style_guidelines = self._load_or_create_style()
|
||||
self.content_formats = {
|
||||
"website_copy": """
|
||||
Generate engaging website copy for a brand or business.
|
||||
- Start with a strong headline and supporting subheadline
|
||||
- Write in a clear, benefit-driven tone
|
||||
- Use SEO-friendly keywords naturally
|
||||
- Structure content with short paragraphs and bullet points
|
||||
- Include a clear call-to-action at the end
|
||||
""",
|
||||
"email": """
|
||||
Create a marketing or sales email for a target audience.
|
||||
- Start with a compelling subject line
|
||||
- Use a warm, conversational tone
|
||||
- Keep the message focused and value-driven
|
||||
- Personalize where possible (name, context)
|
||||
- End with a clear and persuasive CTA
|
||||
""",
|
||||
"social_media": """
|
||||
Write social media content tailored to a specific platform.
|
||||
- Hook the reader within the first sentence
|
||||
- Keep the message concise and engaging
|
||||
- Use platform-appropriate tone and emojis (if applicable)
|
||||
- Add relevant hashtags and tag accounts when needed
|
||||
- Include a prompt or CTA to drive interaction
|
||||
""",
|
||||
"blog_post": """
|
||||
Generate a blog article on a given topic or keyword.
|
||||
- Begin with a strong hook or introduction
|
||||
- Organize content with subheadings and logical flow
|
||||
- Use examples, data, and storytelling
|
||||
- Optimize for SEO with keywords and meta description
|
||||
- Conclude with a summary or actionable insight
|
||||
""",
|
||||
"sales_copy": """
|
||||
Write persuasive sales copy for a product or service.
|
||||
- Lead with a strong value proposition
|
||||
- Address specific pain points and offer solutions
|
||||
- Highlight features, benefits, and outcomes
|
||||
- Include social proof (testimonials, stats, etc.)
|
||||
- End with a direct and compelling CTA
|
||||
""",
|
||||
"ad_copy": """
|
||||
Create short, punchy ad copy for digital or print campaigns.
|
||||
- Capture attention in the first line
|
||||
- Use emotional or benefit-driven language
|
||||
- Keep it brief and persuasive
|
||||
- Align copy with the target audience
|
||||
- Include a CTA or promotional message
|
||||
""",
|
||||
"video_script": """
|
||||
Generate a short video script for a marketing video.
|
||||
- Hook the viewer in the first few seconds
|
||||
- Introduce the problem and present the solution
|
||||
- Keep the tone conversational and natural
|
||||
- Include visual cues and on-screen text ideas
|
||||
- Wrap up with a strong CTA
|
||||
""",
|
||||
"case_study": """
|
||||
Write a case study that highlights a customer success story.
|
||||
- Start with a quick summary of the results
|
||||
- Describe the client and their initial problem
|
||||
- Explain how the product/service helped
|
||||
- Include measurable outcomes or metrics
|
||||
- End with a quote and a CTA to learn more
|
||||
""",
|
||||
"product_description": """
|
||||
Generate a product description that drives interest and conversions.
|
||||
- Begin with the most attractive benefit
|
||||
- Mention key features and what makes the product unique
|
||||
- Use sensory and persuasive language
|
||||
- Include important specs or FAQs
|
||||
- End with a micro-CTA (e.g., "Shop now", "View details")
|
||||
""",
|
||||
"landing_page": """
|
||||
Write copy for a focused landing page.
|
||||
- Use a bold, attention-grabbing headline
|
||||
- Describe the offer clearly and simply
|
||||
- Include supporting details that reinforce value
|
||||
- Remove distractions and focus on a single goal
|
||||
- Add a CTA above the fold and at the end
|
||||
""",
|
||||
"press_release": """
|
||||
Create a professional press release for an announcement.
|
||||
- Begin with a headline that summarizes the news
|
||||
- Use a journalistic tone and structure
|
||||
- Provide key facts in the first paragraph
|
||||
- Add quotes from relevant leaders or stakeholders
|
||||
- End with boilerplate company info and contact details
|
||||
""",
|
||||
"newsletter": """
|
||||
Write a newsletter update for subscribers.
|
||||
- Start with a warm greeting or short intro
|
||||
- Highlight the most important news or offer first
|
||||
- Use engaging sub-sections or article teasers
|
||||
- Maintain consistent tone with the brand
|
||||
- Include CTAs to drive clicks or traffic
|
||||
"""
|
||||
}
|
||||
logger.info("BrandStyleManager initialized successfully")
|
||||
|
||||
def _load_or_create_style(self) -> Dict[str, Any]:
|
||||
@@ -84,55 +182,29 @@ class BrandStyleManager:
|
||||
raise
|
||||
|
||||
def format_prompt_with_brand_style(self, user_prompt: str, content_type: Optional[str] = None) -> str:
|
||||
"""
|
||||
Format user prompt with brand style guidelines for the LLM.
|
||||
"""Format user prompt to match the established writing style."""
|
||||
|
||||
Args:
|
||||
user_prompt: Original user prompt
|
||||
content_type: Type of content being generated
|
||||
|
||||
Returns:
|
||||
Formatted prompt with brand style instructions
|
||||
"""
|
||||
style = self.style_guidelines
|
||||
|
||||
# Create a formatted prompt with brand style instructions
|
||||
prompt_parts = [
|
||||
f"Generate marketing content for {style['brand_name']} based on the following request:",
|
||||
f"\"{user_prompt}\"",
|
||||
"\nFollow these brand style guidelines:",
|
||||
f"- Brand Name: {style['brand_name']}",
|
||||
f"- Tone: {', '.join(style.get('tone', []))}",
|
||||
f"- Voice Characteristics: {', '.join(style.get('voice_characteristics', []))}",
|
||||
style_instructions = [
|
||||
"Follow these writing style guidelines:",
|
||||
"- Use direct commands that empower the reader",
|
||||
"- Address the reader directly using 'you' and 'your'",
|
||||
"- Create rhythmic, repetitive patterns in key messages",
|
||||
"- Maintain a clear, confident, and authoritative tone",
|
||||
"- Use simple, practical language without jargon",
|
||||
"- Acknowledge challenges while focusing on solutions",
|
||||
"- Include empowering phrases that emphasize reader's control and choice"
|
||||
]
|
||||
|
||||
# Content type specific formatting
|
||||
content_format = self._get_content_format(content_type) if content_type else ""
|
||||
|
||||
# Add taboo words if any
|
||||
if 'taboo_words' in style and style['taboo_words']:
|
||||
prompt_parts.append(f"- Avoid these words: {', '.join(style['taboo_words'])}")
|
||||
|
||||
# Add preferred terms if any
|
||||
if 'preferred_terms' in style and style['preferred_terms']:
|
||||
terms = [f"use '{value}' instead of '{key}'" for key, value in style['preferred_terms'].items()]
|
||||
prompt_parts.append(f"- Preferred terminology: {'; '.join(terms)}")
|
||||
|
||||
# Add content type specific instructions
|
||||
if content_type:
|
||||
if content_type == "email_campaign":
|
||||
prompt_parts.append("- Format as a professional email with subject line, greeting, body, and signature")
|
||||
elif content_type == "social_media":
|
||||
prompt_parts.append("- Format as a concise social media post with appropriate hashtags")
|
||||
elif content_type == "blog_post":
|
||||
prompt_parts.append("- Format as a blog post with title, introduction, body with subheadings, and conclusion")
|
||||
elif content_type == "website_copy":
|
||||
prompt_parts.append("- Format as website copy with clear headings and concise paragraphs")
|
||||
elif content_type == "ad_copy":
|
||||
prompt_parts.append("- Format as advertising copy with headline, body, and clear call to action")
|
||||
|
||||
# Combine all parts
|
||||
formatted_prompt = "\n".join(prompt_parts)
|
||||
|
||||
logger.debug("Created formatted prompt with brand style")
|
||||
return formatted_prompt
|
||||
return "\n".join([
|
||||
f"Generate content based on this request:",
|
||||
f"\"{user_prompt}\"",
|
||||
"",
|
||||
"\n".join(style_instructions),
|
||||
content_format
|
||||
])
|
||||
|
||||
def check_content_alignment(self, content: str) -> Dict[str, Any]:
|
||||
"""
|
||||
@@ -171,5 +243,23 @@ class BrandStyleManager:
|
||||
'aligned': alignment_score >= 80 # Consider aligned if score is 80% or higher
|
||||
}
|
||||
|
||||
def _get_content_format(self, content_type: str) -> str:
|
||||
"""
|
||||
Get formatting instructions for specific content type.
|
||||
|
||||
Args:
|
||||
content_type: Type of content to generate
|
||||
|
||||
Returns:
|
||||
Formatting instructions as string
|
||||
"""
|
||||
if not content_type:
|
||||
return ""
|
||||
|
||||
format_instructions = self.content_formats.get(content_type, "")
|
||||
if format_instructions:
|
||||
return f"\nContent type specific instructions:\n{format_instructions.strip()}"
|
||||
return ""
|
||||
|
||||
# Create a singleton instance
|
||||
brand_style_manager = BrandStyleManager()
|
||||
brand_style_manager = BrandStyleManager()
|
||||
|
||||
Reference in New Issue
Block a user