
    mj"                        d 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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mZmZ ddlmZ ddlmZmZ  ej>                  e       Z!de"fdZ#de"fdZ$ G d d      Z%y)u  ImageComposerService — T2I Composer + composer prompt 설정 서비스 (W5 F23 Phase 3).

ImageService facade(image_service.py)에서 T2I composer 관련 3개 공개 메서드를
literal lift. facade는 얇은 delegate만 유지.

이관된 메서드:
- compose_prompts — 씬 스틸에 T2I cinematic/closeup 프롬프트 생성
- get_composer_prompt / update_composer_prompt — 프로젝트 단위 composer 오버라이드
    N)datetimetimezone)AnyDictListOptional)Session)settings)AppError)t)ActivityLogger)EntityCanonProjectSettings
SceneStill)T2IPromptComposer)get_latest_world_guideload_project_llm_configreturnc                  d    t        j                  t        j                        j	                         S N)r   nowr   utc	isoformat     Y/Users/manta/Documents/Projects/TheRoad-I1/backend/app/services/image_composer_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ededededdf
dZd	ee   de	e
eef      fd
Z	 ddedee   de
eef   fdZde
eef   fdZ	 	 	 ddee   dee   dee   de
eef   fdZy)ImageComposerServiceu0   T2I Composer + composer prompt 설정 서비스.db
project_idactor_idactivity_loggerr   Nc                 <    || _         || _        || _        || _        y r   )_db_project_id	_actor_id_logger)selfr%   r&   r'   r(   s        r   __init__zImageComposerService.__init__)   s!     %!&r   visible_entities_jsonc           
      v   |sg S 	 t        j                  |      }g }|D ]  }t        |t              r&|j                  d      xs |j                  dd      }nt        |t              r|}nM| j                  j                  t              j                  t        j                  |k(        j                         }|s|j                  |j                  |j                  |j                  |j                   xs d|j"                  xs d|j$                  xs dd        |S # t         j                  $ r g cY S w xY w)z4Parse visible entities JSON and look up entity data.id	entity_id {})r2   nameentity_typeshort_iddescriptionstable_traits)jsonloadsJSONDecodeError
isinstancedictgetr   r*   queryr   filterr2   firstappendr6   r7   r8   r9   r:   )r.   r0   visible_idsvisible_entitiesveidentitys          r   _get_visible_entitiesz*ImageComposerService._get_visible_entities5   s   $I	**%:;K A!T"eeDk;QUU;%;As# {+#-. 
  '' ))"KK#)#5#5 & 52#)#5#5#;%+%9%9%AT)  .  7 ## 	I	s   D   D87D8still_idipc                    ddl m}  |       st        dt        d      d      | j                  j                  t              j                  t        j                  |k(  t        j                  | j                  k(        j                         }|st        dt        d      d      | j                  j                  t              j                  t        j                  | j                  k(        j                         }|r|j                  nd}|r|j                  nd}t        t!        | j                  | j                        d	||
      }| j#                  |j$                        }	i }
|	D ]H  }|d   }|j'                  dd      }t)        |t*              r	 t-        j.                  |      |
|<   D||
|<   J t3        | j                  | j                  |j4                        }	 t-        j.                  |j6                  xs d      }	 t-        j.                  |j8                  xs d      }|j;                  |j<                  xs d|||	|
|      }|d   |_        |d   |_         |d   |_!        | j                  jE                          | jF                  jI                  | jJ                  dd|| j                  |d   |j'                  dg       d|       ||d   |d   |d   |j'                  dg       |j'                  dg       dS # t,        j0                  $ r	 i |
|<   Y w xY w# t,        j0                  $ r i }Y 6w xY w# t,        j0                  $ r i }Y .w xY w)u?   Run T2I composer on a still — save cinematic+closeup prompts.r   )has_openai_keyzimage.openai_key_missingi  )codemessagestatus_codezstill.not_foundi  Nv1)project_llm_configprompt_versionsystem_prompt_overrideuser_prompt_overrider2   r:   r5   r4   )scene_descriptioncamera_jsonlighting_jsonrF   entity_visual_traitsworld_guide	cinematiccloseupcomposer_versionzstill.compose_promptsstillkey_visual_elements)r^   r`   )r'   actionresource_typeresource_idr&   detail
ip_addressremoved_narrative_elements)rK   t2i_prompt_cinematict2i_prompt_closeupr^   r`   rf   )&app.core.openai_keysrN   r   r   r*   rA   r   rB   r2   r&   r+   rC   r   composer_system_promptcomposer_user_promptr   r   rJ   r0   r@   r>   r   r;   r<   r=   r   
episode_idrX   rY   composestill_frame_promptrg   rh   t2i_composer_versioncommitr-   logr,   )r.   rK   rL   rN   r_   proj_settingssystem_overrideuser_overridecomposerrF   rZ   rI   rH   traitsr[   cameralightingresults                     r   compose_promptsz$ImageComposerService.compose_promptsX   s>    	8/45  HHNN:&VJMMX-z/D/DHXHX/XYUW 	
 &+,  HHNN?+VO..$2B2BBCUW 	
 CP->>UY>K::QU$6txxAQAQR#2!.	
  55e6Q6QR/1&F,CZZ6F&#&304

60B(- -3$S) ' -TXXt7G7GIYIYZ	ZZ 1 1 9T:F	zz%"5"5"=>H !!#66<""-!5# " 
 &,K%8"#))#4 %+,>%?"^^*! ''$*+=$>'-zz2G'L  	 	
 !$*;$7"("3 &'9 :#)::.CR#H*0**5QSU*V
 	
[ ++ 302(-3 ## 	F	 ## 	H	s6   L!#L" #L> LL"L;:L;>MMc                     | j                   j                  t              j                  t        j                  | j
                  k(        j                         }|r|j                  nd|r|j                  dS ddS )z6Get current composer prompt settings for this project.Nrj   rk   )	r*   rA   r   rB   r&   r+   rC   rj   rk   )r.   rr   s     r   get_composer_promptz(ImageComposerService.get_composer_prompt   so     HHNN?+VO..$2B2BBCUW 	 O\m&J&JaeJWM$F$F
 	
]a
 	
r   system_promptuser_promptc                 `   | j                   j                  t              j                  t        j                  | j
                  k(        j                         }|sCt        t               | j
                  t                     }| j                   j                  |       |||_
        |||_        t               |_        | j                   j                          | j                  j                  | j                   dd|j"                  | j
                  |       |j                  |j                  dS )z.Update project-level composer prompt override.)r2   r&   
updated_atzproject.update_composer_promptproject_settings)r'   ra   rb   rc   r&   re   r|   )r*   rA   r   rB   r&   r+   rC   r"   r   addrj   rk   r   rp   r-   rq   r,   r2   )r.   r~   r   rL   rr   s        r   update_composer_promptz+ImageComposerService.update_composer_prompt   s     HHNN?+VO..$2B2BBCUW 	 +9++6M
 HHLL'$3@M0"1<M.#'6 ^^3,%(('' 	 	
 '4&J&J$1$F$F
 	
r   r   )NNN)__name__
__module____qualname____doc__
OrmSessionr   r   r/   r   r   r   r   rJ   rz   r}   r   r   r   r   r$   r$   &   s    :
'
' 
' 	
'
 (
' 

'! 8C= ! TRVWZ\_W_R`Ma ! L !g
g
 SMg
 
c3h	g
Z

T#s(^ 

 (,%) 	(
}(
 c](
 SM	(

 
c3h(
r   r$   )&r   r;   loggingr    r   r   typingr   r   r   r   sqlalchemy.ormr	   r   app.core.configr
   app.core.errorsr   app.i18n.loaderr   app.logging.activity_loggerr   app.models.projectr   r   r   app.modules.t2i_prompt_composerr   "app.services.image_service_helpersr   r   	getLoggerr   loggerr   r   r"   r$   r   r   r   <module>r      so       ' , , 0 $ $  6 G G = ^			8	$2c 2 S
 S
r   