
    O*jO,                        d Z ddlmZ ddlZddlmZ ddlmZmZ ddl	m
Z
  e
d          ZdZd	Zd
Z e            Zd%dZd%dZd&dZd'dZd(dZd)dZd*dZd+dZd,dZd-d#Zd.d$ZdS )/u  世界持久化:WorldEngine 全量可变状态的存档与恢复(G20:随时存档,断点续世)。

设计为**纯外部模块**,不侵入引擎:snapshot 只读、restore 只写回。
不可变部分(地图拓扑/人设/seed/brain/llm)不入档——调用方约定:
restore 前先用**相同参数**重新构造引擎,本模块只负责"可变状态":
时钟、世界客观事实、每个心智(意图/躯体/记忆)、叙事与说书人前情。

已知未覆盖(恢复后自愈,见模块尾注):
- actor 当前动作与调度器预约:醒来重新决策,start() 会重新排程;
- attention 收件箱里未消费的事件:丢失,但事件源头已落入世界状态;
- dialogue_until / auto_ff 等瞬时调速窗口:恢复为常规速率。
    )annotationsN)Path)
MemoryKindMemoryRecord)
get_loggerzruntime.persistence   )	intentlast_speechlast_thoughthomedialogue_with	gatheringgoals	relationsimp_acc)last_meal_h	woke_at_hfear
_fear_at_hreturndictc                   | j         }t          | j        j        | j        dt          |j                  |j        |j        t          |j	                  d |j
                                        D             d |j                                        D             d |j                                        D             dd | j                                        D             t          | j                  | j        t#          | dd          t          t#          | d	g                     t#          | d
d          t#          t#          | dd          dd          t%          t#          | dd                    t'          | j                  d}t*                              d| j                                        t1          |d                   t1          |j	                  t1          | j                             |S )uc   把引擎的全量可变状态导出为 JSON-safe dict(任何时刻可调,只读不扰动世界)。)sim_seconds	base_ratec                8    i | ]\  }}||t          |          S  )list).0pnamess      6/root/genesis-world/src/genesis/runtime/persistence.py
<dictcomp>z#snapshot_engine.<locals>.<dictcomp>.   s)    QQQ(!U5Qq$u++QQQ    c                $    i | ]\  }}||j         S r   )state)r   fidfs      r!   r"   z#snapshot_engine.<locals>.<dictcomp>/   s     LLLFC3LLLr#   c                L    i | ]!\  }}||j         |j        |j        |j        d "S )placeholder	destroyedhiddenr)   )r   iidits      r!   r"   z#snapshot_engine.<locals>.<dictcomp>0   sI     7 7 7!#r RX)+L L 7 7 7r#   )	positionsweatherpower_ondeadbodies
facilitiesitemsc                4    i | ]\  }}|t          |          S r   )_snapshot_mind)r   nameminds      r!   r"   z#snapshot_engine.<locals>.<dictcomp>4   s&    TTTt$t,,TTTr#   	ferry_etaNexecutedendingdevicesacts_burnedr   
_demo_doner   )versionclockr%   minds	narrativelighthouse_fuelr;   r<   r=   r?   	demo_donenarratoru8   📸 世界快照:t=%s,%d 心智,%d 死亡,叙事 %d 条rC   )r%   SNAPSHOT_VERSIONrB   r   r   r   r0   r1   r2   r3   r4   r6   r5   rC   r   rD   rE   getattrsorted_snapshot_narratorrG   loggerinfolabellen)enginestdatas      r!   snapshot_enginerS   #   s   	B#!'!9HXYYbl++zMMQQbioo6G6GQQQLLbm6I6I6K6KLLL7 7%'X^^%5%57 7 7

 

 UTv|?Q?Q?S?STTT&*++!1V[$77R8899&(D11wvy$??PQRRGFL"==>>&v77/ D2 KKJ""$$c$w-&8&8#bg,,FL\H]H]_ _ _Kr#   c                   i }t           D ]&}t          | |t                    }|t          ur|||<   't          | dd          }|t          |          |d<   t          | dd          }|t          |          |d<   t          | dd          fdt          D             |d<   t          | dd          }|,d |j                            |j                  D             |d<   |S )u_   单个心智的可变状态。StubMind / CognitiveMind 字段集不同,只存实际存在的。dialogueNinsightssomac                2    i | ]}|t          |          S r   )rI   )r   r'   rW   s     r!   r"   z"_snapshot_mind.<locals>.<dictcomp>S   s%    AAAqq'$**AAAr#   memoryc                ,    g | ]}t          |          S r   )_record_to_dictr   rs     r!   
<listcomp>z"_snapshot_mind.<locals>.<listcomp>V   s     WWW++WWWr#   )_MIND_FIELDSrI   _MISSINGr   _SOMA_FIELDSstoreallagent_id)r:   outkeyvalrU   rV   rY   rW   s          @r!   r8   r8   D   s   C  dC**hCHtZ..Hx..JtZ..Hx..J4&&DAAAALAAAFT8T**FWWV\5E5Efo5V5VWWWHJr#   recr   c                f    | j         | j        | j        | j        | j        | j        j        | j        dS )N)idrd   content
created_atlast_accessedkind
importance)rj   rd   rk   rl   rm   rn   valuero   )rh   s    r!   r[   r[   Z   s6    &cls{.3;LHN#.B B Br#   dict | Nonec                    | d S t          | j                  | j        t          | j                  t	          | dd          dS )N_last_write_s        )parassummarybufferlast_write_s)r   ru   rv   rw   rI   )rG   s    r!   rK   rK   `   sM    t(.))h6F8?++#HosCCE E Er#   rR   Nonec           
         |                     dd          }|t          k    r!t                              d|t                     |d         }t	          |d                   | j        _        | j                                        | j        _        | 	                    t	          |d                              t          | j        |d                    |                     di                                           D ]M\  }}| j                             |          }|t                              d
|           =t          ||           N| j        j        D ]^}| j                            |           | j                            |           | j                             |          }|d	|j        _        _d |                     dg           D             | j        d	d	<   t/          |                     dd                    | _        |                     d          *t3          | d          rt	          |d                   | _        t3          | d          r-t7          |                     dg                     | j        d	d	<   t3          | d          r|                     d          | _        t3          | d          r-t/          |                     dd                    | j        _        | j        j                              d          }|;|j        dk    r0t3          | j        d          r| j        !                    dd           t3          | d          r(tE          |                     dd                    | _#        tI          | j%        |                     d                     t          &                    d| j        '                                tQ          |                     di                     tQ          | j        j                             d	S )u  把快照应用回一个**新构造的同世界**引擎;在 engine.start() 之前调用。

    时钟恢复:把存档的模拟时刻设为新锚点(真实时间锚到"现在"),
    时间从断点无缝续走;start() 会按恢复后的时刻重新排程唤醒。
    rA   r   u5   存档版本 %s 高于当前支持的 %s,尽力恢复rB   r   r   r%   rC   Nu9   存档中的心智「%s」在新引擎里不存在,跳过c                ,    g | ]}t          |          S r   r   )r   ns     r!   r^   z"restore_engine.<locals>.<listcomp>   s    FFFq477FFFr#   rD   rE   r;   r<   r=   r>   r?   master_dooropenconnectu   二层走廊u	   青之房r@   rF   r   rG   u)   ⏪ 世界恢复:t=%s,%d 心智,%d 死亡))getrH   rL   warningfloatrB   _anchor_sim_time_fn_anchor_realset_base_rate_restore_stater%   r6   rC   _restore_mindr3   bus
unregisterscheddropactorcurrentrD   intrE   hasattrr;   r   r<   r=   r>   r?   r5   r   setr@   _restore_narratorrG   rM   rN   rO   )	rP   rR   rA   clkr9   mdatar:   victimmds	            r!   restore_enginer   j   s    hhy!$$G!!!NPWYijjj w-C$S%788FL & 5 5 7 7FL
s;/001116<g///xx,,2244 # #e|%%<NNVX\]]]dE"""" ,# & &
f%%%&!!!|''!%DJFFDHH[",E,EFFFFQQQ *;Q!?!?@@Fxx(WV[-I-I( k!233vz"" <!$((:r":":;;vx   +**vy!! E%(-)C)C%D%D"		 	$	$]	3	3B	~"(f,,y1Q1Q,^[999v|$$ ;b 9 9::fotxx
';';<<<
KK;V\=O=O=Q=QDHHWb))**C0A,B,BD D D D Dr#   sdatac                   | j                                          | j                             |d                    |d         | _        |d         | _        | j                                         | j                            |d                    | j                                         |                    di                                           D ]\  }}t          |          | j        |<   |                    di                                           D ]<\  }}|| j
        v r|| j
        |         _        !t                              d|           =|                    di                                           D ]q\  }}| j                            |          }|t                              d
|           =|d         |_        |d         |_        |d         |_        |d         |_        rd	S )ud   写回 WorldState。设施/物品按 id 就地改状态(对象本身由 seed 构造,保持引用)。r0   r1   r2   r3   r4   r5   u0   存档设施「%s」不存在于新世界,跳过r6   Nu0   存档物品「%s」不存在于新世界,跳过r*   r+   r,   r-   )r0   clearupdater1   r2   r3   r4   r   r6   r   r5   r%   rL   r   r*   r+   r,   r-   )	rQ   r   r*   r    r&   fstater.   idatar/   s	            r!   r   r      s   LLk*+++y!BJ
#BKGMMOOOGNN5=!!!IOO		(B//5577 ' 'u;;	%yyr2288:: T TV"-'-BM#$$NNMsSSSSii,,2244 $ $
UX\\#:NNMsSSS>(O	[)(O		$ $r#   r   c                z   t           D ]-}||v r't          | |          rt          | |||                    .t          | dd           }|3d|v r/|                                 |                    |d                    t          | dd           }|3d|v r/|                                 |                    |d                    t          | dd           }|5d|v r1t          D ])}||d         v rt          |||d         |                    *t          | dd           }|d|v rt          ||d                    d S d S d S )NrU   rV   rW   rY   )r_   r   setattrrI   r   extendra   _restore_memory)r:   r   rf   rU   rV   rW   r'   rY   s           r!   r   r      sq    + +%<<GD#..<D#uSz***tZ..H
e 3 3j)***tZ..H
e 3 3j)***4&&DFeOO 	3 	3AE&M!!avq!1222T8T**Fh%//h00000 //r#   records
list[dict]c                    d |D             }t          | j        dd          }| || j        |           dS |D ]#}d|_        | j                            |           $dS )u`   整体重建记忆流。优先用 store 的 replace_all(保留原 id);否则逐条 add 兜底。c                    g | ]\}t          |d          |d         |d         t          |d                   |d         |d         |                    d                    ]S )rd   rk   rl   rn   ro   rm   rj   )rd   rk   rl   rn   ro   rm   rj   )r   r   r   r\   s     r!   r^   z#_restore_memory.<locals>.<listcomp>   su        	 !J-9$%lO*QvY:O:O$%lO1_CUEE$KK) ) )   r#   replace_allN)rI   rb   rd   rj   add)streamr   recsreplacerh   s        r!   r   r      s      	  D
 flM488G&&&&& 	" 	"CCFLS!!!!	" 	"r#   ndatac                   | | |r| t                               d           d S d |                    dg           D             | j        d d <   |                    d| j                  | _        t          |                    dg                     | j        d d <   t          |                    dd                    | _        d S )Nu>   存档含说书人前情,但新引擎未注入 narrator,跳过c                ,    g | ]}t          |          S r   r|   )r   r   s     r!   r^   z%_restore_narrator.<locals>.<listcomp>   s    AAAQaAAAr#   ru   rv   rw   rx   rt   )	rL   r   r   ru   rv   r   rw   r   rs   )rG   r   s     r!   r   r      s    5= 	]X%NN[\\\AA%))GR*@*@AAAHN111yyH,<==Heii"5566HOAAA"599^S#A#ABBHr#   path
str | Pathr   c                   t          |          }|j                            dd           |                    t	          j        t          |           dd          d           t                              d|           |S )	u=   存档落盘(JSON,中文原样可读)。返回写入路径。T)parentsexist_okF   )ensure_asciiindentutf-8encodingu   💾 存档已写入 %s)	r   parentmkdir
write_textjsondumpsrS   rL   rM   )rP   r   r   s      r!   save_to_filer      sy    T

AHNN4$N///LLOF33%PQRRR!  # # #
KK)1---Hr#   c                    t          j        t          |                              d                    }t	          | |           |S )u`   从存档文件恢复到 engine(须为同参数新构造、未 start)。返回读到的快照。r   r   )r   loadsr   	read_textr   )rP   r   rR   s      r!   load_from_filer      s=    :d4jj**G*<<==D64   Kr#   )r   r   )rh   r   r   r   )r   rq   )rR   r   r   ry   )r   r   r   ry   )r   r   r   ry   )r   r   r   ry   )r   rq   r   ry   )r   r   r   r   )r   r   r   r   )__doc__
__future__r   r   pathlibr   genesis.memory.recordr   r   genesis.obs.logging_setupr   rL   rH   r_   ra   objectr`   rS   r8   r[   rK   r   r   r   r   r   r   r   r   r#   r!   <module>r      s    # " " " " "        : : : : : : : : 0 0 0 0 0 0	)	*	*  AA688
   B   ,B B B BE E E E3D 3D 3D 3Dl$ $ $ $61 1 1 1," " " " C C C C        r#   