
    ia                    D    d Z ddlmZ ddlZddlmZmZ ddZd	dZd
dZ	y)u   skills/comparador_finalistas.py — COMPARADOR (estación 5)

Cruza candidatos vs ganador. Selecciona 5 SIMILARES + 1 ARRIESGADO.
Skill canónica: comparador-finalistas.

Backend: claude CLI subprocess (LLM Opus 4.7 para scoring multidimensional).
    )annotationsN)SkillContextSkillResultc           	        |j                         }|j                  di       j                  d      xs i }|j                  di       j                  d      xs i }|j                  d      xs i }|j                  d      xs g }|st        ddg      S t        |      d	k  rt        dd
t        |       dg      S t	        ||      }|j                  |dd      }|j                  d      s3t        dd|j                  d      xs |j                  d       g      S 	 t        j                  t        |j                  dd                  }	|	j                  d      xs g }|D cg c]  }|j                  d      dk(  s| }}|D cg c]  }|j                  d      dk(  s| }}t        |      dk7  st        |      dk7  r&t        ddt        |       dt        |       g      S |j                  d|	d d!"       t        d#ddd$%      S # t        $ r/}
t        dd|
 |j                  dd      d d g      cY d }
~
S d }
~
ww xY wc c}w c c}w )&Nsectionsanalizarbuscarcombo_completocandidates_validatedFu#   caja.analizar.combo_completo vacío)okerrors   u!   Necesitamos ≥6 candidatos, hay u    — relanzar buscadoreszclaude-opus-4-7   )model	timeout_sr   u   claude CLI falló: stderrerrorstdout zJSON parse error: i  
finalistastiposimilar
arriesgado      u-   Esperaba 5 similares + 1 arriesgado, recibí +
comparadorreplacezcomparador-finalistas)modeactorT)count_similarescount_arriesgados)r   output)	read_cajagetr   lenbuild_compare_prompt
claude_clijsonloadsextract_json	Exceptionwrite_section)inputscontextcajaanalyzebusccombo
candidatespromptresparseder   f	similaresarriesgadoss                  MC:\Users\ferna\proyecto cero\_factory_3d_demo\skills\comparador_finalistas.pyrunr=      s]   Dhhz2&**:6<"G88J#''17RDKK()/RE017RJe-R,STT
:e/PQTU_Q`Paay-z,{||!%4F


V+<

LC774=e/B3778CTChX[X_X_`gXhBi-j,klleL2)>?@ L)/RJ&EJq!%%-9*DJIE(JjAEE&M\,I1jKJ
9~c+.!3e;C	N;K1SQ\M]L^_-
  	 ,YF]^$1ST'UVV  ee/A!-EswwxY[G\]a^aGb,cdde FJs6   #.H *III(I	I$IIIc                z    t        j                  | dd      }t        j                  |d d dd      }d| d| dS )NF   )ensure_asciiindent   zEres el agente COMPARADOR del flow Factory v4 escalado de formato.
Tu tarea: de los candidatos abajo, elegir EXACTAMENTE 6 finalistas: 5 similares + 1 arriesgado.

COMBO COMPLETO DEL GANADOR:
z.

CANDIDATOS (de los 4 buscadores paralelos):
u-  

CRITERIO scoring (multidim, pesos):
  awareness 0.20, sof 0.15, jergas 0.10, deseo 0.15, avatar 0.15,
  temporalidad 0.10, fuerza_cambio 0.10, formato 0.05.

REGLAS DURAS:
- 5+1 OBLIGATORIO. Nunca 6 similares ni 4 similares.
- 5 SIMILARES = top 5 por score · score ≥ 0.65.
- 1 ARRIESGADO = score 0.65-0.85 con UN diferenciador claro (formato distinto, avatar lateral, ángulo nuevo).
- En mercado saturado: rechazar UGC talking-head básico problem→solution.

Devuelve JSON estricto:
{
  "finalistas": [
    {
      "rank": 1, "tipo": "similar", "video_url": "...", "video_id": "...",
      "match_score": 0.92,
      "match_breakdown": {"awareness": 1.0, "sof": 1.0, "jergas": 0.85, "deseo": 1.0, "avatar": 0.90, "temporalidad": 1.0, "fuerza_cambio": 0.88, "formato": 0.95},
      "por_que_similar": "..."
    },
    ... 4 más similares ...,
    {
      "rank": 6, "tipo": "arriesgado", "video_url": "...", "match_score": 0.74,
      "diferenciador": "..."
    }
  ],
  "rejected_count": <int>,
  "rejected_reasons_summary": {...}
}

Responde SOLO con el JSON.)r)   dumps)r3   r4   combo_scand_ss       r<   r'   r'   0   sS    jjU1=GZZ
3BeAFF 		 
  	& &    c                N   | j                         }|j                  d      rI|j                  dd      }t        |      dk\  r)|d   }|j                  d      r|dd  j                         }	 |j	                  d      }|j                  d      }|||dz    S # t        $ r |cY S w xY w)Nz```r?   r   r)      {})strip
startswithsplitr&   indexrindexr,   )r   spartsfirstlasts        r<   r+   r+   \   s    A||Eq!u:?aA||F#abEKKMxx}tAv s   ,)B B$#B$)r.   dictr/   r   returnr   )r3   rT   r4   listrU   str)r   rW   rU   rW   )
__doc__
__future__r   r)   skills._libr   r   r=   r'   r+    rF   r<   <module>r\      s'    #  1 WF)XrF   