| import asyncio |
| import uuid |
| from datetime import datetime |
|
|
|
|
| |
| |
| |
|
|
| DEFAULT_PERSONA = { |
| "age_range": "18-34", |
| "interests": ["content creation", "social media growth"], |
| "behavior": "scroll-heavy short-form consumption" |
| } |
|
|
|
|
| |
| |
| |
|
|
| def normalize_context(context): |
|
|
| if isinstance(context, dict): |
| return { |
| "words": context.get("words") or context.get("transcript") or [], |
| "video_path": context.get("video_path"), |
| } |
|
|
| return { |
| "words": getattr(context, "words", None) or getattr(context, "transcript", None) or [], |
| "video_path": getattr(context, "video_path", None) |
| } |
|
|
|
|
| |
| |
| |
| |
|
|
| def compute_hook(words): |
| if not words: |
| return "Create content that hooks attention in the first 3 seconds." |
|
|
| |
| text = " ".join(words if isinstance(words, list) else []) |
| return text.split(".")[0][:120] |
|
|
|
|
| def compute_viral_score(words): |
| if not words: |
| return 50 |
|
|
| length = len(words) |
|
|
| |
| score = min(95, 40 + (length / 50)) |
|
|
| return round(score, 2) |
|
|
|
|
| def detect_platform_fit(score): |
| if score >= 80: |
| return ["tiktok", "reels", "youtube-shorts"] |
| if score >= 60: |
| return ["tiktok", "reels"] |
| return ["reels"] |
|
|
|
|
| |
| |
| |
|
|
| def simulate_retention_curve(words): |
|
|
| if not words: |
| return [1.0, 0.7, 0.5, 0.3] |
|
|
| n = len(words) |
|
|
| return [ |
| 1.0, |
| max(0.7, 1 - (n * 0.001)), |
| max(0.4, 1 - (n * 0.002)), |
| max(0.2, 1 - (n * 0.003)), |
| ] |
|
|
|
|
| |
| |
| |
|
|
| async def run(context): |
|
|
| ctx = normalize_context(context) |
|
|
| batch_id = str(uuid.uuid4()) |
| started_at = datetime.utcnow().isoformat() |
|
|
| try: |
|
|
| words = ctx.get("words") or [] |
|
|
| |
| |
| |
|
|
| hook = compute_hook(words) |
| viral_score = compute_viral_score(words) |
| platforms = detect_platform_fit(viral_score) |
| retention_curve = simulate_retention_curve(words) |
|
|
| |
| |
| |
|
|
| result = { |
| "status": "success", |
| "task": "strategy", |
| "batch_id": batch_id, |
| "started_at": started_at, |
| "completed_at": datetime.utcnow().isoformat(), |
|
|
| |
| "hook": hook, |
| "viral_score": viral_score, |
| "platforms": platforms, |
|
|
| |
| "persona": DEFAULT_PERSONA, |
|
|
| "retention_curve": retention_curve, |
|
|
| "strategy": { |
| "recommended_length_sec": min(60, max(15, len(words) // 3)), |
| "hook_strength": "high" if viral_score > 75 else "medium", |
| "distribution_priority": platforms |
| } |
| } |
|
|
| return result |
|
|
| except Exception as e: |
|
|
| return { |
| "status": "error", |
| "task": "strategy", |
| "batch_id": batch_id, |
| "message": str(e), |
| "stage": "strategy_failed" |
| } |