from typing import List, Optional def build_quick_prompt(idea: str, tone: str, words: int, include_emoji: bool, add_hashtags: bool, language: str) -> str: return ( "You are a senior LinkedIn content strategist.\n" "Write a concise LinkedIn post as 4–6 short lines per paragraph (one idea per short paragraph). No long paragraphs.\n" "Return plain text only (no labels) and use Markdown bolding for the opening line.\n\n" "Use short paragraphs of 2–3 lines, then insert a blank line after each paragraph." f"Language: {language}\n" f"Idea: {idea}\n" f"Tone: {tone}\n" f"Target length: ~{max(90, min(220, words))} words\n" "- The post should sound personal yet professional, using first-person voice (I/we) with excitement and gratitude.\n" "- Include one short line showing appreciation for mentors, peers, or a support network.\n" "- Mention a clear milestone, achievement, or announcement (e.g., qualified for finale, launched project, hit metric).\n" "- Optionally include one forward-looking statement showing enthusiasm for the next step.\n" "- Insert a blank line after every 3–4 lines to improve readability.\n" "Hard rules (apply silently):\n" "- Line 1 must be a bold, specific hook (no generic questions).\n" "- Include exactly one concrete detail (metric/date/example).\n" f"- Emojis: {'max 5' if include_emoji else 'none'}.\n" f"- Hashtags: {'append 1–2 niche hashtags at the very end' if add_hashtags else 'none'}.\n" "- Use short sentences and white space for scannability.\n" "- Use Punctuation Marks where needed.\n" "- End with a question‑led CTA.\n" "- No repeated sentences. No clichés. No filler.\n" "- Return only the post text." ) def build_post_prompt(topic: str, language: str, tone: str, target_len: int, purpose: str, audience: str, evidence: str, keywords: List[str], style_cues: List[str], clarifier_notes: str, chosen_hook: Optional[str]) -> str: kw_block = ", ".join(keywords[:8]) if keywords else "N/A" cues_block = "\n".join(f"- {c}" for c in style_cues[:4]) if style_cues else "- None" hook_line = chosen_hook.strip() if chosen_hook else "" return ( "You are a senior LinkedIn content strategist. " "Write one viral, insightful LinkedIn post as plain text only (no section headers, no labels).\n\n" f"Language: {language}\n" f"Topic: \"{topic}\"\n" f"Purpose: {purpose or 'awareness'}\n" f"Audience: {audience or 'general professionals'}\n" f"Tone: {tone}\n" f"Approx length: ~{target_len} words\n" f"Keywords to weave in naturally: {kw_block}\n" "Style cues (apply silently):\n" f"{cues_block}\n\n" "User-provided detail (incorporate if relevant):\n" f"{evidence or 'None'}\n\n" "Additional notes from clarifier (apply silently):\n" f"{(clarifier_notes or 'None').strip()}\n\n" f"Preferred opening line (if provided): {hook_line or 'None'}\n\n" "Rules (apply silently):\n" "- Curiosity-driven first sentence; short paragraphs; 3–5 concrete insights.\n" "- Max 2 emojis; 2–4 niche hashtags only at the end (optional).\n" "- No repeated sentences; avoid clichés.\n" "- Return a single cohesive post in plain text only." ) def transform_instruction(kind: str) -> str: mapping = { "shorter": "Shorten to ~120 words. Keep the opening intact. Plain text only.", "punchier": "Make the opening more punchy and contrarian; keep length similar. Plain text only.", "add_data": "Add one concrete metric or example supporting the main claim. Plain text only.", "less_emoji": "Remove all emojis. Plain text only.", "add_tags": "Append 2–4 niche hashtags at the end (new line). Plain text only." } return mapping[kind]