o
    Þ›XjE:  ã                   @  sˆ   d dl mZ d dlmZmZ d dlmZ d dlmZm	Z	 d dl
mZ dZeG dd„ dƒƒZeG d	d
„ d
ƒƒZdZd!dd„Zd"dd„Zd S )#é    )Úannotations)Ú	dataclassÚfield)ÚAny)ÚLAYOUTSÚCreativeBrief)Ú
LLMService)ÚlinkedinÚ	instagramÚxÚthreadsÚfacebookc                   @  s6   e Zd ZU ded< ded< edd	d
„ƒZddd„ZdS )ÚPlatformPostÚstrÚpostú	list[str]ÚhashtagsÚdataúdict[str, Any] | NoneÚreturnú'PlatformPost'c                 C  s@   |pi }| t | dd¡ƒ ¡ dd„ | d¡pg D ƒd d… d�S )Nr   Ú c                 S  s   g | ]	}t |ƒ d ¡‘qS ©ú#)r   Úlstrip©Ú.0Úh© r   úsrc/services/ideation.pyÚ
<listcomp>   s    z*PlatformPost.from_dict.<locals>.<listcomp>r   é   ©r   r   )r   ÚgetÚstrip)Úclsr   r   r   r   Ú	from_dict   s
   þzPlatformPost.from_dictc                 C  sZ   | j  ¡ }dd„ | ¡ D ƒ}d |¡ ¡ }d dd„ | jD ƒ¡}|r+|› d|› � ¡ S |S )Nc                 S  s   g | ]}|  ¡  d ¡s|‘qS r   )r$   Ú
startswith)r   Úlnr   r   r   r       ó    z0PlatformPost.as_publish_text.<locals>.<listcomp>Ú
ú c                 s  s   � | ]
}|rd |› �V  qdS )r   Nr   r   r   r   r   Ú	<genexpr>   s   € z/PlatformPost.as_publish_text.<locals>.<genexpr>z

)r   ÚrstripÚ
splitlinesÚjoinr$   r   )ÚselfÚbodyÚlinesÚtagsr   r   r   Úas_publish_text   s
   
zPlatformPost.as_publish_textN)r   r   r   r   ©r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__annotations__Úclassmethodr&   r4   r   r   r   r   r      s   
 r   c                   @  sT  e Zd ZU ded< ded< ded< ded< ded< ded< ded< d	Zded
< dZded< eed�Zded< d	Z	ded< dZ
ded< dZded< dZded< d	Zded< dZded< dZded< d	Zded< d	Zded< dZded< eed�Zd ed!< eed�Zd ed"< eed�Zded#< eed�Zd$ed%< d7d)d*„Zd8d+d,„Zed9d:d5d6„ƒZd-S );ÚContentIdear   ÚidÚformatÚtopicÚhookÚnews_urlÚ
news_titleÚvisual_briefr   Úcreative_directionÚeditorial_overlayÚlayout)Údefault_factoryr   ÚpaletteÚpalette_nameÚmodern_startupÚ
typographyÚdark_premiumÚbackground_styleÚeditorial_3dÚillustration_styleÚimage_promptÚ	cinematicÚvideo_styleÚsquareÚaspectÚwhy_it_mattersÚkey_factÚaiÚnews_categoryzlist[dict[str, str]]ÚslidesÚvideo_scriptÚsource_refszdict[str, PlatformPost]Ú	platformsÚnamer   r   c                 C  s   | j  |¡pt| jddgd�S )NÚAIÚTechr"   )r[   r#   r   r?   )r0   r\   r   r   r   Úplatform<   s   zContentIdea.platformc                 C  s   | j pdd d… S )Nz	Tech Newsé<   )rA   )r0   r   r   r   Únews_source_label?   s   zContentIdea.news_source_labelNr   údict[str, Any]ÚidxÚintÚbriefúCreativeBrief | Noneú'ContentIdea'c           
        sP  t | dd¡ƒ ¡  ¡ }|dvrd}| d¡pg }|dkr^t|ƒdk r^| dd¡d	dd
œdt | dd¡ƒdd
œdt | dd¡ƒdd
œdt | dd¡ƒdd
œdddd
œdddd
œdddd
œg}t | d¡pj|ri|jndƒ ¡ }|tvr|rw|jnt|ttƒ  }d d!„ | d"¡p�|rŒ|jng D ƒd d#… }|r�|s�t|jƒ}| d$¡p£i ‰ ‡ fd%d&„t	D ƒ}d'd!„ | d(¡p¶g D ƒd d)… }	|d*k�rt|	ƒd#k �rdt | dd¡ƒd+dd,d-d.œd/d0t | dd¡ƒdd1dd.œd2t | dd3¡ƒt | dd¡ƒdd4d5d.œd6d7t | dd¡ƒdd8d9d.œdd:d;dd<d=d.œg}	| dVi d>t | d>¡�p!d?|d@›�ƒ“d|“dt | dd¡ƒ ¡ “dt | dd¡ƒ ¡ “dAt | dAd¡ƒ ¡ “dBt | dBd¡ƒ ¡ “dCt | dCd¡ƒ ¡ “dDt | dDd¡ƒ ¡ “d|“d"|“dEt | dE¡�p}|�r||j
ndƒ“dFt | dF¡�pŽ|�r�|jndGƒ“dHt | dH¡�pŸ|�rž|jndIƒ“dJt | dJ¡�p°|�r¯|jndKƒ“dLt | dLd¡ƒ ¡ “dMt | dM¡�pÌ|�rË|jndNƒ“dOt | dO¡�pÝ|�rÜ|jndPƒ“dt | dd¡ƒ ¡ “dt | dd¡ƒ ¡ “dQt | dQdR¡ƒ ¡  ¡ “ddSd!„ |D ƒd d)… “d(|	“dTdUd!„ | dT¡�pg D ƒd d9… “d$|“ŽS )WNr=   Úimage>   rh   ÚvideoÚcarouselrX   rj   é   r?   ÚHookzThe moment everything shifted.)Útitler1   ÚrolezWhat happenedr>   r   ÚwhatzWhy it mattersrT   ÚwhyzThe numbersrU   ÚstatszThe insightz$Here's what most people are missing.ÚinsightzWhat's nextz This changes the next 12 months.Úfuturez	Your movez)Save + share with someone who needs this.ÚctarE   rD   c                 S  ó   g | ]}t |ƒ‘qS r   ©r   )r   Úcr   r   r   r    X   ó    z)ContentIdea.from_dict.<locals>.<listcomp>rG   é   r[   c                   s   i | ]}|t  ˆ  |¡¡“qS r   )r   r&   r#   )r   Úp©Úraw_platformsr   r   Ú
<dictcomp>]   r)   z)ContentIdea.from_dict.<locals>.<dictcomp>c                 S  sj   g | ]1}t | d d¡ƒt | dd¡ƒt | dd¡ƒt | dd¡ƒt | dd¡ƒt| dd¡p/dƒd	œ‘qS )
Úbeatr   Ú	on_screenÚ	voiceoverÚvisualÚmotionÚzoom_inÚsecondsry   ©r~   r   r€   r�   r‚   r„   )r   r#   Úfloat©r   Úsr   r   r   r    _   s    	ùúÿrY   é   ri   zThis just dropped.Úpunch_ing      @r…   ÚproblemzWhat changedÚ	pan_rightÚdetailszThe detailsrƒ   é   ÚimpactzWhy you should careÚparallaxé   zFollow for daily AI dropsz
Save this.Úzoom_outé   r<   úidea-Ú02dr@   rA   rB   rC   rH   rJ   rI   rL   rK   rN   rM   rO   rQ   rP   rS   rR   rW   rV   c              
   S  sJ   g | ]!}t | d d¡ƒt | dd¡ƒt | dd¡ƒt | dd¡ƒdœ‘qS )rm   r   r1   rn   rO   )rm   r1   rn   rO   )r   r#   r‡   r   r   r   r    ‰   s   J rZ   c                 S  ru   r   rv   )r   r   r   r   r   r    ‹   rx   r   )r   r#   Úlowerr$   ÚlenrE   r   rG   ÚlistÚ	PLATFORMSrH   rJ   Ú
backgroundrN   rQ   rS   )
r%   r   rc   re   ÚfmtrX   rE   rG   r[   rY   r   r{   r   r&   B   s¤   


ù 
*
	÷
ö(ûÿþýüûúùø	÷
ö õ ô ó òñ ð ïîíìëê"éèzContentIdea.from_dict)r\   r   r   r   r5   )N)r   rb   rc   rd   re   rf   r   rg   )r6   r7   r8   r9   rC   rE   r   r˜   rG   rH   rJ   rL   rN   rO   rQ   rS   rT   rU   rW   rX   rY   rZ   Údictr[   r_   ra   r:   r&   r   r   r   r   r;   !   s:   
 

r;   u%  You are the Creative Director + Social Strategist for a premium AI/Tech media brand
(quality bar: OpenAI, Nvidia, Apple, Stripe, Linear, Figma, Arc â€” NEVER Canva-like templates).

MISSION: Turn breaking tech news into scroll-stopping, publish-ready social assets with agency-level polish.

VOICE:
- Natural fluent English, modern Gen-Z energy, professional credibility.
- Sharp, concrete, specific. Avoid empty hype, buzzword soup, and generic phrasing.
- Forbidden cliches: "game-changer", "revolutionary", "changing everything" unless backed by evidence.

FACTUALITY (non-negotiable):
- Every idea maps to ONE real item from the provided feed.
- Do not invent data, quotes, timelines, valuations, benchmarks, or product claims.
- If a number is uncertain, speak in implications, not fake precision.
- key_fact must be specific and verifiable from the source context.

CONTENT RULES:
- Prioritize: breaking launches, funding rounds, model updates, cyber incidents, research papers, major big-tech moves.
- Hook in first 1â€“2 lines. Make "why it matters" practical for operators/builders/decision-makers.
- Unique copy per platform. Never paraphrase the same caption 5 times.
- Emojis: 0â€“3 tasteful max.
- Hashtags ONLY in hashtags arrays (not in post body).

PLATFORM WRITING STANDARDS:
- linkedin: 900â€“1300 chars, insight-led narrative, crisp line breaks, 3â€“5 tags.
- instagram: high-energy storytelling, skimmable rhythm, 8â€“12 tags, social CTA.
- x: <=260 chars, punchy and opinionated, one clear takeaway.
- threads: 350â€“500 chars, conversational perspective + debate hook.
- facebook: 400â€“800 chars, clear context + discussion starter.

IMAGE / VISUAL RULES:
- image_prompt describes a full cinematic scene that EXPLAINS the story visually.
- No text-in-image instructions, no poster language, no blank backgrounds, no generic "AI brain" wallpaper.
- Include tangible objects/environments: devices, UI, labs, chips, dashboards, robotics, people-in-context, data metaphors.
- Match subject language to news_category (ai/hardware/startup/cyber/research/programming/robotics/healthcare/finance/cloud/opensource/bigtech).
- Follow assigned creative brief EXACTLY (layout, palette, typography, background, illustration_style).

CAROUSEL RULES:
- 6â€“7 slides, narrative arc: hook -> what happened -> why it matters -> stats/fact -> expert insight -> future impact -> CTA.
- Each slide must add NEW information (no repetitive rewording).
- Slide titles <=8 words. Body concise and high-signal.

VIDEO RULES:
- Cinematic reel storyboard, not slideshow.
- Beats: hook (0â€“2s) -> problem (2â€“6s) -> details (6â€“15s) -> impact (15â€“25s) -> CTA (25â€“35s).
- Each beat needs: on_screen (<=6 words), voiceover, visual scene, motion.
- motion one of: zoom_in|zoom_out|pan_left|pan_right|punch_in|parallax|glitch.

QUALITY GATE (self-check before output):
Reject and regenerate internally if any idea is generic, repetitive, or weak.
Do not output ideas that:
- look like templates,
- repeat prior layout/palette/style,
- have weak hooks,
- lack a concrete key_fact,
- or have vague visual prompts.
Úllmr   Ú
brand_namer   ÚprofilesÚ
news_blockÚ
batch_sizerd   Úenable_videoÚboolÚcreative_briefsúlist[CreativeBrief]Úrecent_stylesr   úlist[ContentIdea]c                C  sz  |rdnd}g }	|rg d¢nddg}
t |ƒD ]}|	 |
|t|
ƒ  ¡ qd|› d|› dtd	ƒ d
d„ t|ƒD ƒ¡› dt|ƒ› d|› d|› d|› d|	› d|› d�}| jt|dd�}t	|t
ƒrb| d¡n|}t	|tƒsmtdƒ‚g }t|d |… ƒD ]C\}}|t|ƒk r…|| nd }tj||d |d�}|rµ|j|_t|jƒ|_|j|_|j|_|j|_|j|_|j|_|j|_| |¡ qw|S )Nzimage, carousel, videozimage, carousel)rh   rj   ri   rh   rj   zBrand: zC

## Recent styles ALREADY USED (do NOT repeat these combinations)
uL   

## LOCKED creative briefs (assign idea-01 to brief 1, etc. â€” mandatory)
é
   c                 s  sH   � | ]\}}|d  › d|j › d|j› d|j› d|j› d|j› �V  qdS )é   z. z | N)rE   rH   rJ   rN   rQ   )r   ÚiÚbr   r   r   r,   ã   s   €F z!generate_ideas.<locals>.<genexpr>z

Full briefs:
z

## Creator style notes
uL   

## Latest news (ONLY source of truth â€” pick the highest-impact stories)
z

Create exactly zJ packages from DISTINCT high-impact news stories.
Suggested format order: z
Mix of formats available: u¯  .

Each idea MUST:
1. Use its locked creative brief fields (layout, palette, typography, background_style, illustration_style, video_style, aspect, palette_name)
2. Include a rich image_prompt (cinematic scene, no text-in-image, agency quality)
3. Include news_category one of: ai|hardware|startup|cyber|research|programming|robotics|healthcare|finance|cloud|opensource|bigtech
4. Have UNIQUE platform copy for linkedin, instagram, x, threads, facebook
5. Have a strong key_fact tied to the source (no fabricated numbers)
6. Avoid repeating sentence structure across platform posts for the same idea

JSON schema:
{
  "ideas": [
    {
      "id": "idea-01",
      "format": "image|carousel|video",
      "topic": "...",
      "hook": "scroll-stopping â‰¤8 words",
      "news_url": "https://...",
      "news_title": "exact title",
      "news_category": "ai",
      "why_it_matters": "...",
      "key_fact": "one concrete fact",
      "creative_direction": "1-2 sentence art direction",
      "layout": "...",
      "palette_name": "...",
      "palette": ["#...", "#..."],
      "typography": "...",
      "background_style": "...",
      "illustration_style": "...",
      "aspect": "square|portrait",
      "image_prompt": "detailed cinematic scene WITHOUT any text overlays...",
      "visual_brief": "short overlay caption for design system (1 sentence)",
      "video_style": "...",
      "source_refs": ["news_title"],
      "slides": [
        {"title": "...", "body": "...", "role": "hook|what|why|stats|insight|future|cta", "image_prompt": "optional"}
      ],
      "video_script": [
        {"beat": "hook", "on_screen": "...", "voiceover": "...", "visual": "...", "motion": "punch_in", "seconds": 2.5}
      ],
      "platforms": {
        "linkedin": {"post": "...", "hashtags": ["AI"]},
        "instagram": {"post": "...", "hashtags": ["AI"]},
        "x": {"post": "...", "hashtags": ["AI"]},
        "threads": {"post": "...", "hashtags": ["Tech"]},
        "facebook": {"post": "...", "hashtags": ["AI"]}
      },
      "quality_checks": {
        "hook_strength_1to10": 9,
        "specificity_1to10": 9,
        "visual_uniqueness_1to10": 9,
        "factual_confidence_1to10": 9
      }
    }
  ]
}
ià.  )Ú
max_tokensÚideasz)LLM ideation did not return an ideas listr©   )re   )ÚrangeÚappendr—   Úchrr/   Ú	enumerateÚ_briefs_jsonÚcomplete_jsonÚIDEATION_SYSTEMÚ
isinstancerœ   r#   r˜   ÚRuntimeErrorr;   r&   rE   rG   rH   rJ   rš   rL   rN   rQ   rS   )r�   rž   rŸ   r    r¡   r¢   r¤   r¦   ÚformatsÚformat_planÚcyclerª   Úuserr   Ú	raw_ideasr­   Úitemre   Úidear   r   r   Úgenerate_ideasË   sR   ýú	÷ôñïîíM
r¾   Úbriefsc                 C  st   g }t | dƒD ]-\}}| d|d›d|j› d|j› d|j› d|j› d|j› d	|j› d
|j› d|j	› �¡ qd 
|¡S )Nr©   r”   r•   z	: layout=z; typography=z; background=z; palette_name=z
; palette=z; illustration_style=z; video_style=z	; aspect=r*   )r±   r¯   rE   rJ   rš   rH   rG   rN   rQ   rS   r/   )r¿   r2   rª   r«   r   r   r   r²   A  s$   ÿÿÿþþþÿ
r²   N)r�   r   rž   r   rŸ   r   r    r   r¡   rd   r¢   r£   r¤   r¥   r¦   r   r   r§   )r¿   r¥   r   r   )Ú
__future__r   Údataclassesr   r   Útypingr   Úsrc.services.creativer   r   Úsrc.services.llmr   r™   r   r;   r´   r¾   r²   r   r   r   r   Ú<module>   s    n
;v