o
    YFji                    @  s,  U d dl mZ d dlZd dlZd dl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 dlmZmZ d dlmZ d d	lmZ d d
lmZmZ d dlmZmZ d dlmZ d dlmZ d dlm Z m!Z! d dl"m#Z#m$Z$m%Z%m&Z&m'Z' d dl(m)Z) d dl*m+Z+m,Z, d dl-m.Z. d dl/m0Z0 e1e0Z2dhZ3de4d< h dZ5dZ6dZ7dZ8dZ9dZ:ddiZ;G dd  d eZ<G d!d" d"eZ=G d#d$ d$eZ>G d%d& d&Z?dddddddd'dd?d@Z@ddEdFZAddHdIZBddMdNZCd dPdQZDdd[d\ZEdd^d_ZFddadbZGddcddZHddedfZIddgdhZJddidjZKddkdlZLddndoZMd	dqdrZNd
dtduZOddwdxZPddzd{ZQdddZRdddZSdddZTdddZUdddZVdddZWdddZXdddZYdddZZdddZ[dddZ\dddddZ]dddZ^dddZ_dddZ`dddddZadddZbdddZcdddZddddZed ddZfd!ddńZgd"ddȄZhd#dd܄Zid$dd߄Zjd%ddZkd&ddZld'ddZmd(ddZnd)ddZod*ddZpd+ddZqd ddZrd,ddZsd-ddZtdS (.      )annotationsN)ThreadPoolExecutoras_completed)Counter)datetimetimezone)Path)AnyProtocol)APIMartRequestError)OpenAIRequestError)QwenPhotoAnalyzerQwenRequestError)load_image_generatorload_visual_reviewer)prepare_photo_inputs)ensure_png_alpha)evaluate_action_semanticsscore_candidate_frame)FRAMES_PER_ACTION_read_rgba_png_write_rgba_pngcompose_action_frame_atlasextract_action_strip_frames)#build_action_strip_layout_guide_png)write_animation_previewswrite_contact_sheet_png)evaluate_size_proportions)ALLOWED_ACTIONSsleepzset[str] PREVIOUS_FRAME_REFERENCE_ACTIONS>   sitidlelookr   tail_wag)r   r      g     f@   two_frame_copy   walk   c                   @  s   e Zd Zddd	Zd
S )PhotoAnalyzerpet_namestrnotesimageslist[dict[str, Any]]returndict[str, Any]c                C     d S N )selfr,   r.   r/   r5   r5   L/opt/sixxie/releases/current/services/pet_builder/photo_generation_worker.pyanalyze_pet_photos-   s   z PhotoAnalyzer.analyze_pet_photosNr,   r-   r.   r-   r/   r0   r1   r2   )__name__
__module____qualname__r8   r5   r5   r5   r7   r+   ,   s    r+   c                   @  s0   e Zd ZdddddZdddddddZdS )ImageGenerator	1024*1024)sizer,   r-   r.   analysisr2   r/   r0   r?   r1   c                C  r3   r4   r5   )r6   r,   r.   r@   r/   r?   r5   r5   r7   generate_canonical_pet2   s   	z%ImageGenerator.generate_canonical_petNr   )previous_frame_image_bytescandidate_indexr?   actionframe_indexintcanonical_image_bytesbytesrB   bytes | NonerC   c       
         C  r3   r4   r5   )r6   rD   rE   r,   r.   r@   r/   rG   rB   rC   r?   r5   r5   r7   generate_action_frame=   s   z$ImageGenerator.generate_action_frame)r,   r-   r.   r-   r@   r2   r/   r0   r?   r-   r1   r2   )rD   r-   rE   rF   r,   r-   r.   r-   r@   r2   r/   r0   rG   rH   rB   rI   rC   rF   r?   r-   r1   r2   )r:   r;   r<   rA   rJ   r5   r5   r5   r7   r=   1   s    r=   c                   @  s    e Zd Zdd	d
ZdddZdS )ActionReviewerr,   r-   rD   image_bytesrH   
image_mimer1   r2   c                C  r3   r4   r5   )r6   r,   rD   rL   rM   r5   r5   r7   review_action_framesO   s   z#ActionReviewer.review_action_framesc                C  r3   r4   r5   )r6   r,   rL   rM   r5   r5   r7   review_contact_sheetY   s   z#ActionReviewer.review_contact_sheetN)
r,   r-   rD   r-   rL   rH   rM   r-   r1   r2   )r,   r-   rL   rH   rM   r-   r1   r2   )r:   r;   r<   rN   rO   r5   r5   r5   r7   rK   N   s    

rK   c                   @  s   e Zd ZdZdZdd
dZdS )LocalPetPhotoAnalyzerlocal_photo_analysis_v1localr,   r-   r.   r/   r0   r1   r2   c                C  s.   t | d| }| j|ddddg dddd
S )N unknowng      ?Tu_   本地素材元数据检查通过；外貌还原以授权原图和 canonical 主形象为准。)
providerspecies
base_coloraccent_color	eye_color
body_shapedistinctive_marks
confidencesafe_for_generationuser_visible_summary)_infer_species_from_textrU   )r6   r,   r.   r/   rV   r5   r5   r7   r8   g   s   z(LocalPetPhotoAnalyzer.analyze_pet_photosNr9   )r:   r;   r<   modelrU   r8   r5   r5   r5   r7   rP   c   s    rP   )analyzerimage_generatoraction_reviewercandidates_per_frame%stop_after_first_acceptable_candidateresume_build_diraction_frame_generation_moder,   r-   r.   photo_pathslist[str | Path]output_root
str | Pathra   PhotoAnalyzer | Nonerb   ImageGenerator | Nonerc   ActionReviewer | Nonerd   rF   re   bool | Nonerf   str | Path | Nonerg   
str | Noner1   r   c           J        s    std|stdd u}|d u}pt tttddp%d!d u o1t!||d}|p7t!}|r?t!dd u}'d u rK!dv 't	|
pTt
jdd}
|
d	kr`td
t|}|j    |d

ddu r{tdt}|	d urt|	nd %%r%jnd! d| dt  }d! d| dt  }%pt|| }|d "tdttd"d "d "d #"d "d "d }"d jddd jddd #jddd jddd jddd |jddd t|d t|  |d "d  }%rV| rV| td!d !ttd"d#d$d%< d&d'< "d( }| rJ| d)dd*d+}n>t\}| n2j    
|d,d-d%ttrrsvtd.| t\}"d(  i i  i i i 	g g )g }g }g }g }g }d/d/d/d/ d/d/d/i d0t  &d"fd5d6$d$fd?d@(d #$fdCdDd!fdFdGd!fdJdKd$fdMdN}d $fdOdP,tdQd *t!*ot"!++st#t$}d/dRd 	
$()*fdVdW}d/dXd 	
!$%&'(,fdZd[}dfd]d^} d
!%&+fd_d`}!|!  t$D ]w}"t%|"da}#||" db |# d}$+r(d/}%t&|"t'}&|%|&k r|$s||"|#|%dc}'|'snn| |"ddd}(|(de rd}$n`t(|(|"da})|"d d |)rdfnt)|(dg desdhndi|(dj dkg |(dg dkg dl}*t*|(}+|+r|*+|+ $|* |"|vr|,|" -|"d  %r&.|" |%d7 }%|%|&k r|$r|$s(|"|vr(|,|" |$r-q{t/dmD ]},||"|,td dX | |"|,d dd}(|(de rOd}$ nt(|(|"da})|"d d |)rb|,d/krbdfn*|)rgdnn%t)|(dg desx|,d/krxdhnt)|(dg desdon|,d/krdpndq|(dj dkg |(dg dkg dl}*t*|(}+|+r|*+|+ $|* |,d/krt)|(dr dert)|(dj dert)|(dg der|)r-|"d  %r&.|" |,|" q1|$stds|" q{)rdtkrdu|rdtkrdvdw}-||- }."dx }/d#}0i }1d }2tdyd }3|r*t!|3s*tdzd{}4d}5i }6t/|5D ]}7t/|4D ]X}8t0dd|}9t1|9j2 t3|9j2 t4|9j2}:t5|:};|;r{|;D ]}"$|"d d d}d~ q]t"d |: tdd6|; |.|9j7 t89|. : }0t;|9j7|/d}1t!|3s nt/dmD ]H}<z|3  |/ d&d}2W  n8 t<y }= z+|<d/krW Y d }=~=qdddddddt#t$dt|=d d gdd}2W Y d }=~=qd }=~=ww t"d |2 t=|2r nt|2t>r|2dni }>t|>t>r|>dng }?t|?t#rdd |?D ng }@|8|4d k r|@r$d d d d|@|8d d |@D ]O}A|A|vrA|,|A -|Ad  ||A|8d d dX | |A|8d dd}B|Bde s|Ad d d|Bdj dkg d}*t*|B}+|+rx|*+|+ $|* tds|A q5q;$d d d d|@d tdt?|9j2}6t"d |6 |6dedu r nzt@|6}C|7|5d k r|Cr$d d d d|C|7d |6dkg d |CD ]C}A|A|vr|,|A -|Ad  ||A|7d d dX | |A|4|7 d dd}B|Bde s$|Ad d d|Bdj dkg d tds|A qdq4$d d d d|C|6dkg d  tA"d d}DtB||  |9j7d}EtC|9j2|:d}FtDdi d|d  d|d|d|0d|-d|dt|d"d dtdpqtdd#pqddtd"ptd"d#dtdd#ddd E D d fddt$D dtdd#ddd E D dtFdi dd E D ddddd|	ddr|9j2d|:d|6di dtGdÈddœdƈdǈ)d|d|d|d|d|dtHdtIdtJtKdЈdшd҈dӈ |
t)'%rt%nd tLdԜdՈd'd&dֈ
}Gd|Gd< i ddړddܓddddߓd|2rIdnd ddddddd|Eddd|d|dt|2t>rl|2dnd dt|2t>rz|2d"nd d|1d|D|Gd d< tM|G}HtN|G
}It|d |G t|d |H t|d tO|  |)||||d
 "d jPtQ|Gdd t"d |9j2 t"d |: t"d di t"d |F t"d |I |S (	  Nzpet_name is requiredzat least one photo is requiredrU   qwenprovider_slugimage_generator_was_providedanalyzer_was_providedrt   >   gpt-image-2apimart-gpt-image-2apimart PET_ACTION_FRAME_GENERATION_MODEdeterministiczndeterministic action frame mode is disabled for user-facing builds because action semantics cannot be verified)r,   r.   r/   r]   Fz6photo analysis marked this build unsafe for generationzbuild--zpackage-qar*   r(   zaction-frameszaction-frame-candidateszaction-frame-raw-candidateszaction-reviewszaction-contact-sheetszlayout-guideszaction-stripsTparentsexist_okzpet_request.jsonpet_idr,   
image_refszcanonical-reference.png	canonicalr`    rD   rE   rU   r`   rL   	image/pngrM   zcanonical.pngresumed_existing_alpha_pngqa/canonical.pngmethodalpha_capablesourcer>   )r,   r.   r@   r/   r?   z5canonical image generation did not return image bytesr    canonical_plus_per_action_framesfailurer2   r1   Nonec                   s      |  td d i d S )Ncandidate-failures.jsonfailures)append_write_json)r   )candidate_failuresqa_dirr5   r7   record_candidate_failure   s   
z?build_pet_package_from_photos.<locals>.record_candidate_failurerD   r-   rE   rF   rC   
int | Noneexc	Exceptionc                   sB   t |sd S  | ||dt|d d d td|  d| |)Nprovider_request_blockedi  rD   rE   rC   reasonprovider_errorz"image provider unavailable during  frame )_provider_request_blockedr-   
ValueErrorrD   rE   rC   r   )r   r5   r7    stop_if_provider_request_blocked  s   	zGbuild_pet_package_from_photos.<locals>.stop_if_provider_request_blockedaction_generationdict[str, Any] | Nonec              	     s`  | d}t|tr|s| ||dd d S |  d| d| d | t|ttd\}}t|}|dkrDt|d \}}t|} |  d| d| d }|| |rf| |||t|d d S t	| |gid	d
j
d t|  d }|r|d nd dd}	t|	}
|
r| |||
t|	d d S t| |	|d}t|}|||||	|| ||dS )NrL   empty_image_bytesrD   rE   rC   r   r}   .png
chroma_keychroma_thresholdchroma_key_background_missingrD   rE   rC   r   transparencyTallow_stable_pet_partsrowsframesr   )source_bboxforeground_pixels)rD   rE   rC   r   frame_report)rD   r   rC   )
generationrL   r   rC   r   score
base_scorevisual_detail_score)get
isinstancerH   write_bytesr   ACTION_FRAME_CHROMA_KEYACTION_FRAME_CHROMA_THRESHOLD_transparency_rejection_reason_safe_transparency_reportr   r~   r   index_frame_rejection_reason_safe_frame_reportr   _candidate_visual_detail_score)rD   rE   rC   r   action_bytesframe_transparencytransparency_rejectioncandidate_pathcandidate_reportr   rejection_reasonr   r   )candidate_dirraw_candidate_dirr   r5   r7   process_frame_candidate  s   
 

		z>build_pet_package_from_photos.<locals>.process_frame_candidatesource_reasonc                   sj   d7 rdndt  | |ddd|  d| tdd	 d
dd|d d dtddddS )Nr*   *canonical_plus_deterministic_action_frames,canonical_plus_deterministic_action_fallbackrD   rE   r   zdeterministic-fallback::r`   rT   z:canonical-motion-fallbackcanonical_referencer   x   )r   external_image_countfallback_reasonprompt_sha256r   deterministic_canonical_motion)rL   rM   rU   
request_idr`   usager   fallback)*_deterministic_motion_frame_from_canonicalgetattrr-   r   rD   rE   rC   r   )canonical_bytescanonical_generation$deterministic_action_fallback_frames!force_deterministic_action_framesgeneration_strategyrb   rt   r5   r7   deterministic_action_generationd  s*   
zFbuild_pet_package_from_photos.<locals>.deterministic_action_generationsource_frame_image_bytesrH   c                   sR   d7 t || ddd|  tdd ddd	d	d
dt ddd
d
d	S )Nr*   )rE   r   zlocal-sleep-direction-variant:r`   rT   z:local-sleep-direction-lockprovider_first_sleep_poser   $local_sleep_direction_locked_variant)r   source_frame_indexr   source_moder   r   )	rL   rM   rU   r   r`   r   r   r   r   )%_direction_locked_sleep_variant_framer   r-   r   rE   rC   r   )r   rb   local_sleep_variant_framesrt   r5   r7   local_sleep_variant_generation  s$   zEbuild_pet_package_from_photos.<locals>.local_sleep_variant_generationr   c              
     s8   | ||d|d d d | || | |||ddS )N!provider_action_frame_unavailable   r   r   rD   rE   rC   r   r5   r   )r   r   r   r5   r7   !use_deterministic_action_fallback  s&   
	zHbuild_pet_package_from_photos.<locals>.use_deterministic_action_fallbackc           
   
     s   | t vrd S  | pg }| pg }|r|sd S t|d }t|| }t|dtr3|dni }d7 | ||d||d d d i ||| d|dd d	|  d	| d
i |d||d d ddd}	| |||	dS )Nr*   r   %provider_previous_frame_copy_fallbackr   )rD   rE   rC   r   r   r   r   r   rU   r   z:copy-fallbackprevious_same_action_framer   )r   r   r   provider_previous_frame_copy)rL   rM   r   r   r   r   )$PROVIDER_PREVIOUS_FRAME_COPY_ACTIONSr   lendictr   )
rD   rE   rC   r   previous_framesprevious_generationsr   source_generationsource_usagefallback_generation)action_framesaction_generationsr   ,provider_previous_frame_copy_fallback_framesr   r5   r7    use_previous_frame_copy_fallback  sP   


zGbuild_pet_package_from_photos.<locals>.use_previous_frame_copy_fallbackgenerate_action_strip)strip_candidate_indexlayout_guide_image_bytesr  boolc                  s  t sdS dz7| 
 	 g |dd}|r||d< z	d/i |}W n ty=   |dd  d/i |}Y nw W n4 tys } z(| dd |d | d d dt|d d	 d
 | vrh|  W Y d }~dS d }~ww |d}t|t	r|s| d d dd | vr|  dS j
ddd |  d | t|ttd\}}t|}|dkrt|d \}}t|}|  d | |r| d d |t|d | vr|  dS t| |dd}	t|  d dd |	 D  |	ds| d d d|	dd | vr|  dS g | < g  | < g | < g | < t|dd}
t|	d D ]\}}t|}||d< d |d!< |
 d"| |d< |
|d#< ||d$< | |d%|d&}|sg | < g  | < g | < g | < | vr|   dS t|d' }|d |d(< |d) |d*< |d+ |d+< |d, |d,< |  |  |  |g |  |d  |  |d-  |  d.| d |d  q:dS )0NF canonical_plus_per_action_stripsz1280*720)rD   r,   r.   r@   r/   rG   r  r?   rC   r   action_strip_generation_failedr   r   rL   action_strip_empty_image_bytesr   Tr   z-raw.pngr   r   r   r   r   .jsonc                 S  s   i | ]\}}|d kr||qS )r   r5   ).0keyvaluer5   r5   r7   
<dictcomp>E      zWbuild_pet_package_from_photos.<locals>.generate_action_strip_frames.<locals>.<dictcomp>okaction_strip_structure_invalidfailure_reason)rD   rE   rC   r   strip_failure_reasonr   r   r   r   rM   z:frame-strip_request_idstrip_frame_indexr   r   r   selected_candidate_indexr   candidate_scorer   r   r   r}   r5   )callablestrip	TypeErrorpopr   r-   r   r   r   rH   mkdirr   r   r   r   r   r   r   r   items	enumerater   )rD   r  r  strip_kwargsstrip_generationr   strip_bytesstrip_transparencyr   	extractedr  rE   frame_bytesframe_generation	candidateselected_generation)action_candidate_generationsaction_frame_dirr   r   action_strip_diraction_transparencyr@   canonical_reference_bytesr   r.   r,   r   r   r   strip_fallback_actionsstrip_generatorr5   r7   generate_action_strip_frames  s  
	



	
"
	


"zCbuild_pet_package_from_photos.<locals>.generate_action_strip_frames)candidate_index_offsetr0  c          %        s	  g  < g  < g  < g  <   i }d } dkrtnt}i }t rΈsΈ	dkrt fddD sg }t|D ]'}  d| d }rU vrU| rUq>t	D ]}	||||	 f qYq>|rΈd7 t|7 t	t|t
}
t|
dF fd	d
|D }t|D ]*}|| \}}z
| |||f< W q ty } z||||f< W Y d }~qd }~ww W d    n1 sw   Y  t|D ]}  d| d }r) vr)| r)| }t |ttddd}  |   |g   |   ddd  d| dd |}q| |g }d}tra dkra|dkra ra ||||  d dd}|ra|| d}r| || ||ddd}|r||| d}t	D ]}	|r n||	 }zM ||f}||f}|v r| }n||v r|| }nd }t|tr||d ur|}n tv r|nd }j |  g ||dd
}W nG ty } z:t|r ||dt|d d d W Y d }~q |||d  ||t|d d d W Y d }~qd }~ww  |||d}|r5|| r5 nq|s|	 }z tv rF|nd }j |  g ||dd
}W nj ty } z\t|r} ||dt|d d d n |||d  ||t|d d d |d }d}d }z tv r|nd }j |  g ||dd
}W n ty } zt|rو ||dt|d d d n |||d  ||t|d d d tdd }t|rj|d }z| |  |dd }W nS tyd } zF |||d  ||t|d d d  ||d t|d} | rF||  n |d d!d td"  d#| |W Y d }~n3d }~ww d}|}n) ||d t|d} | r||  n |d d!d td"  d#| |W Y d }~nd }~ww |r |||d}|r|rd7 n
d7 
|| W Y d }~nd }~ww  |||d}|r|| |s ||	 d$ d%d} | r||  n |d d!d td"  d#| t|d&d' d(}!t|!d) }tr= dkr=|dkr=d*|d+< i t|d,tr4|d,i ni d+d*i|d,< |!d- |d.< |!d/ |d0< |!d1 |d1< |!d2 |d2<   |   d3d4 |D    |!d5    |!d6    d| d |!d5  |!d5 }q҈ dkrtttD ]T}"|"t }#t  |# |#|"d7}t  |# }$t |$d+< |#|$d8<   |# }  |   |g   |   |$   d|" d | qd S d S )9Nr)   r   c                 3  s    | ]	}|d   kV  qdS r   Nr5   )r  r  rD   r5   r7   	<genexpr>  s    zSbuild_pet_package_from_photos.<locals>.generate_per_frame_action.<locals>.<genexpr>r}   r   r*   max_workersc                   s@   i | ]\}}j j |  g d |dd||fqS Nr>   
rD   rE   r,   r.   r@   r/   rG   rB   rC   r?   submitrJ   r  )r  rE   rC   )rD   r@   r,  executorrb   r.   r,   r5   r7   r    s"    zTbuild_pet_package_from_photos.<locals>.generate_per_frame_action.<locals>.<dictcomp>r`   r   r   r   Tqa/action-frames/r   Fr   r   r   z*action_frame_generation_mode:deterministicr   r>   r7  r   r   r   r   r   generate_action_frame_minimal)rD   rE   r,   r.   r@   rG   rC   r?   no_acceptable_frame_candidatezframe QA failed for r   r(   z no acceptable provider candidatec                 S  s   | d S )Nr   r5   )itemr5   r5   r7   <lambda>  s    zRbuild_pet_package_from_photos.<locals>.generate_per_frame_action.<locals>.<lambda>)r  r   r   r   r   rC   r  r   r  r   r   c                 S     g | ]}t |d  qS )r   )r   r  r>  r5   r5   r7   
<listcomp>      zTbuild_pet_package_from_photos.<locals>.generate_per_frame_action.<locals>.<listcomp>rL   r   )r   target_frame_indexderived_from_frame_index)!
setdefaultWALK_GENERATED_FRAME_COUNTr   +_should_generate_action_frames_concurrentlyanyrangeexistsr   r   min%_concurrent_action_frame_worker_countr   r   resultr   
read_bytes_resumed_generation_payloadr-   r   *_should_use_local_sleep_direction_variantsr   r   r    rJ   r  _provider_request_transientr  r   maxr   r   _copy_walk_generation_payloadWALK_LOOP_MODE)%rD   r0  pooled_candidatesrB   generated_frame_countconcurrent_provider_results	job_specsrE   existing_frame_pathcandidate_offsetr5  futuresfuturerC   r   selected_bytesr'  
candidatesprovider_fallback_usedr&  prefetched_keylocal_prefetched_key
prefetchedr   previous_referencefallback_candidate_indexlast_resort_candidate_indexused_minimal_last_resortlast_resort_excminimal_generatorminimal_candidate_indexminimal_exccopy_candidateselectedrD  r   selected_transparency)r(  action_candidate_poolsr)  r   r   r+  r@   rd   !canonical_only_last_resort_framesr,  concurrent_action_frame_batchesconcurrent_action_frame_jobsr   r   rb   r   minimal_last_resort_framesr.   r,   prefetched_action_frame_resultsr   rt   r   resume_build_pathresume_regenerate_actionsre   r   r  )rD   r:  r7   generate_per_frame_actionz  s  












	








"_

  





z@build_pet_package_from_photos.<locals>.generate_per_frame_actionattemptc                  s  t | |  idd}t| |jd}t|| |  i t| t|}t|  }d }d}rt|drt|drt|drt	dD ]F}zj
 | |jdd}t|| d}W  n/ ty }	 z#|d	krpW Y d }	~	qGd
dddt|	d d gdd}d}W Y d }	~	qGd }	~	ww | |t|dot|dot|do|||||d}
 |  d |j t|  d |
 |
S )NTr   )rD   frame_qar  r&   r   )r,   rD   rL   rM   r2  r   errorrr   Fz>action visual review failed before receiving a usable responser   )passedr.   risksstatusrU   review)rD   rx  r  ry  semantic_qastyle_qavisual_reviewr   r
  )r   _single_action_frame_qar~   _annotate_selected_candidates_annotate_walk_loop_moder   "_evaluate_action_style_consistencyr  r   rJ  rN   r  rL   _visual_review_passedr   r-   r   r   )rD   rx  action_atlasaction_frame_qaaction_semantic_qaaction_style_qar  visual_review_okreview_attemptr   r  )action_contact_dirr   r   action_review_dirrc   r,   r5   r7   review_generated_action  sn   	z>build_pet_package_from_photos.<locals>.review_generated_actionc                    sv  ssdkr
d S g } t D ]=}t|sq|dkrtnt}t|D ](}| d| d }r9|vr9| r9q"tD ]}|}| |||f q=q"q| sPd S d7 t| 7 tt| t	}t
|dI  	
fdd| D }t|D ]-}	||	 \}}}z|	 |||f< W q{ ty }
 z|
|||f< W Y d }
~
q{d }
~
ww W d    d S 1 sw   Y  d S )	Nr   r)   r}   r   r*   r4  c                   sD   i | ]\}}}j j||   g d |dd|||fqS r6  r8  )r  rD   rE   rC   )r@   r,  r:  rb   r.   r,   r5   r7   r  i  s"    zlbuild_pet_package_from_photos.<locals>.prefetch_independent_action_frames_for_first_pass.<locals>.<dictcomp>)r   rH  rG  r   rJ  rK  r   r   rL  rM  r   r   rN  r   )rY  rD   rW  rE   rZ  r[  rC   r5  r\  r]  r   )r)  r@   rd   r,  rq  rr  r   rb   r.   r,   rt  rt   ru  rv  use_action_strips)r:  r7   1prefetch_independent_action_frames_for_first_passR  sF   
"zXbuild_pet_package_from_photos.<locals>.prefetch_independent_action_frames_for_first_passr2  r   )r  r  )rx  r  action_visual_review_repairr  action_style_consistency_repair"action_strip_weak_action_semanticsr  failure_reasons)rD   rE   rC   r   semantic_failure_reasonsstyle_failure_reasonsr&   (action_visual_review_failed_after_repair,action_style_consistency_failed_after_repairaction_semantics_repair$action_semantics_failed_after_repairry  zaction review failed for r  4canonical_plus_action_strips_with_per_frame_fallback1canonical_plus_action_strips_with_semantic_repairspritesheet.pngzcontact-sheet.pngrO   z:final visual QA reviewer must support review_contact_sheet   r   final_action_semantics_failedr   zaction-semantic-qa.jsonz$final action semantic QA failed for z, )spritesheet_bytesoutput_path)r,   rL   rM   rz  zKfinal contact sheet visual review failed before receiving a usable responser   )r{  identity_okrow_semantics_okdirection_okrow_distinct_okrepair_actionsr.   r|  r}  zfinal-visual-review.jsonr  r  c                 S  s    g | ]}t |tv rt |qS r5   )r-   r   r  rD   r5   r5   r7   rB  )  s
    z1build_pet_package_from_photos.<locals>.<listcomp>$final_contact_sheet_visual_qa_repair)rD   rE   rC   r   r  repair_round
   !final_visual_repair_action_failed)rD   rE   rC   r   r  $final_contact_sheet_visual_qa_failed)rD   rE   rC   r   r  z$final contact sheet visual QA failedzsize-proportion-qa.jsonsize_proportion_qa_repair)rD   rE   rC   r   r  r  r     $size_proportion_repair_action_failed-canonical_plus_action_frames_with_size_repairsize_proportion_qa_failed)rD   rE   rC   r   r  r  previews)r   
output_dir)	build_dirr   r,   r  )ry  r  r   r,   build_id
package_idchecksumspritesheet_filenamer   analyzer_modelimage_generation_providerrT   image_modelcanonical_request_idr   action_request_idsc                 S      i | ]\}}|d d |D qS )c                 S     g | ]
}t |d dqS r   r   r-   r   r  payloadr5   r5   r7   rB        <build_pet_package_from_photos.<locals>.<dictcomp>.<listcomp>r5   r  rD   payloadsr5   r5   r7   r        z1build_pet_package_from_photos.<locals>.<dictcomp>action_candidate_request_idsc                   s    i | ]}|d d  | D qS )c                 S  s   g | ]	}d d |D qS )c                 S  r  r  r  )r  r&  r5   r5   r7   rB    r  zGbuild_pet_package_from_photos.<locals>.<dictcomp>.<listcomp>.<listcomp>r5   )r  frame_candidatesr5   r5   r7   rB        r  r5   r  )r(  r5   r7   r    s    generation_prompt_sha256r   action_prompt_sha256sc                 S  r  )c                 S  r  )r   r   r  r  r5   r5   r7   rB    r  r  r5   r  r5   r5   r7   r    r  generation_usager   c                 S  r  )c                 S  s   g | ]
}t |d i qS )r   )_safe_generation_usager   r  r5   r5   r7   rB    r  r  r5   r  r5   r5   r7   r    r  )r   actionstransparency_processingatlas_composed_rgba)appliedr   r   r   r  r  size_proportion_qacandidate_policygeneration_moderd   	selection#deterministic_action_semantic_scorere  r-  semantic_repair_actionsfinal_semantic_repair_actionsfinal_visual_repair_actionssize_proportion_repair_actionsforced_per_frame_actionswalk_loop_modewalk_generated_frames previous_frame_reference_actionsrp  rs  r   r   )r   rq  rr  rg   re   rf   r   r   r@   package/pet.jsonpackage_ref	referencez	hatch-petjob_manifestzimagegen-jobs.jsonpet_requestdeterministic_reviewqa/review.jsonfinal_visual_reviewzqa/final-visual-review.jsoncontact_sheet_pngqa/contact-sheet.pngpreview_dirqa/previewspackage_dirpackagepackage_manifestrepair_modesmallest_failed_action'visual_qa_required_before_user_approvalfinal_visual_review_requiredfinal_visual_review_providerfinal_visual_review_modelcontact_sheet_mediapreview_mediar   hatch_pet_pipelinemanifest.jsonvalidation.json)
r   r,   r   r   r   r-  r  r  r  r  zcontact-sheet.htmlutf-8encodingzframe-qa.jsonr   r   zreview.jsonzrun-summary.json)r   r2   r1   r   )
rD   r-   rE   rF   rC   r   r   r   r1   r   )
rD   r-   rE   rF   rC   rF   r   r2   r1   r   )
rD   r-   rE   rF   rC   rF   r   r-   r1   r2   )rE   rF   rC   rF   r   rH   r1   r2   )
rD   r-   rE   rF   rC   rF   r   r-   r1   r   )rD   r-   r  rH   r  rF   r1   r  )rD   r-   r0  rF   r1   r   )rD   r-   rx  rF   r1   r2   )r1   r   r5   )Rr  r   r   _slugifyr-   r   $_should_load_default_visual_reviewer_default_photo_analyzerr   '_normalize_action_frame_generation_modeosenvironr   r   r8   r   name
_utc_stamprS  rL  rF   r  r   _build_pet_requestrK  rO  rP  r   r   rA   r   rH   setr  $_should_use_action_strips_by_defaultlistr   r   ACTION_STRIP_ATTEMPT_LIMITSMAX_ACTION_STRIP_ATTEMPTS(_visual_review_rejected_generated_actionr  %_action_visual_review_failure_summaryupdater   r  addrJ  r   r  r~   r  r   _failed_semantic_actionsjoinrL   hashlibsha256	hexdigestr   r   )_final_contact_sheet_visual_review_passedr   r   _failed_size_proportion_actionsr   _write_install_package_build_review_build_manifestr  r  _generation_moderU  rG  sortedr    r   _build_validation_build_summary_build_job_manifest
write_text_contact_sheet_html)Jr,   r.   rh   rj   ra   rb   rc   rd   re   rf   rg   ru   rv   default_visual_review_allowedr  r/   r   r  r  r  layout_guide_dircanonical_reference_pathcanonical_png_pathcanonical_transparencyr  r  r  r  r  r   r/  rw  r  r  rD   r  	action_okstrip_attemptmax_strip_attemptsstrip_generatedaction_reviewvisual_rejectedfailure_payloadvisual_summaryrx  r  spritesheet_pathcontact_sheet_pathr  r  r  rO   max_final_visual_attemptsmax_size_proportion_attemptsr  size_attemptfinal_attemptatlasr  failed_final_actionsr  r   review_payloadr  normalized_repair_actionsrepair_actionrepaired_action_reviewsize_repair_actionsr  r  r  manifest
validationsummaryr5   )-r(  ro  r  r)  r   r   r  rc   r*  r+  r@   r   r   rd   r   r   rp  r,  rq  rr  r   r   r   r   rb   r   r   rs  r.   r,   rt  r   r   rt   r   r   r   ru  rv  re   r   r-  r.  r  r  r7   build_pet_package_from_photosw   sz  


"	


M!04 L	   %,6.






$




















	




	


	
&,-./	
IJKM	
r@  r   r   r0   r2   c              	   C  s(   | |dt |ttdddd |D dS )Nraw_pet_photoFc              	   S  s6   g | ]}|d  | d|d |d | dddqS )r  source_mimemime	convertedF)r  rC  prepared_mimerD  r   r  imager5   r5   r7   rB    s    
z&_build_pet_request.<locals>.<listcomp>)r   display_namesource_kindphoto_countstatesmemory_text_storedraw_media_includedinput_media_refs)r   r  r   r   r5   r5   r7   r    s   r  rt   c                 C  s   | dkrt  S t S )Nrr   )r   from_envrP   rw   r5   r5   r7   r  *  s   r  ru   r  rv   c                 C  s   | dkr|sdS | S )Nrr   Tr5   rs   r5   r5   r7   r  0  s   r  r  c                 C  s4   |   }d|v sd|v rdS d|v sd|v rdS dS )Nu   猫catu   狗dogpetlower)r  cleanr5   r5   r7   r_   ;  s   r_   r   r   dict[str, list[dict[str, Any]]]r-  	list[str]r  r  r  r  c        
         C  s  dddg ddd |D | d| dttj d	d
d	g}
tD ]T}| |g }tdd |D }|
	|dt
|tkrAdnddgd| ddddgd| d|dd |D dd |D t||||||	dttj d	d
d q$d| |t
|
|
ddddS )Nr   canonical_basecompleter   c              	   S  s(   g | ]}d |d | d|d dqS )rA  r  rB  rC  )roler  rC  rF  rG  r5   r5   r7   rB  X  s    z'_build_job_manifest.<locals>.<listcomp>r   r`   +00:00Z)	idkindr~  
depends_onr  input_imagesr   r`   completed_atc                 S  s   h | ]}t |d pdqS )r   	per_framer  r  r5   r5   r7   	<setcomp>g  r  z&_build_job_manifest.<locals>.<setcomp>
action_row
incompleter;  z-*.pngcanonical_identity_referencezqa/canonical-reference.png)r[  pathzqa/layout-guides/r   c                 S     g | ]}| d qS r   rF  r  r5   r5   r7   rB  t      c                 S  ri  )r   rF  r  r5   r5   r7   rB  u  rk  rD   r-  r  r  r  r  )r^  r_  r~  r`  r  ra  layout_guidesource_modesrequest_idsprompt_sha256srepair_reasonrb  zhatch_pet_style_photo_worker.v1F)rN  rM  )versionr   rI  	job_countjobsprivacy)r   r   nowr   utc	isoformatreplacer   r  r   r   r   _job_repair_reason)r   r,   r   r   r   r-  r  r  r  r  rt  rD   r  rn  r5   r5   r7   r   D  s`   

r   rD   c                 C  s@   | |v rdS | |v rdS | |v rdS | |v rdS | |v rdS d S )Nfinal_action_semantics_repairr  r  r  forced_per_framer5   rl  r5   r5   r7   rz    s   	rz  r   c                 C  s4   | dkrdS | dkrdS | dkrdS d| v rdS d	S )
Nr   deterministic_motionr   deterministic_motion_fallbackr  action_stripaction_stripsmixedrc  r5   )r   r5   r5   r7   r    s   r  c                 C  s,   t | pd  dd}|dv rdS dS )NrU   r}   _>   rR   r|   canonical_onlycanonical_motionr|   )r-   r  rU  ry  )r  
normalizedr5   r5   r7   r    s   r  c                 C  s   | dvS N>   openaiofficial-openaiopenai-gpt-imager5   rw   r5   r5   r7   r
    s   r
  c                 C  s   | dv S r  r5   rw   r5   r5   r7   rQ    s   rQ  c                 C  s   | dv o|dkS )N>   r  r  r  r   r5   )rt   rD   r5   r5   r7   rH    s   rH  c                 C  s   | dv rdS dS )N>   r  r  r  r(   r*   r5   rw   r5   r5   r7   rM    s   rM  r  c                 C  J   g }|  dg D ]}t| dd}|tv r"| ddur"|| q|S Nr   rD   r   r  Tr   r-   r   r   )r  failedrowrD   r5   r5   r7   r       
r  r  c                 C  r  r  r  )r  r  r  rD   r5   r5   r7   r    r  r  ry  c                   s   t  fdd|dg D d }t|ts,dd|d|dtdd	 d	d	g d
gdS dd |dg D }d }|D ]}t|}|rG|} nq;t|tksYt|dpUd	tkr]|p\d}|d u ||d|dtdt||gdS )Nc                 3  s"    | ]}| d  kr|V  qdS )rD   NrF  rA  r2  r5   r7   r3    s     z*_single_action_frame_qa.<locals>.<genexpr>r   Fmissing_action_row
cell_widthcell_heightr*   r   )rD   input_framesselected_framesr   )r  r  r  r  frames_per_actionaction_countselected_frame_countr   c                 S  s   g | ]	}t |tr|qS r5   )r   r   )r  framer5   r5   r7   rB        z+_single_action_frame_qa.<locals>.<listcomp>r   r  not_enough_frames)nextr   r   r   r   r   r   rF   )rD   ry  r  r   r  r  frame_reasonr5   r2  r7   r    s<    

"r  r   c                 C  s   | r|  ds	dS |  ddu rdS t|  dpd}|dkr!d	S t|  d
p(d}|dk r0dS t|  dp7d}|dkrC|dkrCdS |dk rIdS d S )Nr   missing_frame_foregroundfragmented_foregroundTfragmented_frame_foregroundcomponent_countr      too_many_frame_fragmentsr      weak_frame_foregroundbbox_fill_ratio      ?i gffffff?opaque_background_not_removed)\(?sparse_frame_foreground)r   rF   float)r   r  r   
fill_ratior5   r5   r7   r      s    r   r   c                 C  s   |  ddkr	d S t|  dpd}t|  dpd}t|  dp"d}|dks,|dkr.dS |t|| d k r:d	S t|  d
pAd}|tdt|| d krRdS d S )Nr   explicit_chroma_keywidthr   heighttransparent_pixels chroma_key_background_unverifiedg?r   chroma_residue_pixelsi  g{Gzt?chroma_key_residue_remaining)r   rF   rS  )r   r  r  r  r  r5   r5   r7   r     s   r   rL   rH   r  c                   sN  z	t | \}}}W n
 ty   Y dS w tdt|d   fddt|D }t|dk r0dS dd |D }tt|}tt| | }t|}t| | }	t|}
d}|dkrf||d d	 8 }n|d
k rn|d7 }|	dkr{||	d d 8 }n|	dk r|d7 }|
dk r|d|
 d 8 }n|
dkr|t|
d d d7 }tdtd|S )N        r*   i q c                   s6   g | ]\}\}}}}|  d kr|d kr|||fqS r   r5   )r  r   redgreenbluealphasample_stepr5   r7   rB  *  s
    z2_candidate_visual_detail_score.<locals>.<listcomp>r  c                 S  s(   g | ]\}}}|d  |d  |d  fqS )   r5   r  r  r  r  r5   r5   r7   rB  2  s   ( gffffff?g     V@r  g      (@g{Gz?g      ^@gQ?g      $@i.  g     @i]  g     p@g      Ig     A@)	r   r   rS  r   r  r  r   valuesrL  )rL   _width_heightpixels
foreground	quantizedtotaltop_quantized_ratioexact_countertop_exact_ratiounique_exactr   r5   r  r7   r   #  s>   
r   rG   rE   c             	     s  z	t | \}W n ty   dddg}Y nw t|}|d u r1dddg}d}|\}}td| d  td| d } fddt|D }d}	d}
t||d\}}}}dg|	|
  }t|D ]f}t|d t|| td| }t|D ]O}t d t|  td| }||  |  \}}}}|d	krq|| }|| }d	|  kr|	k rn qd	|  kr|
k rn q||||f|||	 | < qqqt|	|
|S )
Nr*   )r   r   r   r%   r   r   r   r   c                   2   g | ]}t  D ]}|   |  qqS r5   rJ  r  yx
crop_widthleftsource_pixelssource_widthtopr5   r7   rB  Y      z>_deterministic_motion_frame_from_canonical.<locals>.<listcomp>   p   r   r   )	r   r   _foreground_bboxrS  rJ  _deterministic_frame_geometryrL  rF   r   )rG   rD   rE   source_heightbboxrightbottomcrop_heightcropcanvas_widthcanvas_heighttarget_widthtarget_heightx0y0canvasr  source_yr  source_xr  r  r  r  dest_xdest_yr5   r  r7   r   L  sB     0	r   source_image_bytesc                  s  z	t | \}W n ty   |  Y S w t|}|d u r!| S |\}}td| d  td| d } fddt|D }|t }g d}	g d}
|	|t|	  }tdtt | }tdt|t|| }t	| |||}| d }|}t||d  }t|| d |
|t|
   }tdt| |}tdt|| |}dg|  }t|D ]$}t|D ]}||| |  }|d	 dkrq||||  | | < qqt
||S )
Nr*   c                   r  r5   r  r  r  r5   r7   rB  |  r  z9_direction_locked_sleep_variant_frame.<locals>.<listcomp>)r  gGz?gHzG?g\(\?)r   r&   r  r*   r&   r   r  r(   )r   r   r  rS  rJ  r   r   rL  round_resize_nearestr   )r  rE   r  r  r  r  r  r  variantscale_by_framevertical_breath_by_framescaler  r  resizedcenter_xbottom_anchortarget_left
target_topr  r  r  pixelr5   r  r7   r   p  sH    r   r  list[tuple[int, int, int, int]]r  r  r  r  c           
      C  s   ||kr||krt | S g }t|D ].}t|d t|| | }t|D ]}t|d t|| | }	|| || |	   q%q|S )Nr*   )r  rJ  rL  rF   r   )
r  r  r  r  r  outputr  r  r  r  r5   r5   r7   r    s   r   tuple[int, int, int, int] | Nonec           
      C  sp   g }g }t | D ]\}\}}}}	|	dkrq|||  |||  q|r(|s*d S t|t|t|t|fS )Nr   )r  r   rL  rS  )
r  r  r  xsysr   _red_green_bluer  r5   r5   r7   r    s   r  tuple[int, int, int, int]c                 C  sD  |t  }| dkr g d}g d}g d}|| || || dfS | dkr<g d}g d}g d	}|| || || d
fS | dkrXg d}g d}g d}|| || || dfS | dkrrg d}g d}|| || d|d  dfS | dkrg d}g d}|| || d|d  dfS g d}g d}|| || d|d  dfS )Nr   )`   t   r  r   )"   r  r     )   r  r     :   r)   )d   r   r  r   ),   $   r  r	  )r     r  r
  r  r$   )N   j   R   n   )r  2   r  r  )   r  r  r  r  r!   )H   L   r  r  )T   P   r  r      r&   r
  r#   )r  r  r  r  )J   r  r  r  r  r  )r  r  r  V   )r  r  r  r  r  r(   r   )rD   rE   r   widthsheightsoffsetsr5   r5   r7   r    s6   r  frame_imageslist[bytes]c                 C  s4  g }t | D ]\}}t|}||d< || qdd |D }t|dk r,dg g |dS tdd |D }tdd |D }g }|D ]B}	tt|	d	 | }
t|	d
 }t|
d|	d< t|| d|	d< |
dkrr|t|	d  qB|t	d|d kr|t|	d  qB| |sg ndg|t|dt|d|dS )Nr  c                 S  s   g | ]	}| d r|qS )r  rF  rA  r5   r5   r7   rB    r  z6_evaluate_action_style_consistency.<locals>.<listcomp>r&   T)r  r  
bad_framesr   c                 S  r@  )	blue_biasr  rA  r5   r5   r7   rB    rC  c                 S  r@  )
dark_ratior   rA  r5   r5   r7   rB    rC  r  r!     blue_bias_deltadark_ratio_deltag      0@g)\(?g
ףp=
?frame_style_outlier)r  r  r  median_blue_biasmedian_dark_ratior   )
r  _frame_style_signaturer   r   _median_floatabsr  r  rF   rS  )r  
signaturesrE   rL   	signaturevalidr&  r'  r  r>  r#  r!  r5   r5   r7   r    s@   r  c           
      C  s   z	t | \}}}W n ty   ddd Y S w dd |D }t|dk r*dddS tt|}tdd	 |D | }td
d	 |D | }tdd	 |D | }tdd	 |D | }	dt|t|dt|dt|dgt||| d  dt|	ddS )NFunreadable_png)r  r   c                 S  s&   g | ]\}}}}|d kr|||fqS r  r5   )r  r  r  r  r  r5   r5   r7   rB    s   & z*_frame_style_signature.<locals>.<listcomp>r  not_enough_foregroundc                 s      | ]}|d  V  qdS r1  r5   r  r  r5   r5   r7   r3  	      z)_frame_style_signature.<locals>.<genexpr>c                 s  r0  )r*   Nr5   r1  r5   r5   r7   r3  
  r2  c                 s  r0  )r&   Nr5   r1  r5   r5   r7   r3    r2  c                 s  s*    | ]\}}}|| | d k rdV  qdS )r   r*   Nr5   r  r5   r5   r7   r3    s   ( Tr(   r&   r"  )r  r   mean_rgbr  r!  )r   r   r   r  sumr  )
rL   r  r  r  r  countmean_red
mean_green	mean_bluer!  r5   r5   r7   r(     s&   
r(  r  list[float]c                 C  sH   | sdS t | }t|d }t|d r|| S ||d  ||  d S )Nr  r&   r*   )r  r   )r  orderedmidpointr5   r5   r7   r)    s   r)  c              	   C  s>   |  d|  d|  d|  d|  d|  d|  ddS )	Nr   r  r  r  r  r   r   )r   r  r  r  r  r   r   rF  )r   r5   r5   r7   r      s   r   c                 C  s&   |  d|  d|  d|  ddS )Nr  r   r   r  )r  r   r   r  rF  )r   r5   r5   r7   r   ,  s
   r   r   r2  r  c                C  s   t | tr
| dnd }t |tsdS |d}|dd}|dd}|dkr8|ddur8|d	dur8dS |du oJ|duoJ|duoJt||d
 S )Nr  Fr{  r(  Tr  r)   gait_cycle_oktwo_frame_loop_okrD   r  )r   r   r   !_visual_review_notes_block_action)r  rD   r  r{  r(  r  r5   r5   r7   r  5  s   

$r  r   r   c                   s4   t | ttfs	dS t|   t fdddD S )NFc                 3      | ]}| v V  qd S r4   r5   r  markertextr5   r7   r3  J  
    
z,_provider_request_blocked.<locals>.<genexpr>)	arrearagezaccount is in good standingzaccess deniedzoverdue-paymentzinsufficient balance)r   r   r   r-   rU  rI  r   r5   rC  r7   r   F  s   r   c                   sB   t | rdS t| tttfsdS t|   t fdddD S )NFc                 3  r@  r4   r5   rA  rC  r5   r7   r3  \  rE  z._provider_request_transient.<locals>.<genexpr>)z	timed outtimeoutzpolling failedzbefore receiving a responsezremote end closed connectionztemporarily unavailablezconnection resetzconnection aborted)r   r   r   r   r   r-   rU  rI  rG  r5   rC  r7   rR  V  s   rR  r   c                 C  sd   t | tr
| dnd }t |tsdS |ddu o1|ddduo1|ddduo1|ddduS )Nr  Fr{  Tr  r  r  )r   r   r   )r  r  r5   r5   r7   r  k  s   
r  r,  c                C  s   |  d}t|tr| ddkrdS | d}t|tsdS | ddu pK| ddu pK| ddu pK|d	koE| d
duoE| ddupKt||dS )Nr  r~  r  Fr  r{  r(  r  r)   r<  Tr=  r>  )r   r   r   r?  )r,  rD   r  r  r5   r5   r7   r  w  s   


"
r  c                 C  s   |  d}t|tsi S | d}t|tsi S | dg }| d| d| d| d| d| d	| d
| d| dt| dpIdd d t|tr`dd |d d D dS g dS )Nr  r  r|  r   r{  r(  r  r<  r=  front_paw_sequencehind_paw_sequencer  r.   r      c                 S  s   g | ]
}t |d d qS )Nr   )r-   rA  r5   r5   r7   rB    r  z9_action_visual_review_failure_summary.<locals>.<listcomp>r  )visual_review_scorevisual_review_passedvisual_review_action_okvisual_review_identity_okvisual_review_gait_cycle_okvisual_review_two_frame_loop_ok visual_review_front_paw_sequencevisual_review_hind_paw_sequencevisual_review_bad_framesvisual_review_notesvisual_review_risks)r   r   r   r-   r  )r,  r  r  r|  r5   r5   r7   r    s*   



r  r  c                   s   t |dpd }ddd |dg D }| d|  | dkr@d}t fd	d|D r3d
S d}t fdd|D S d
S )Nr.   r   rS   c                 s  s$    | ]}|d urt | V  qd S r4   )r-   rU  rA  r5   r5   r7   r3       " z4_visual_review_notes_block_action.<locals>.<genexpr>r|  r!   )zno standingzwithout standingznot standingzno transitionc                 3  r@  r4   r5   )r  negationrC  r5   r7   r3    r2  F)zone standing framezstanding frame includedzstanding poseznot sittingz
not seatedzfrom standingztransition logicc                 3  r@  r4   r5   )r  blockerrC  r5   r7   r3    r2  )r-   r   rU  r  rI  )rD   r  r.   r|  safe_negationsblockersr5   rC  r7   r?    s   	r?  c              	   C  s   g }|  ddur|d|  dpdd | dg D ]}| ddu r&q|d| d	| d
g d q| dd||  ddu | ddu dS )Nr  Tr   r  frame_review_failed)scoper   r   action_semanticsrD   reasons)r]  rD   r_  $deterministic_hatch_pet_style_review)r  r_  r  errorsframe_qa_okaction_semantic_qa_ok)r   r   )ry  r  ra  r  r5   r5   r7   r    s.   
r  r  r  c              
   C  sh   | d }|j ddd |d | ||ddddd ttD d	d
d	dd}t|d | ddddS )Nr  Tr   r  u3   纪念桌宠动作包，需用户确认后安装。0.1.0c                 S  s   i | ]\}}||t d dqS )low_disturbance)r  r   moder  )r  r   rD   r5   r5   r7   r    s    z*_write_install_package.<locals>.<dictcomp>Fprivate_generated)fixtureKindsensitiveContentStored)r^  displayNamedescriptionruntimeVersionspritesheetPath
animationsuserApprovedr   zpet.jsonr  zpackage/spritesheet.png)rh  spritesheetformat)r  r   r  r   r   )r  r   r,   r  r  r  r5   r5   r7   r    s*   r  rh  c                 C  sZ   |   std| j }|dkrdn|dkrdnd}|  }| j|| |t| dS )Nzphoto file does not existr   r   z.webp
image/webp
image/jpeg)r  rC  rh  rH   r  )	rK  r   suffixrU  rO  r  r  r  r  )rh  rt  rC  rL   r5   r5   r7   _read_image_ref  s   
ru  rH  c                 C  s0   t | dd }|dkrdS |dkrdS dS )NrC  r   rr  spritesheet.webpr   r  spritesheet.jpg)r-   r   rU  )rH  rC  r5   r5   r7   _spritesheet_filename	  s   rx  rM   c                 C  s$   |   }|dkr
dS |dkrdS dS )Nrr  rv  rs  rw  r  rT  )rM   rC  r5   r5   r7   _generated_spritesheet_filename
	  s   ry  r  r  r  r  r  r  r  r  r  dict[str, list[str]]r  dict[str, list[list[str]]]r  r  r  r  r  r@   c                 C  s   ||| |dddddd t D |d|ttj ddd	i d
dddddddd|d|d|d|	d|
d|
d|d|d|d|ddd|d|||||d d |D ||d	d	t|d!d"d d# |d$d%d&S )'Nrd        c                 S  s   g | ]}|t d dqS )re  )r  r   rf  r  r  stater5   r5   r7   rB  7	  s    
z#_build_manifest.<locals>.<listcomp>r  r\  r]  Fr_  photo_to_image_worker
input_kindrA  asset_style"high_fidelity_reference_preservinggenerator_versionz)photo_generation_worker.image_provider.v3r   r  r  r  image_request_idr  r  r  r  r  generation_sizer>   r  r  c              
   S  s>   g | ]}|d  | d|d |d | d| dddqS )r  rB  rC  prepared_sha256rD  F)r  rC  rE  r  rD  rF  rG  r5   r5   r7   rB  V	  s    
r^   r      r\   )ry  r  r  r  rO  output_asset_refoutput_mimerN  memory_text_includedanalysis_summaryanalysis_confidence)r  r  r   rI  runtime_versionschema_versionr  r  rL  r0  checksum_algorithmr  
created_atuser_approvedr   )	r   r   rv  r   rw  rx  ry  r-   r   )r   r,   r  r  r  r  r   r  r  r  r  r  r  r  r  r  r  ry  r  r  r  r   rM   r@   r5   r5   r7   r  	  s   	

r  r   c                 C  s   |  dg D ]@}t| dd}| |g }| dg D ])}t| dd}|t|kr-q|| }t| dd|d< t| dd	|d< qqd S )
Nr   rD   r   r   r  r   r  r  r  )r   r-   rF   r   r  )ry  r   r  rD   selected_payloadsr  rE   r  r5   r5   r7   r  j	  s   r  c                 C  sL   |  dg D ]}| ddkr#t|d< t|d< dd tttD |d< qd S )	Nr   rD   r)   	loop_moderW  c                 S  s   g | ]	}||t  d qS ))r  derived_from_frame)rG  )r  rE   r5   r5   r7   rB  |	  r  z,_annotate_walk_loop_mode.<locals>.<listcomp>derived_frames)r   rU  rG  rJ  r   )ry  r  r5   r5   r7   r  w	  s   
r  source_payloadr   rD  c                C  s   t | dd}t| }d|pd|  |d< t|d< ||d< ||d< t| dd	|d< t| d
d|d
< t| dd|d< t| dd|d< t| dtr\t| di ni }d|d< d	|d< ||d< |S )Nr   r   zderived-copy-of:zwalk-r   rE  copied_to_frame_indexr  r   r  r  r   r   r   Tderived_copyr   )r-   r   r   rU  rF   r  r   )r  r   rD  source_request_idcopiedr   r5   r5   r7   rT  	  s   $rT  r   rU   r`   c                 C  sD   |d u rdn|  d| }d||d| ddddd	dd
d
d
ddS )Nr   r}   r  zresumed-existing:r   Tr   )resumed_existingr   r   r  r  )r~  rU   r`   r   rM   r   r   r  r  r   r   r   r5   )rD   rE   rU   r`   rt  r5   r5   r7   rP  	  s    rP  r=  c                 C  sJ  | d  d}| d  di }t| d}ddt| d dkdd	 | d
 D ttk|dv t| d  do?t| d  d| d  di  ddu | d  di  ddu | d  di  ddu | d  di  ddu t| dot| dot| d| pt| d|  ddk| d du dd}t| |d dS )Nr   r  r  r  Tr  @   c                 S  s   g | ]}|d  qS )r  r5   r~  r5   r5   r7   rB  	  s    z%_build_validation.<locals>.<listcomp>rL  >   r  r  r  r  r   ry  r  r  r  r  r  r  r  r  r  r  F)manifest_completespritesheet_existschecksum_sha256states_allowedhigh_fidelity_assetimage_generation_trackedalpha_capable_assetframe_qa_passedaction_semantics_passedsize_proportion_qa_passed hatch_pet_review_artifacts_readyfinal_visual_qa_passedpackage_manifest_writtenuser_approval_requiredno_sensitive_payloads)r  checksr  )r   r  r   r  r   allr  )r=  r  hatch_pipelinefinal_visual_qa_requiredr  r5   r5   r7   r  	  s4   
r  c                 C  s<  i ddd| d d| d d| d d| dd| d	| d
| d| d| dd| dddd| d  dpD| dpDd| d| d  d| ddd | D d| d  di dd| d  di d| d  di d| d  di d d!d"| d# d$d%d&d'd(d)d*d+d,d-d.|  d/S )0Nr  Tr  r  r   photo_analysisrU   externalrV   rW   rX   r\   r]   r^   r   )rU   rV   rW   rX   r\   r]   r?  image_generationr   r  rT   r`   r   r   c                 S  r  )c                 S  ri  rj  rF  r  r5   r5   r7   rB  	  rk  z-_build_summary.<locals>.<dictcomp>.<listcomp>r5   r  r5   r5   r7   r  	  r  z"_build_summary.<locals>.<dictcomp>r   r  )rU   r`   r   r  r  r  r   ry  r  r  r=  r  rp  r0  r>  r  contact_sheetr  contact_sheet_htmlzqa/contact-sheet.htmlr  r  r  r  r  r  )r   r  )r=  r@   r   r   r5   r5   r7   r  	  sp   


 !"#$%
&r  c                 C  sL   d dd | d D }d| d  d| d  d| d	  d
| d  d| dS )N
c                 s  s4    | ]}d |d  d|d  d|d  dV  qdS )z<li><strong>r  z</strong><span>r   u    frames · rf  z</span></li>Nr5   r~  r5   r5   r7   r3  
  s
    "
z&_contact_sheet_html.<locals>.<genexpr>rL  zD<!doctype html>
<html lang="zh-CN">
<meta charset="utf-8" />
<title>rI  a   photo worker QA</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", sans-serif; background: #fbf7f0; color: #2e2a26; }
main { max-width: 880px; margin: 32px auto; padding: 24px; background: #fff; border-radius: 18px; }
img { width: 256px; height: 256px; object-fit: none; object-position: left top; }
li { margin: 8px 0; display: flex; gap: 12px; }
</style>
<main>
<h1>u    照片生成 worker QA</h1>
<p>本页展示从授权照片经本地素材检查和配置的图片生成 provider 产出的 P0 高还原桌宠包证据。</p>
<img src="../r0  z" alt="z+ generated spritesheet first frame" />
<ul>z</ul>
</main>
</html>
)r  )r=  r   r5   r5   r7   r"  
  s   
r"  r	   c                 C  sV   t | tsi S i }|  D ]\}}t |ttttfs|d u r(||t|d d < q|S )Nr  )r   r   r  r-   rF   r  r  )r  safer  r>  r5   r5   r7   r  
  s   
r  c                 C  s6   d dd |  D }d dd |dD pdS )Nr   c                 s  s$    | ]}|  r| nd V  qdS )r}   N)isalnumrU  )r  chr5   r5   r7   r3  %
  rW  z_slugify.<locals>.<genexpr>r}   c                 s  s    | ]}|r|V  qd S r4   r5   )r  partr5   r5   r7   r3  &
  r2  rS  )r  r  split)r  cleanedr5   r5   r7   r   $
  s   r   c                   C  s   t tjdS )Nz%Y%m%d%H%M%S)r   rv  r   rw  strftimer5   r5   r5   r7   r  )
  s   r  c                 C  s"   | j tj|dddd dd d S )NFr&   )ensure_asciiindentr  r  r  )r!  jsondumps)rh  r  r5   r5   r7   r   -
  s   "r   )r,   r-   r.   r-   rh   ri   rj   rk   ra   rl   rb   rm   rc   rn   rd   rF   re   ro   rf   rp   rg   rq   r1   r   )r   r-   r,   r-   r   r0   r1   r2   )rt   r-   r1   r+   )rt   r-   ru   r  rv   r  r1   r  )r  r-   r1   r-   )r   r-   r,   r-   r   r0   r   r2   r   rW  r-  rX  r  rX  r  rX  r  rX  r  rX  r1   r2   )rD   r-   r-  rX  r  rX  r  rX  r  rX  r  rX  r1   rq   )r   r-   r1   r-   )r  rq   r1   r-   )rt   r-   r1   r  )rt   r-   rD   r-   r1   r  )rt   r-   r1   rF   )r  r2   r1   rX  )r  r2   r1   rX  )rD   r-   ry  r2   r1   r2   )r   r2   r1   rq   )r   r2   r1   rq   )rL   rH   r1   r  )rG   rH   rD   r-   rE   rF   r1   rH   )r  rH   rE   rF   r1   rH   )r  r  r  rF   r  rF   r  rF   r  rF   r1   r  )r  r  r  rF   r  rF   r1   r  )rD   r-   rE   rF   r1   r  )r  r  r1   r2   )rL   rH   r1   r2   )r  r9  r1   r  )r   r2   r1   r2   )r   r2   r1   r2   )r  r2   rD   r-   r1   r  )r   r   r1   r  )r  r   r1   r  )r,  r2   rD   r-   r1   r  )r,  r2   r1   r2   )rD   r-   r  r2   r1   r  )ry  r2   r  r2   r1   r2   )
r  r   r   r-   r,   r-   r  rH   r1   r2   )rh  r   r1   r2   )rH  r2   r1   r-   )rM   r-   r1   r-   )2r   r-   r,   r-   r  r-   r  r-   r  r-   r  r-   r   r0   r  rq   r  r-   r  r-   r  r-   r  rz  r  r{  r  r-   r  rz  r  r2   r  r2   ry  r2   r  r2   r  r2   r  r2   r   r-   rM   r-   r@   r2   r1   r2   )ry  r2   r   rW  r1   r   )ry  r2   r1   r   )r  r2   r   rF   rD  rF   r1   r2   )
rD   r-   rE   r   rU   r-   r`   r-   r1   r2   )r=  r2   r1   r2   )
r=  r2   r@   r2   r   r2   r   rW  r1   r2   )r=  r2   r1   r-   )r  r	   r1   r2   )r1   r-   )rh  r   r  r2   r1   r   )u
__future__r   r  r  r  concurrent.futuresr   r   collectionsr   r   r   pathlibr   typingr	   r
    services.ai.apimart_image_clientr   services.ai.openai_image_clientr   services.ai.qwen_clientr   r   services.ai.model_routerr   r   $services.media_pipeline.photo_inputsr   (services.media_pipeline.png_transparencyr   %services.pet_builder.action_semanticsr   r   !services.pet_builder.action_atlasr   r   r   r   r   "services.pet_builder.layout_guidesr   services.pet_builder.qa_mediar   r   'services.pet_builder.size_proportion_qar   packages.pet_package_schemar   r	  FORCED_PER_FRAME_ACTIONSr    __annotations__r   r   r   rG  rU  r  r  r+   r=   rK   rP   r@  r  r  r  r_   r   rz  r  r  r
  rQ  rH  rM  r  r  r  r   r   r   r   r   r  r  r  r  r(  r)  r   r   r  r   rR  r  r  r  r?  r  r  ru  rx  ry  r  r  r  rT  rP  r  r  r"  r  r   r  r   r5   r5   r5   r7   <module>   s               
$

	J		")$+$
	"		W0
