+
    YUj                        R t ^ RIHt ^ RIt^ RIt^ RIt^ RIHtHt ^ RIt]P                  P                  RR4      t^tRtR R ltR tR	 R
 ltR R ltR tR# )u  Twice-daily backup of the Jarvis memory graph (FalkorDB) into the Ultron
Supabase database — a SEPARATE system from the memory DB, so a FalkorDB or volume
failure can't take the backup with it. Runs inside jarvis-tools (which already
has both the FalkorDB and Supabase connections). No new service, no OAuth.

Table `memory_backups(id, created_at, counts jsonb, snapshot jsonb)` — the full
graph as portable JSON (embeddings excluded; they regenerate from text on
restore). Keeps the last KEEP snapshots.

Env: FALKOR_HOST/FALKOR_PORT (+ MEMORY_GRAPH) to read the graph; SUPABASE_URL /
SUPABASE_DB_PASSWORD (already set for the ultron tools) to write the backup.
)annotationsN)datetimetimezoneMEMORY_GRAPHjarvisc                   V ^8  d   QhRR/# )   returnbool )formats   "memory_backup.py__annotate__r      s     J JD J    c                     \        \        P                  P                  R 4      4      ;'       d    \        P
                  ! 4       # )FALKOR_HOST)r
   osenvironget	ultron_db
configuredr   r   r   r   r      s+    

}-.II93G3G3IIr   c            	        ^ RI Hp  T ! \        P                  R,          \	        \        P                  P                  RR4      4      \        P                  P                  R4      ;'       g    RR7      pVP                  \        4      # )    )FalkorDBr   FALKOR_PORT6379FALKOR_PASSWORDN)hostportpassword)falkordbr   r   r   intr   select_graphGRAPH)r   dbs     r   _graphr%      s\    !	rzz-02::>>-@A::>>*;<DD
FB ??5!!r   c                   V ^8  d   QhRR/# )r   r	   dictr   )r   s   "r   r   r   '   s      d r   c                   a \        4       oV3R  lp V ! R4      pV ! R4      pV ! R4      pV ! R4      pR pR\        P                  ! \        P                  4      P                  4       R\        RR	\        V4      R
\        V4      R\        V4      R\        V4      /R	V! . ROV4      R
V! . ROV4      RV! . ROV4      RV! . ROV4      /# )c                b   <  SP                  V 4      P                  #   \         d    . u # i ; iN)query
result_set	Exception)qgs   &r   rowsexport_graph.<locals>.rows*   s0    	771:((( 	I	s    ..zoMATCH (m:Memory) RETURN m.id, m.text, m.kind, m.group, m.valid, m.created_at, m.confidence, m.tone, m.refers_toz-MATCH (e:Entity) RETURN e.key, e.name, e.typez3MATCH (i:Insight) RETURN i.id, i.text, i.created_atzMMATCH (a)-[r]->(b) RETURN coalesce(a.id,a.key), type(r), coalesce(b.id,b.key)c           	     T    V Uu. uF  p\        \        W4      4      NK  	  up# u upi r*   )r'   zip)colsdatars   && r   <lambda>export_graph.<locals>.<lambda>6   s    >AT#d,/>>s   %exported_atgraphcountsmemoriesentitiesinsightsrelationships)	idtextkindgroupvalid
created_at
confidencetone	refers_to)keynametype)r@   rA   rE   )fromrelto)r%   r   nowr   utc	isoformatr#   len)r0   mementinsrM   mkr/   s         @r   export_graphrW   '   s    A  A BC
>
?C
D
EC
 & 'C	>Bx||HLL1;;=:s3xSXs3x#c(DB ;<?AB.4B3S9137
 
r   c                   V ^8  d   QhRR/# )r   r	   strr   )r   s   "r   r   r   D   s     W WC Wr   c            	        \        4       p \        P                  ! V R ,          4      \        P                  ! V RR7      r!\        P                  ! 4       ;_uu_ 4       pVP                  R4       VP                  RW34       VP                  R\        34       RRR4       V R ,          pRVR,           R	VR
,           RVR,           R\         R2	#   + '       g   i     LA; i)r;   F)ensure_asciizCREATE TABLE IF NOT EXISTS memory_backups (id bigserial PRIMARY KEY, created_at timestamptz DEFAULT now(), counts jsonb, snapshot jsonb)zKINSERT INTO memory_backups (counts, snapshot) VALUES (%s::jsonb, %s::jsonb)zdDELETE FROM memory_backups WHERE id NOT IN (SELECT id FROM memory_backups ORDER BY id DESC LIMIT %s)Nu   → Supabase memory_backups: r<   z memories / r=   z entities / r>   z insights (keep last ))rW   jsondumpsr   _connectexecuteKEEP)r5   r;   snapconncs        r   
run_backupre   D   s    >D::d8n-tzz$U/SD					,	- 	YN	 	HJN	R 
 	XA+AjM?,}o\!J-8MdVSTV W 
	s   <CC!	c                 p  "     \        4       '       d4   \        P                  ! \        4      G Rj  xL
 p \	        RV  2RR7       M\	        RRR7        \        P                  ! \        4      G Rj  xL
  Kw   LG  \
         d+   p\	        R\        T4      R,           2RR7        Rp?LVRp?ii ; i L@5i)z=Backup on startup, then every 12h. Never crashes the service.TNz[memory-backup] )flushz5[memory-backup] skipped (FALKOR/SUPABASE env not set)z[memory-backup] error: :N   N)	r   asyncio	to_threadre   printr-   rY   sleep
INTERVAL_S)outes     r   	schedulerrp   X   s     
	H||#--j99(.d;M " mmJ''' :
  	H+CF4L>:$GG	H'sV   B6-A< A:A< B6A< B63B44B6:A< <B1 B,'B6,B11B6i  )__doc__
__future__r   ri   r]   r   r   r   r   r   r   r#   ra   rm   r   r%   rW   re   rp   r   r   r   <module>rs      sW    #   	 ' 


~x0	
J":W((r   