
    yjF                        d Z ddlmZ ddlZddlZddl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Zd	Z G d
 de      Zy)u  W20A: BaseLocationDossierStep — deterministic per-fp dossier producer.

Consumes:
  - ``floor_plan_prompt`` (v6) — numbered_elements + base_layer_decision.
  - ``floor_plan_render`` — png_path per fp (best-effort).
  - ``background_master_plan`` — backgrounds[] DAG per fp.
  - ``floor_plan_overlay_payload`` — per-bg overlay payload.

Gates (opt-in, default OFF):
  - ``settings.background_mode`` ∉ {"on","floor_plan_anchored"} → not_applicable.
  - ``settings.base_location_dossier_enabled`` != True → not_applicable.
  - ``settings.floor_plan_prompt_version`` != "6" → not_applicable.
    v5 path does not carry base_layer_decision, so a dossier built off
    v5 markers would lose the partition contract.

Checkpoint data shape:
  ``data.dossiers`` = ``{fp_id: dossier_dict}`` (build_dossiers output).
  Failure path emits ``data.error`` (truncated str) and an empty
  ``data.dossiers``.

LLM / image / VLM API call 0, DB / ImageAsset write 0.
    )annotationsN)Path)AnyDictOptional)
StepRunner)BaseLocationDossierErrorbuild_dossiers   1c                  6    e Zd ZddZ	 	 	 	 ddZddZd	d
dZy)BaseLocationDossierStepc                   ddl m} |j                  |j                  t	        |j
                        t        t        d}t        j                  t        j                  |d      j                  d            j                         d d S )Nr   settings)background_modefloor_plan_prompt_versionbase_location_dossier_enabledschema_versionprompt_versionT)	sort_keysutf-8   )app.core.configr   r   r   boolr   SCHEMA_VERSIONPROMPT_VERSIONhashlibsha256jsondumpsencode	hexdigest)selfr   payloads      _/Users/manta/Documents/Projects/TheRoad-I1/backend/app/core/steps/base_location_dossier_step.py_config_hashz$BaseLocationDossierStep._config_hash.   su    ,  (77)1)K)K-166. -,
 ~~JJw$/66w?

)+cr 	    c                L   ddl m} t        |j                        | j                  z  dz  dz  | j
                  z  |z  dz  }|j                         r&	 t        j                  |j                  d            S y # t        $ r!}t        j                  d||       Y d }~y d }~ww xY w)	Nr   r   checkpointsepisodeszmanifest.jsonr   )encodingz*base_location_dossier: %s parse failed: %s)r   r   r   projects_dir
project_id
episode_idexistsr    loads	read_text	Exceptionloggerwarning)r$   step_idr   cpexcs        r&   _load_prev_checkpointz-BaseLocationDossierStep._load_prev_checkpointC   s     	- &&'oo  oo	
   	 99;zz",,,"@AA   @ 
 s   $A9 9	B#BB#c                8    dddt         | j                         i dS )Nr   applicable_countcompleted_countfailed_countr   config_hashdata)r   r'   )r$   s    r&   _not_applicablez'BaseLocationDossierStep._not_applicable\   s'     ! ,,,.
 	
r(   c           	     2   ddl m} |j                  dvr| j                         S t	        |j
                        s| j                         S ddlm} |j                  |vr| j                         S | j                  d      }| j                  d      }| j                  d      }| j                  d      }|xs i j                  d	      xs i }|xs i j                  d	      xs i }	|xs i j                  d	      xs i }
|xs i j                  d	      xs i }	 t        ||	|
|
      }dddt        | j!                         d|idS # t        $ rJ}t        j                  d|       dddt        | j!                         t#        |      d d i ddcY d }~S d }~ww xY w)Nr   r   >   onfloor_plan_anchored) V6_COMPATIBLE_FP_PROMPT_VERSIONSfloor_plan_promptbackground_master_planfloor_plan_overlay_payloadfloor_plan_renderr@   )fp_prompt_datamaster_plan_dataoverlay_payload_datafp_render_datazbase_location_dossier: %s      )errordossiersr;   rQ   )r   r   r   rA   r   r   app.core.fp_prompt_compatrE   r   r9   getr
   r	   r4   rP   r   r'   str)r$   moder   rE   fp_prompt_cpmaster_plan_cp
overlay_cpfp_render_cprJ   rK   overlay_datarM   rQ   r8   s                 r&   _executez BaseLocationDossierStep._executef   s   ,##+HH''))H::;'')) 	O--5UU''))112EF334LM//0LM
112EF&,"11&9?R*0b55f=C"(b--f5;&,"11&9?R	%-!1%1-	H$ !" ,,,.*
 	
 ( 		LL4c:$%#$ !"0#002"%c(4C.bA 		s   E 	F?FFFN)returnrT   )r6   rT   r\   zOptional[Dict[str, Any]])r\   Dict[str, Any])resume)rU   rT   r\   r]   )__name__
__module____qualname__r'   r9   rA   r[    r(   r&   r   r   -   s&    *	!2
0
r(   r   )__doc__
__future__r   r   r    loggingpathlibr   typingr   r   r   app.core.step_runnerr   *app.modules.pipeline.base_location_dossierr	   r
   	getLoggerr_   r4   r   r   r   rb   r(   r&   <module>rk      sW   , #     & & +
 
		8	$ i
j i
r(   