
    Ei8                         d Z ddlZddlmZmZ ddlmZmZmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZmZ  ej$                  e      Zd	Z G d
 de      Zy)u  location_consistency StepRunner — 씬 간 location 외형 고정 문장 추출.

scene 이미지 생성은 현재 location 참조 이미지를 주입하지 않으므로,
scene_detail이 t2i_prompt에 쓰는 `[L##: 설명]` 블록이 유일한 location 시각 정보다.
이 step은 각 L##의 "씬 간 동일해야 할 외형 문장"을 미리 확정하여
scene_detail이 그대로 삽입하도록 강제한다. 환경 상태(날씨/시간/조명)는 제외.
    N)ThreadPoolExecutoras_completed)AnyDictList)AppError)
StepRunner)call_structured)load_promptload_schema   c                   x    e Zd ZdZdefdZddeeef   fdZde	deee	f   deee
e   f   d	e
e	   d
ede	de	fdZy)LocationConsistencyStepuF   Location별 씬 간 고정 외형 문장 추출 (scene_detail 직전).step_idc                     dd l }ddlm} ddlm}  ||j
                        | j                  z  dz  dz  | j                  z  |z  dz  }|j                         r!|j                  |j                  d            S y )	Nr   )Path)settingscheckpointsepisodeszmanifest.jsonzutf-8)encoding)jsonpathlibr   app.core.configr   projects_dir
project_id
episode_idexistsloads	read_text)selfr   _json_Path	_settingscps         ^/Users/manta/Documents/Projects/TheRoad-I1/backend/app/core/steps/location_consistency_step.py_load_prev_checkpointz-LocationConsistencyStep._load_prev_checkpoint   s    )9 )(()oo -.0:;oo '(*9: 	
 99;;;r||W|=>>    returnc                 	   | j                  d      }|r|j                  d      st        ddd      | j                  d      }i }|r*|j                  d      r|d   j                  di       xs i }| j                  d	      }g }|r*|j                  d      r|d   j                  d
g       xs g }|d   j                  dg       xs g }|st        j	                  d       ddddg idS i }| j                  d      }	i }
|	r[|	j                  di       j                  d      r:|	d   d   D ]/  }|j                  d      }||j                  dg       xs g |
|<   1 |D ]  }|j                  dd      }|j                  dd      }|s*g ||<   |
r2|
j                         D ]  \  }}||v s||   j                  |         nZ|rXt        |      dk\  rJ|D ]E  }|j                  d      }||j                  dd      xs d}||v s2||   j                  |       G ||   j                           t        dd      }t        dd      }| j                  d      }i }|dk(  r|r|j                  di       j                  d      r|d   d   D ]V  }|j                  d      }|s|j                  dd      xs d}|s0|j                  dd      j                  d      rR|||<   X |rt        j	                  d t        |             g }d}d}g }|D ]A  }|j                  dd      }|s||v r|j                  ||          1|j                  |       C |rt        t        !      5 }|D ci c]$  }|j                  | j                  ||||||      |& }}t!        |      D ]u  }||   } 	 |j#                         }!|!s|j                  |!       |!j                  dd      xs d}#|#j                  d      r|d&z  }Z|!j                  d      r|d&z  }q|d&z  }w 	 d d d        |j                  d' (       ||z   t        |      z   }$t        j	                  d)||t        |      |$       |t        |      z   |$|d|idS c c}w # t$        $ r\}"t        j'                  d"| j                  dd#      |"       | j                  dd      | j                  dd      dd$|" d%}!Y d }"~"(d }"~"ww xY w# 1 sw Y   xY w)*Nentity_mergedatazstep.no_inputu   entity_merge 결과 없음i  )codemessagestatus_codeentity_detailentity_details
scene_savesegments	locationsuD   location_consistency: no locations in entity_merge — nothing to dor   )completed_countapplicable_countfailed_countr+   scene_directorscenesscene_indexpresent_entity_idsshort_id name   headinglocation_consistencysystemlocation_schemaresumelocation_idfixed_visual_descriptionanalysis_summaryu   실패z@location_consistency resume: %d locations already done, skipping)max_workersz)location_consistency %s future raised: %s?u   실패 — future 예외: rD   r=   rE   rF      c                 &    | j                  dd      S )NrD   r<   )get)rs    r%   <lambda>z2LocationConsistencyStep._execute.<locals>.<lambda>   s    AEE-,Dr'   )keyzClocation_consistency: %d processed, %d failed, %d cached (total=%d))r&   rL   r   loggerinfoitemsappendlensortr   r   
startswithr   MAX_WORKERSsubmit_process_locationr   result	Exceptionerror)%r    modeentity_merge_cpentity_detail_cpr0   scene_save_cpr2   merge_locationsscenes_by_locationdirector_cpid_baseddssilocsidr=   presentsegr?   system_promptschemaexisting_cpexisting_okliddesclocation_results	processedfailed
to_processpoolfuturesfutorig_locrZ   fut_excsummarytotals%                                        r%   _executez LocationConsistencyStep._execute'   ss   44^Do&9&9&&A$4   55oF 0 4 4V <-f599:JBOUSUN22<@!]..v6$V,00R@FBH *&155k2FL"KK^_#$$% !$b)	  46001AB)+;??626::8D!&)(3VVM*>#%66*>#C#IrHRL 4
 #C''*b)C7762&D&(s##+>>#3KBg~*3/66r: $4 #d)q.#C/Bz !ggi4:G w*3/66r: $ s#((*/ #4 $$:HE35FG 001GH')80K0O0OP[0\"6*;7ggm,ww92>D"(:B ? J J8 T'*K$ 8 V$ (*	!#
"C''*b)Ck! ''C(89c" # #<  *  * KK..^-?%v 	
  *   (0C&s|H!$ " $++F3 %jj);R@FBG))(3!$>?!Q	!; 1 =R 	"DEF"S%55Qvs;/	
  )3{+;; %" "23	
 	
a % G$LLS97
 ,4<<
B+G$,LL$<8:2LWI0V	" =<sJ   %S)*)Q<S))R9AS)<S)	S&
AS!S)!S&&S))S2rg   r0   rb   r2   rk   rl   c                    |j                  dd      }|j                  dd      }| d}	|j                  |	      }
|
s|j                  |      }
|
sC|rA|j                         D ].  \  }}|j                  | d      st        |t              s,|}
 n |
xs i }
t        |
t              r|
j                  dd      nd}t        |
t              r|
j                  dg       ng }|j                  |g       }|D ci c]  }|j                  d      | }}g }|d d	 D ]T  }|j                  |i       }|j                  d
d      xs d}|j                  dd      xs d}|j                  |||f       V d| d| d}|r	|d| dz  }|r|ddj                  |      z   dz   z  }|rB|dt        |       dz  }|D ]&  \  }}}|d| d|rd|z   dz   nd dz  }||z  }|dz  }( |dz  }|dz  }dt        t        t        f   dt        fd}	 t        d|||| j                  d| | j                  d |i!      |"      }|j                  d#g       }|rV|d$   }||d <   ||d<   |j                  d%d      xs d}t        j!                  d&||t        |j#                                      |S t%        d'      c c}w # t&        $ r,}t        j)                  d(||       |||xs dd)d*cY d }~S d }~ww xY w)+Nr;   r<   r=   z	:location:descriptionvisual_traitsr9      r?   textz
[Location u
   ]
이름: z

u   기존 설명 (entity_detail):
u!   시각 특성 (entity_detail):
- z
- u(   등장 씬 텍스트 (맥락 참고용, u   개 샘플):
u	   
--- 씬  []z ---

u  [지시]
위 정보를 바탕으로 이 location의 **씬 간 동일하게 유지되어야 할 외형만** 추출하여 fixed_visual_description을 영어로 작성하세요.
- 포함: 크기·형태·재질·색상·구조적 디테일·고정 소품
- 제외: 날씨·시간·조명·대기 상태·인물·차량·감정·분위기·순간적 상태
- 3~5 문장, 40~80 단어
- 엔티티 ID(C##/L##/P##) 사용 금지, 고유명사 사용 금지
- T2I 프롬프트에 직접 삽입 가능한 구체적 묘사
respr(   c                     t        | t              r| j                  d      nd}|rt        |t              sy|d   }t        |t              sy|j                  dd      xs d}t	        |j                               S )uZ   semantic 검증: locations 배열에 최소 1개 요소 + fixed_visual_description 존재.r3   NFr   rE   r<   )
isinstancedictrL   listboolstrip)r   locsfirstrp   s       r%   _validate_locationszFLocationConsistencyStep._process_location.<locals>._validate_locations  sg    ,6tT,B488K(Dz$5GEeT*997<BD

%%r'   r@   location_consistency_rD   )extra_metadata)steprk   user_promptresponse_schemaproject_configschema_nameopik_metadatavalidate_responser3   r   rE   z&location_consistency %s (%s): %d wordsu    locations 배열이 비어있음z,location_consistency %s all tiers failed: %su2   실패 — 기존 entity_detail description 사용rI   )rL   rR   rV   r   r   rS   joinrT   r   strr   r   r
   r   build_opik_metadatarP   rQ   split
ValueErrorr[   r\   )r    rg   r0   rb   r2   rk   rl   rh   r=   
detail_keydetailkvbase_descriptionr   appear_scene_indicesrj   seg_mapscene_samplesrf   r?   r   r   r   rZ   r3   r   rp   excs                                r%   rY   z)LocationConsistencyStep._process_location   ss    ggj"%wwvr"
 vY'
##J/#''-F$&,,.1<<4&
+
1d0CF / 2<Fvt<T6::mR8Z\;Efd;S

?B7Y[  255c2>:BC(3377=)3.(C &r*B++b"%Cggi,2G7762&,"D  "gt!45	 + #3%{4&==>N=OtTTK?6;;}C]]`fffKEc-FXEYYghhK%2!GTB4q'#-#2EWY0ZZ`aat#t# &3 4KO		
		&d38n 		& 		& 	$++' &#223C59"66}VYFZ6["5	F 

;3I!!'*m$ $fyy!;R@FB<s4::<0 ?@@U DV  	LLGcR",<,B$X	 	s+   7J.BJ3 #J3 3	K(<!K#K(#K(N)rC   )__name__
__module____qualname____doc__r   r&   r   r   r|   r   r   intrY    r'   r%   r   r      s    PS a
c3h a
Fqq S$Yq !d3i0	q
 t*q q q 
qr'   r   )r   loggingconcurrent.futuresr   r   typingr   r   r   app.core.errorsr   app.core.step_runnerr	   app.modules.llm.llm_clientr
   app.modules.prompt_loaderr   r   	getLoggerr   rP   rW   r   r   r'   r%   <module>r      sI     ? " " $ + 6 >			8	$ej er'   