"feat:enhance-podcast-topic-ai"

This commit is contained in:
ajaysi
2026-03-11 19:09:27 +05:30
parent e472861967
commit 01881bb405
51 changed files with 3627 additions and 218 deletions

View File

@@ -56,26 +56,33 @@ async def enhance_podcast_idea(
logger.warning(f"[Podcast Enhance] Failed to parse or generate bible context: {exc}")
prompt = f"""
You are a creative podcast producer. Your goal is to take a simple podcast idea or keywords
and transform it into a compelling, professional, and detailed episode concept.
You are a creative podcast producer. Generate 3 distinct, compelling podcast episode concepts from the raw idea.
{f"USER PERSONALIZATION CONTEXT (Podcast Bible):\n{bible_context}\n" if bible_context else ""}
RAW IDEA/KEYWORDS: "{request.idea}"
TASK:
1. Rewrite the idea into a professional, presentable 2-3 sentence episode pitch.
2. Focus on making it sound expert-led and audience-focused.
3. Ensure it aligns with the host's persona and target audience interests if context was provided.
4. Keep it concise but information-rich.
Generate 3 different enhanced versions, each with a unique angle:
1. Professional & Expert-led angle (focus on authority, insights, and expertise)
2. Storytelling & Human interest angle (focus on narratives, emotions, and personal connections)
3. Trendy & Contemporary angle (focus on current trends, modern perspectives, and relevance)
Each version should be 2-3 sentences, audience-focused, and align with host persona if provided.
Return JSON with:
- enhanced_idea: the rewritten, professional episode pitch
- rationale: 1 sentence explaining why this version works better for the target audience
- enhanced_ideas: array of 3 enhanced episode pitches (in order: Professional, Storytelling, Trendy)
- rationales: array of 3 rationales explaining the approach for each version
"""
try:
raw = llm_text_gen(prompt=prompt, user_id=user_id, json_struct=None)
raw = llm_text_gen(
prompt=prompt,
user_id=user_id,
json_struct=None,
preferred_provider="huggingface",
flow_type="premium_tool",
)
# Normalize response
if isinstance(raw, str):
@@ -83,15 +90,52 @@ Return JSON with:
else:
data = raw
# Extract enhanced ideas and rationales with fallbacks
enhanced_ideas = data.get("enhanced_ideas", [])
rationales = data.get("rationales", [])
# Ensure we have exactly 3 ideas, fallback to original if needed
if not isinstance(enhanced_ideas, list) or len(enhanced_ideas) != 3:
# Fallback: create 3 variations of the original idea
base_idea = request.idea
enhanced_ideas = [
f"Expert insights on {base_idea}: A deep dive into industry trends and best practices.",
f"The human side of {base_idea}: Personal stories and real-world experiences that resonate.",
f"Modern perspectives on {base_idea}: Current trends and forward-thinking approaches."
]
rationales = [
"Professional approach focusing on expertise and authority",
"Storytelling approach emphasizing human connection",
"Contemporary approach highlighting current relevance"
]
# Ensure rationales match the number of ideas
if not isinstance(rationales, list) or len(rationales) != 3:
rationales = [
"Professional angle with expert insights",
"Storytelling angle with human interest",
"Trendy angle with contemporary relevance"
]
return PodcastEnhanceIdeaResponse(
enhanced_idea=data.get("enhanced_idea", request.idea),
rationale=data.get("rationale", "Made it more professional and listener-focused.")
enhanced_ideas=enhanced_ideas[:3], # Ensure exactly 3
rationales=rationales[:3] # Ensure exactly 3
)
except Exception as exc:
logger.error(f"[Podcast Enhance] Failed for user {user_id}: {exc}")
# Fallback to basic variations of original idea
base_idea = request.idea
return PodcastEnhanceIdeaResponse(
enhanced_idea=request.idea,
rationale="Failed to enhance idea with AI, using original."
enhanced_ideas=[
f"Expert insights on {base_idea}: A deep dive into industry trends and best practices.",
f"The human side of {base_idea}: Personal stories and real-world experiences that resonate.",
f"Modern perspectives on {base_idea}: Current trends and forward-thinking approaches."
],
rationales=[
"Professional approach focusing on expertise and authority",
"Storytelling approach emphasizing human connection",
"Contemporary approach highlighting current relevance"
]
)
@@ -242,7 +286,13 @@ Requirements:
"""
try:
raw = llm_text_gen(prompt=prompt, user_id=user_id, json_struct=None)
raw = llm_text_gen(
prompt=prompt,
user_id=user_id,
json_struct=None,
preferred_provider="huggingface",
flow_type="premium_tool",
)
except HTTPException:
# Re-raise HTTPExceptions (e.g., 429 subscription limit) - preserve error details
raise

View File

@@ -144,7 +144,13 @@ Requirements:
- Avoid generic filler.
"""
try:
llm_response = llm_text_gen(prompt=prompt, user_id=user_id, json_struct=None)
llm_response = llm_text_gen(
prompt=prompt,
user_id=user_id,
json_struct=None,
preferred_provider="huggingface",
flow_type="premium_tool",
)
# Normalize response
if isinstance(llm_response, str):

View File

@@ -126,7 +126,13 @@ Guidelines:
"""
try:
raw = llm_text_gen(prompt=prompt, user_id=user_id, json_struct=None)
raw = llm_text_gen(
prompt=prompt,
user_id=user_id,
json_struct=None,
preferred_provider="huggingface",
flow_type="premium_tool",
)
except Exception as exc:
raise HTTPException(status_code=500, detail=f"Script generation failed: {exc}")

View File

@@ -230,14 +230,33 @@ def _execute_podcast_video_task(
f"[Podcast] Video generation completed for project {request.project_id}, scene {request.scene_id}"
)
except Exception as exc:
# Use logger.exception to avoid KeyError when exception message contains curly braces
logger.exception(f"[Podcast] Video generation failed for project {request.project_id}, scene {request.scene_id}")
# Extract user-friendly error message from exception
except HTTPException as exc:
error_msg = _extract_error_message(exc)
error_meta = extract_error_metadata(exc)
logger.warning(
"[Podcast] Video generation failed (HTTP %s) for project %s, scene %s: %s",
exc.status_code,
request.project_id,
request.scene_id,
error_msg,
)
task_manager.update_task_status(
task_id,
"failed",
error=error_msg,
message=f"Video generation failed: {error_msg}",
error_status=error_meta.get("error_status"),
error_data=error_meta.get("error_data"),
)
except Exception as exc:
logger.exception(
f"[Podcast] Video generation failed for project {request.project_id}, scene {request.scene_id}"
)
error_msg = _extract_error_message(exc)
error_meta = extract_error_metadata(exc)
task_manager.update_task_status(
task_id,
"failed",

View File

@@ -77,8 +77,8 @@ class PodcastEnhanceIdeaRequest(BaseModel):
class PodcastEnhanceIdeaResponse(BaseModel):
"""Response model for enhanced podcast idea."""
enhanced_idea: str
rationale: str
enhanced_ideas: List[str] = Field(..., description="3 AI-enhanced topic choices")
rationales: List[str] = Field(..., description="Rationale for each enhanced idea")
class PodcastScriptRequest(BaseModel):