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:
Michael Ikehi
2025-04-18 04:39:06 +01:00
parent 6fd7213076
commit af8f99dea3
13 changed files with 550 additions and 167 deletions
+47 -44
View File
@@ -28,7 +28,6 @@ class Copywriter:
self,
prompt: str,
content_type: Optional[str] = None,
tone: Optional[str] = None,
length: Optional[str] = None,
include_cta: bool = False,
reference_similar_content: bool = True,
@@ -36,18 +35,7 @@ class Copywriter:
) -> Dict[str, Any]:
"""
Generate marketing copy based on the user prompt and parameters.
Args:
prompt: User prompt for content generation
content_type: Type of content to generate
tone: Desired tone of the content
length: Desired length of the content
include_cta: Whether to include a call to action
reference_similar_content: Whether to fetch and reference similar content
max_tokens: Maximum tokens for the generated response
Returns:
Dictionary with generated content and metadata
Note: Removed tone parameter as we always use the established style
"""
try:
# Step 1: Format prompt with brand style guidelines
@@ -60,35 +48,19 @@ class Copywriter:
if search_results:
reference_content = [result['text'] for result in search_results]
# Step 3: Add additional instructions based on parameters
full_prompt = branded_prompt
if tone:
full_prompt += f"\n- Use a {tone} tone"
# Step 3: Add length and CTA instructions if needed
if length:
length_instructions = {
"short": "Keep the content brief and to the point (under 100 words).",
"medium": "Write a moderate amount of content (100-300 words).",
"long": "Create comprehensive content with depth (over 300 words)."
}
full_prompt += f"\n- {length_instructions.get(length, '')}"
branded_prompt += f"\n- Generate {length} content"
if include_cta:
full_prompt += "\n- Include a strong call to action at the end"
branded_prompt += "\n- Include a direct, empowering call to action"
# Step 4: Add reference content if available
if reference_content:
full_prompt += "\n\nFor reference, here are some similar pieces of content that have performed well in the past:"
for i, content in enumerate(reference_content, 1):
# Truncate reference content if it's too long
preview = content[:300] + "..." if len(content) > 300 else content
full_prompt += f"\n\nReference {i}:\n{preview}"
full_prompt += "\n\nUse these references for inspiration, but create original content."
branded_prompt += "\n\nReference these successful examples for tone and style:\n"
branded_prompt += "\n---\n".join(reference_content)
# Step 5: Generate content using the LLM
generated_content = await self._call_llm_api(full_prompt, max_tokens)
generated_content = await self._call_llm_api(branded_prompt, max_tokens)
# Step 6: Check content alignment with brand style
alignment_check = brand_style_manager.check_content_alignment(generated_content)
@@ -102,7 +74,7 @@ class Copywriter:
"suggestions": headline_suggestions,
"metadata": {
"content_type": content_type,
"tone": tone,
"tone": None, # Removed tone parameter
"alignment_score": alignment_check['alignment_score'],
"generated_at": None # Will be added by the API
}
@@ -174,20 +146,51 @@ class Copywriter:
Args:
original_prompt: The original user prompt
generated_content: The generated marketing content
Returns:
List of headline suggestions
"""
try:
# This would call the LLM to generate headlines
# Simplified mock response for demonstration
return [
"Alternative Headline 1: Discover the Power of Adriana James' Solutions",
"Alternative Headline 2: Transform Your Results with Adriana James",
"Alternative Headline 3: The Adriana James Approach: Excellence Redefined"
# Create a prompt for headline generation
headline_prompt = f"""
Generate 3 alternative marketing headlines for the following content.
Make headlines compelling, concise, and aligned with the content's message.
Each headline should be unique and capture attention.
ORIGINAL PROMPT:
{original_prompt}
CONTENT:
{generated_content}
Generate exactly 3 headlines, one per line, without numbering or prefixes.
"""
# Call LLM to generate headlines
response = await self._call_llm_api(
prompt=headline_prompt,
max_tokens=100 # Shorter limit for headlines
)
# Process the response into a list of headlines
headlines = [
headline.strip()
for headline in response.split('\n')
if headline.strip() and not headline.lower().startswith(('headline', 'title', '-', '*', ''))
]
# Ensure we have exactly 3 headlines
if len(headlines) > 3:
headlines = headlines[:3]
while len(headlines) < 3:
headlines.append(f"Headline Option {len(headlines) + 1}")
logger.info(f"Generated {len(headlines)} headline suggestions")
return headlines
except Exception as e:
logger.error(f"Error generating headline suggestions: {str(e)}")
# Return empty list instead of mock response on error
return []
async def improve_copy(self, content: str, feedback: str) -> str:
@@ -275,4 +278,4 @@ class Copywriter:
raise
# Create a singleton instance
copywriter = Copywriter()
copywriter = Copywriter()