
    -ǚj)                    $   d Z 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	m
Z
 ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZmZmZm Z  ddl!m"Z" ddl#m$Z$  ejJ                  e&      Z'ddZ(ddZ) G d d      Z*y)u  ReferencePhase2Service — Phase 2 (standalone outfit reference) 단독 서비스.

F24.4.3 (2026-04-24): `ReferencePipelineOrchestrator.run()`의 Phase 2 블록
(character_outlook 기반 outfit 단독 이미지 병렬 생성)을 literal lift.

ctx.outlook_generated / ctx.outlook_skipped를 in-place 업데이트한다.
외부 예외는 원본과 동일하게 내부에서 log + swallow — run()은 None 반환.
    )annotationsN)ThreadPoolExecutoras_completed)datetimetimezone)Path)Dict)Session)settings)to_relative_image_path)annotate_generated_asset)bind_current_budget)ActivityLogger)CharacterOutlookEntityCanon
ImageAssetProjectSettings)load_project_llm_config)ReferencePipelineContextc                 d    t        j                  t        j                        j	                         S N)r   nowr   utc	isoformat     [/Users/manta/Documents/Projects/TheRoad-I1/backend/app/services/reference_phase2_service.py_nowr   !   s    <<%//11r   c                 <    t        t        j                               S r   )struuiduuid4r   r   r   _new_idr#   %   s    tzz|r   c                  >    e Zd ZdZ	 	 	 	 	 	 	 	 	 	 ddZdddZd	dZy)
ReferencePhase2ServiceuK   Phase 2: character_outlook 기반 outfit 단독 reference 이미지 생성.c                <    || _         || _        || _        || _        y r   )_db_project_id	_actor_id_logger)selfdb
project_idactor_idactivity_loggers        r   __init__zReferencePhase2Service.__init__,   s!     %!&r   Nc           	        | j                   j                  t              j                  t        j                  | j
                  k(        j                         }|rg|j                  r[t        j                  |j                        }d|j                  dd       d|j                  dd       d|j                  dd       dS |rt        t        j                        | j
                  z  d	z  d
z  |z  dz  dz  }|j                         rft        j                  |j                  d            j                  di       }|j                  dd      }|j                  dd      }|s|r	d| d| dS y)up   프로젝트 세계관을 T2I 프롬프트 앞에 붙일 컨텍스트로 변환 (orchestrator와 동일 로직).z)Photorealistic cinematic still. Setting: era z, regionz	. Avoid: 
must_avoid.checkpointsepisodesvisual_world_ruleszmanifest.jsonzutf-8)encodingdatazPhotorealistic cinematic still.)r'   queryr   filterr-   r(   firststyle_rules_jsonjsonloadsgetr   r   projects_direxists	read_text)r+   
episode_idpssrcpvwrr2   r4   s           r   _get_style_contextz)ReferencePhase2Service._get_style_context8   sa   XX^^O,33&&$*:*::<<AEG 	"%%B//0BFF5,-Rx0C/D E&&b12!5 X**+d.>.>> ",-/9:&')89 
 yy{jjw!?@DDVRPggeR(2.&Fse2fXUVWW0r   c                    ! ddl m  |j                  |j                  }|j                  |j
                  !|j                  }	 ddlm}  | j                   j                        }g }t               }|D ]  } j                  j                  t              j                  t        j                   j                  k(  t        j                   |j"                  k(  t        j$                  dk(  t        j&                  dk(        j)                         }	|	r9t+        |	j,                        j/                         r|xj0                  dz  c_        ։ j                  j                  t2              j                  t2        j4                  |j"                  k(        j)                         }
|
s1|
j6                  dk(  r|xj0                  dz  c_        W|j8                  |v r|xj0                  dz  c_        ||
j:                  xs |
j<                  }|j"                  |v r|xj0                  dz  c_        |j?                  |j"                         |jA                  |
j<                  ||j"                  d        |rtB        jE                  dtG        |             i  jI                        }tK         j                   j                        }|D ]  } j                  j                  t2              j                  t2        j4                  |d	   k(        j)                         }|r|jL                  r|jL                  |d	   <   tdd
l'm(} 	  |ddd| d|d    |      jS                         }||d	   <   |s||d   k7  s||_&          j                  jW                           ! fd}tY        t[        |tG        |                  5 }t]        |      }|D ci c]  }|j_                  ||      | }}ta        |      D ]$  }||   }	 |jc                         \  }}t        te                j                  d|d	   tg        |d         d|d	    d|d   d d  |d   dti        jj                  |jm                  di       d      |jm                  di       jm                  d      dto                     } j                  j?                  |       tq        |dg         j                  jW                          |xjr                  dz  c_9        tB        jE                  d |d!          ' 	 d d d        y y # tT        $ r	 |d   }Y w xY wc c}w # tT        $ r%}tB        ju                  d"|d!   |       Y d }~vd }~ww xY w# 1 sw Y   y xY w# tT        $ r }tB        ju                  d#|       Y d }~y d }~ww xY w)$Nr   )generate_and_validate_reference)episode_outlook_rows	reference   O00)outlook_nameoutlook_desc
outlook_idz1Generating %d standalone outfit images (parallel)rT   )	call_textprompt_translationzTranslate the Korean costume description to English for image generation. Include the era/setting context. Output ONLY the English description.u   세계관: u
   

의상: rS   )stepsystem_promptuser_promptproject_configc                    ddl m} j                  | d   | d         } |d|      }|r|n|} 	| d   | d   d|
d dj                  d	| d   d
	      }| |fS )Nr   )_load_ref_image_promptrT   rS   outlook)outlook_descriptionrR   r3   ref_image_gen_phase2_outlook)r-   rF   operation_type	entity_id)	gemini_cliententity_nameentity_descriptionentity_type
t2i_prompt
output_dirextra_referencesstyle_context
trace_meta)'app.modules.pipeline.ref_image_pipeliner\   rB   r(   )taskr\   eng_desc
ref_promptcurrent_promptpipe_result_outlook_t2i_cacherF   rb   rM   reference_dirr+   s         r   _gen_outfitz/ReferencePhase2Service.run.<locals>._gen_outfit   s    ^155d<6H$~J^_H!7	,4"6J3=Z8N"A&3$($8+/+?$-#1#0)-&( +/*:*:*4.L)-l);	$#K"  ,,r   )max_workers	file_pathz[outfit:z]    generation_model	generated
validationF)ensure_asciiscore)idr-   
asset_typera   rF   ru   prompt_usedrw   statusreview_notesvalidation_score
is_primary
created_atreference_outlook)pipeline_roleinput_image_idszStandalone outfit generated: %srR   z#Outfit generation failed for %s: %sz&Outfit standalone generation error: %s);rk   rM   rF   low_freq_skip_idsrb   rr   max_concurrentapp.core.entity_identityrN   r'   r(   setr<   r   r=   r-   ra   rT   r}   r   r>   r   ru   rD   outlook_skippedr   r|   short_idcharacter_iddescriptionnameaddappendloggerinfolenrK   r   rf   app.modules.llm.llm_clientrU   strip	Exceptioncommitr   minr   submitr   resultr#   r   r@   dumpsrB   r   r   outlook_generatedwarning)"r+   ctx_low_freq_skip_idsr   rN   char_outlooksoutlook_tasksseen_outlook_idscoexisting_compositeoutlook_entityrS   
_style_ctx_proj_configotaskoerU   engrs   executor_submit_gen_outfittfuturesfuturerl   _rp   outfit_assetexcrq   rF   rb   rM   rr   s"   `                            @@@@@r   runzReferencePhase2Service.runS   s9   [ ^^
 22))))++I	JE0$**J8M M"u#HHNN:.V"--1A1AA",,="--<"--2	 UW # &$/A/K/K*L*S*S*U''1,'!%!<!C!CKNNVXVcVcDc!d!j!j!l%!**e3''1,'??&88''1,'-99P^=P=P==$44''1,' $$R]]3$$$2$7$7$0"$--& E $P OQTUbQcd57"!44Z@
6txxAQAQR*E4;;KNNeT`Na<abhhjBbmmBD--*5+>?H8"+%9 /@.9*\RWXfRgQh,i/;	#
 $eg   CF*5+>?#~)>">,/BM# +$ !- -2 (CMHZ4[\`h *=[)I&R_`R_Qx/A1EqHR_G`".w"7&vF-3]]_NA{+5#*9+/+;+;+6*.|*<+5*@[AY*Z.6tL7I6J"TR`MabfcfMgLh,i1<=O1P'2-1ZZVX8Yhm-n1<r1R1V1VW^1_+,+/6,L !HHLL64 ,<Oac !HHOO-11Q61"KK(I4P^K_`5 #8 ]\g &  ) 8"'"7C8H a8  ) F"NN+P+/+?F FFA ]\H  	JNNCSII	Js   
LV #T=3
V >V AV V#U=VDU/V3V =UV UV V	V V :V VVVV V 	V=V88V=)
r,   
OrmSessionr-   r    r.   r    r/   r   returnNoner   )rF   r    r   r    )r   r   r   r   )__name__
__module____qualname____doc__r0   rK   r   r   r   r   r%   r%   )   sF    U
'
' 
' 	
'
 (
' 

'16SJr   r%   )r   r    )+r   
__future__r   r@   loggingr!   concurrent.futuresr   r   r   r   pathlibr   typingr	   sqlalchemy.ormr
   r   app.core.configr   app.core.file_pathsr   #app.services.image_capture.annotater   app.core.image_call_budgetr   app.logging.activity_loggerr   app.models.projectr   r   r   r   "app.services.image_service_helpersr   'app.services.reference_pipeline_contextr   	getLoggerr   r   r   r#   r%   r   r   r   <module>r      sl    #    ? '   0 $ 6 H : 6 Y Y F L			8	$2}J }Jr   