
    U,i                     
   d Z ddlZddlZddlZddlZddlZddl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 ddlmZmZmZmZmZmZ ddlZej.                  j1                  dd      Z ee      dz  Zej.                  j1                  d	d
      Zej.                  j1                  dd      Zej.                  j1                  dd      Zej.                  j1                  dd      ZdZej@                  jC                  d e" ee      dz  dz                e	jF                  d      Z$e G d d             Z%dkde"de&dee%   fdZ'de"dedee"ef   fdZ(de"de"d e"d!e)de)f
d"Z*dkde"de&dee%   fd#Z+d$e"d%ee"   de,fd&Z-dkde"de&dee%   fd'Z.dkde"de&dee%   fd(Z/	 dlde"ded)ee"   dee"ef   fd*Z0d)e"dee"ef   fd+Z1dkde"de&dee%   fd,Z2de"dedee"ef   fd-Z3d)e"dee"ef   fd.Z4d/ Z5d0e"dee"   fd1Z6dmd0e"d2e"d3e&de7fd4Z8d0e"de7fd5Z9e'e+e.e/e2d6Z:	 	 	 dnde"d8e&d9eee"      d:e7dee%   f
d;Z;	 	 	 dnde"d8e&d9eee"      d:e7dee%   f
d<Z<dkde"d=e&de"fd>Z=dode"d?e"de&dee%   fd@Z>dAe%dBe&de"fdCZ? G dD dE      Z@eAdFk(  rddlBZB eBj                  dGH      ZDeDj                  ddIdJK       eDj                  dLdMdNK       eDj                  dOe&d7P       eDj                  dQdRS       eDj                  dTdRdUV       eDj                         ZGeGj                  rr e@       ZI ej                  eIj                               ZL eMdW       eLj                         D ]  \  ZOZPePdXu rdYndZZQ eMd[eQ d\eO d]eP           ej                  d       eGj                  xs d\j                  ej                  d^d       ZVeVs"eDj                           ej                  d^        ej                         ZX e<eVeGj                  eGj                  eGj                  _      Z\ ej                         eXz
  Z] eMd`eV da        eMdb e^e\       dce]ddde       g Z_g Z`e\D ]k  Zaeaj                  j                  df      seaj                  j                  dg      re_j                  ea       Keaj                  dhk7  s[e`j                  ea       m  efe`d^      D ]  \  ZgZa eM e?eaeg              eM         e_r=eGj                  r1 eMdi       e_D ]$  Zh eMd[ehj                   d]ehj                          & eGj                  r=e\D  cg c]  } | j                  dhk(  s|  c} ZieiD ]  Zj eMdjejj                           yyyc c} w )paz  
Genesis Memory Hub - Unified query across ALL memory systems.
One function to search everything. The missing bridge.

Memory Systems:
  1. Supermemory (genesis-kinan container) - semantic memory via API
  2. Graphiti (Sovereign Memory MCP) - knowledge graph nodes + facts
  3. File-based KG - KNOWLEDGE_GRAPH/ entities, axioms, relationships
  4. Qdrant - vector similarity search across embedded content
  5. PostgreSQL - structured search across memory_bloodstream, ponte_goldmine, etc.

Usage:
    # Async
    results = await query_all("voice agent pricing")

    # Sync
    results = query_sync("voice agent pricing")

    # Class-based
    hub = GenesisMemoryHub()
    await hub.connect()
    await hub.store("voice agent works well", {"category": "voice"})
    results = await hub.search("voice agent pricing")

    # CLI
    python3 core/genesis_memory_hub.py "voice agent pricing"
    N)	dataclassfield)Path)ListDictOptionalSetAnyTupleGENESIS_ROOTz/mnt/e/genesis-systemKNOWLEDGE_GRAPHSUPERMEMORY_API_KEYZsm_EWRhbQPEodMHkJd8Vbshpx_wCauANQAwJFvFfTwTTrujWzHTQajuJPRJLFwavESILxQZpmDiqfIbDAAfGCffQQbSUPERMEMORY_CONTAINER_TAGzgenesis-kinanGRAPHITI_MCP_URLzhttp://152.53.201.221:8001/mcpGRAPHITI_GROUP_IDgenesis      $@datagenesis-memorygenesis_memory_hubc                   \    e Zd ZU dZeed<   eed<   dZeed<    ee	      Z
e	ed<   defd	Zy
)MemoryResultz'A single result from any memory system.sourcecontent      ?	relevance)default_factorymetadatareturnc                     | j                   j                  dd      d d }d| j                  d| j                  dd|dS )	N
 P   zMemoryResult(source=z, relevance=.2fz
, content=z...))r   replacer   r   )selfpreviews     0/mnt/e/genesis-system/core/genesis_memory_hub.py__repr__zMemoryResult.__repr__Q   sQ    ,,&&tS1#26"4;;/ 2, -k'	
    N)__name__
__module____qualname____doc__str__annotations__r   floatr   dictr   r*    r+   r)   r   r   I   s4    1KLIu40Hd0
# 
r+   r   querylimitr    c                 D  K   g }	 t        j                  t              4 d{   }|j                  ddt         dd| |t
        gd       d{   }|j                          |j                         }|j                  d	g       D ]  }|j                  d
g       }dj                  d |D              j                         }|s>|j                  dd      }	|j                  t        d|t        t        |	      d      |j                  d      |j                  d      d              ddd      d{    |S 7 7 7 # 1 d{  7  sw Y   |S xY w# t        $ r7}
|j                  t        dd|
 ddt!        |
      i             Y d}
~
|S d}
~
ww xY ww)z6Search Supermemory via direct API (same as search.sh).timeoutNz$https://api.supermemory.ai/v3/searchBearer application/jsonAuthorizationContent-Type)r5   r6   containerTagsheadersjsonresultschunksr"   c              3   d   K   | ](  }|j                  d       s|j                  d d       * yw)r    N)get).0cs     r)   	<genexpr>z%search_supermemory.<locals>.<genexpr>r   s+      $-.AEE)<LAEE)R($s   00scorer   supermemory      ?	createdAtid)rN   rO   r   r   r   r   z#[ERROR] Supermemory search failed:         error)httpxAsyncClientSYSTEM_TIMEOUTpostr   SUPERMEMORY_CONTAINERraise_for_statusrB   rG   joinstripappendr   minr2   	Exceptionr0   )r5   r6   rC   clientrespr   itemrD   r   rK   es              r)   search_supermemoryrb   ]   s    "$G+
$$^< !	 !	6'./B.C%D$6
 #"&;%< %  D !!#99;DB/ (B/)) $28$ %'  #. , '"%eElC"8)-+)>"&((4."	
!	 !	V NW!	!	 !	 !	 !	V N  
$=aSA!3q6*		
 	
 N
s   F E E E +EECE.E 9E:E >F  E EE EEEE F E 	F&,FF FF r   r   c                   K   	 t        j                  t              4 d{   }| t        gd}|r||d<   |j	                  ddt
         dd|	       d{   }|j                          d
|j                         j                  d      dcddd      d{    S 7 ~7 I7 	# 1 d{  7  sw Y   yxY w# t        $ r}dt        |      dcY d}~S d}~ww xY ww)zStore content in Supermemory.r8   N)r   r?   r   &https://api.supermemory.ai/v3/memoriesr:   r;   r<   r@   TrO   )rL   rO   F)rL   rR   )rS   rT   rU   rW   rV   r   rX   rB   rG   r]   r0   )r   r   r^   payloadr_   ra   s         r)   store_supermemoryrf      s     7$$^< 	F 	F""7!8'G &.
#8'./B.C%D$6  %  D !!##'tyy{t/DE!	F 	F 	F	F 	F 	F 	F"  7$s1v667s   C B< B!B< 3B'B#5B'B< B%B<  C !B< #B'%B< 'B9-B0.B95B< 8C 9B< <	CCCC CC 
session_idmethod	tool_name	argumentsc                   K   d| |||dd}dd| d}t        j                  t              4 d{   }|j                  t        ||	       d{   }|j
                  }|j                  d
      D ]L  }	|	j                  d      st        j                  |	dd j                               c cddd      d{    S  ddd      d{    i S 7 7 7 7 # 1 d{  7  sw Y   i S xY ww)z(Make a single MCP tool call to Graphiti.2.0)namerj   jsonrpcrO   rh   params#text/event-stream, application/jsonr;   Acceptr>   zmcp-session-idr8   NrB   rA   r"   zdata:   )rS   rT   rU   rV   GRAPHITI_URLtextsplit
startswithrB   loadsrZ   )
rg   rh   ri   rj   re   rA   r^   r_   rw   lines
             r)   _graphiti_callr|      s     
 $9=	G 8*$G
   8 4 4F[[GW[MMyyJJt$ 	4Dw'zz$qr(.."2334 4 4	44 4 I4M4 4 4 4 4 Isz   /C2CC2CC5C'C/C2;C<C2CC2CC2CC2C2C/"C%#C/*C2c                   K   g }	 dt        j                         j                  dd  }t        j                  t
              4 d{   }ddddd	d
di dd}dd|d}|j                  t        ||       d{    ddd      d{    t        |dd| t        g|d       d{   }g }|rO|j                  di       j                  dg       }	|	D ](  }
|
j                  dd      }|s|j                  |       * t        |dd| t        g|d       d{   }|rO|j                  di       j                  dg       }	|	D ](  }
|
j                  dd      }|s|j                  |       * |D ]&  }|j                  t        d|ddt        i             ( 	 |S 7 Y7 (7 # 1 d{  7  sw Y   ,xY w7 7 # t        $ r7}|j                  t        dd| dd t        |      i             Y d}~|S d}~ww xY ww)!z4Search Graphiti knowledge graph for nodes and facts.zhub-N   r8   rl   zhub-init
initializez
2024-11-05zgenesis-memory-hubz1.0.0)rm   version)protocolVersion
clientInfocapabilitiesrn   rq   r;   rr   rt   z
tools/callsearch_nodes)r5   	group_idsmax_resultsresultr   rw   rF   search_factsgraphitigffffff?grouprP   z [ERROR] Graphiti search failed: rQ   rR   )uuiduuid4hexrS   rT   rU   rV   rv   r|   GRAPHITI_GROUPrG   r[   r   r]   r0   )r5   r6   rC   rg   r^   init_payloadrA   
nodes_respcontent_itemsresult_contentr`   rw   
facts_respra   s                 r)   search_graphitir      s`    "$GC
DJJL,,Ra012
$$^< 	P 	P ! &'3+?G"T$&		L @ 2",G
 ++lw+OOO#	P 	P( *>*:5Q	
 

 '^^Hb9==iLN& /xx+!((./ *>*:5Q	
 

 '^^Hb9==iLN& /xx+!((./
 " 	DNN% !%~6		$ NE	P" P#	P 	P 	P 	P(

,  
!:1#>!3q6*		
 	
 N
s   HAG F!	G 0F*<F$=F*G F'G +G ,AG 0-G GAG  >G H!G $F*'G *F=0F31F=8	G G 	H,H :H HHrw   keywordsc                 p    | j                         t        fd|D              }|r|t        |      z  S dS )zCSimple keyword relevance: fraction of query keywords found in text.c              3   ,   K   | ]  }|v sd   yw   Nr4   )rH   kwlowers     r)   rJ   z!_keyword_score.<locals>.<genexpr>  s     4be4s   	rQ   )r   sumlen)rw   r   foundr   s      @r)   _keyword_scorer     s4    JJLE4H44E$,53x= 5#5r+   c                 <  K   g }| j                         D cg c]!  }t        |      dkD  s|j                         # }}t        dz  }|j	                         r|j                  d      D ]  }	 |j                  d      }t        ||      }|dkD  r	 t        j                  |      }	t        |	t              rt        j                  |	      dd nt        |	      dd }
|j                  t!        d	|
t#        |d      d
t        |      i              t        dz  }|j	                         r|j                  d      D ]  }	 t%        |dd      5 }t'        |      D ]  \  }}|j)                         }|s	 t        j                  |      }|j+                  d      xs |j+                  d      xs t        |      }t        ||      }|dkD  rL|j+                  dd|       }|j                  t!        d|dd t#        |d      t        |      |d              	 ddd        |j/                  d d       |d| S c c}w # t        $ r	 |dd }
Y vw xY w# t        $ r Y w xY w# t        j,                  $ r Y #w xY w# 1 sw Y   hxY w# t        $ r Y ]w xY ww)zCSearch file-based Knowledge Graph: entities, axioms, relationships.   entitiesz*.jsonzutf-8)encodingr   N,  file_kg_entitypathrP   axiomsz*.jsonlrr   rw   rO   zline-file_kg_axiomi  r   rO   c                     | j                   S Nr   r   s    r)   <lambda>z search_file_kg.<locals>.<lambda>Z  
    q{{ r+   Tkeyreverse)rx   r   r   KG_DIRexistsglob	read_textr   rB   rz   
isinstancer3   dumpsr0   r]   r[   r   roundopen	enumeraterZ   rG   JSONDecodeErrorsort)r5   r6   rC   wr   
entity_dirfpathrw   rK   r   snippet	axiom_dirfline_numr{   axiomr   axiom_ids                     r)   search_file_kgr     s    "$G#(;;=?aCFQJ	?H? *$J__X. 	E8&tX619-#zz$/6@t6LDJJt,Tc2RUVZR[\`]`Ra  
 NN$#3$+&+E1o&,c%j%9		0 !I^^I. 	E%w7 !1*3A, !$#zz|#$!$(JJt$4E %		) 4 !.#(99V#4!.#&u: $
 %37H$EE$qy+099TU8*;M+N '$0/>0727q/47J2:2*	%&
!"!!	D LL*DL96E?E @ % -"&t*-  D  $33 ! !5! !8  s   JH<H</J-#IAI3I/J?J%J 3B#I&J J! JIIII	I#J"I##J&I=	9J <I=	=J  J		J	JJJJc                 T  K   g }	 ddl m} ddlm} t        j
                  j                  dt        t        t              dz  dz               ddl
}|j                         } ||j                  |j                  t              }	 ddlm}  |d      }	t#        |	j%                  | g            d   j'                         }
g }|j/                         j0                  D ]  }	 |j3                  |j4                        }|j6                  rr|j6                  dkD  rc|j8                  j:                  j<                  }t?        |d      r|j@                  }nttC        |
      |k(  r|j+                  |j4                          |D ]  }	 |jG                  ||
tI        |d            }|jJ                  D ]  }|jL                  xs i }|jO                  d      xs; |jO                  d      xs( |jO                  d      xs tQ        jR                  |      }tU        t?        |d      rtW        |jX                        ndd      }|j+                  t-        d| t        |      dd ||jO                  d      t        |jZ                        d               	 |S # t(        $ r% |j+                  t-        d	d
dddi             |cY S w xY w# tD        $ r Y w xY w# tD        $ r Y dw xY w# tD        $ r7}|j+                  t-        d	d| ddt        |      i             Y d}~|S d}~ww xY ww)z3Vector similarity search across Qdrant collections.r   QdrantClientNr   r   urlapi_keyr9   TextEmbeddingBAAI/bge-small-en-v1.5qdrantzU[SKIP] fastembed not installed -- run: pip3 install fastembed --break-system-packagesrQ   rR   zfastembed not installedrP   size   )collection_namer5   r6   rw   r   
chunk_textrK   r   zqdrant:  r   r   z[ERROR] Qdrant search failed: ).qdrant_clientr   qdrant_client.modelsmodelssysr   insertr0   r   r   elestio_configQdrantConfigr   r   rU   	fastembedr   listembedtolistImportErrorr[   r   get_collectionscollectionsget_collectionrm   points_countconfigrp   vectorshasattrr   r   r]   query_pointsr\   pointsre   rG   rB   r   r   r2   rK   rO   )r5   r6   rC   r   qmodelsr   r   r^   r   embedding_modelquery_vectorsearchable_collectionscolcol_info
vec_configvec_sizer   search_resultspointre   rw   rK   ra   s                          r)   search_qdrantr   a  s    "$GT
..3tL1F:=MMNO,,.

NN"
	/+,DEO 5 5ug >?BIIKL "$))+77 	C!00:((X-B-BQ-F!)!7!7!?!?Jz62#-?? <(H4.55chh?	  6 	O!'!4!4$3&eQ- "5 "
 ,22 E#mm1rGF+ /";;y1/";;|4/  ::g.	  "w8O%"4UXZ[\ENN$%,_,=#>$'IdsO&+(/F(;&)%((m&	
	N NE  		NN#s!%'@A	 N		0  <    
8<!3q6*		
 	
 N
s   L(A?K% :J  K%  A/KK% )K9K% DKK% L(+K?K%  L(KK% 	KK% KK% 	K"K% !K""K% %	L%.,L L( L%%L(doc_idc           	      z  K   	 ddl m} ddlm} ddlm} t        j                  j                  dt        t        t              dz  dz               ddl}|j                         } ||j                  |j                  t               } |d      }	t#        |	j%                  | g            d   j'                         }
|4t)        j*                  d	      }t        t)        j,                  ||             }|j.                  xs d
}	 |j1                  |       d| i|}|j?                  ||jA                  ||
|      g       d||dS # t2        $ rD |j5                  ||j7                  t9        |
      |j:                  j<                               Y ~w xY w# t2        $ r}dt        |      dcY d}~S d}~ww xY ww)z'Store content in Qdrant with embedding.r   r   Nr   r   r   r   r   z$e2a6d7f8-b3c4-4d5e-8f90-a1b2c3d4e5f6genesis_vectors)r   distance)r   vectors_configr   )rO   vectorre   )r   r   T)r   rO   
collectionFr   rR   )!r   r   r   r   r   r   r   r   r   r0   r   r   r   r   r   r   rU   r   r   r   r   UUIDuuid5r   r   r]   create_collectionVectorParamsr   DistanceCOSINEupsertPointStruct)r   r   r   r   r   r   r   r   r^   r   r   	namespacer   re   ra   s                  r)   store_qdrantr	    s    %2..+3tL1F:=MMNO,,.&**fnnn]'(@Ao++WI67:AAC>		"HIIIw78F 00E4E	!!/2 g22+''6&''RS 	 	
 fOLL  	$$ /&33Vw/?/?/F/F  4   % 	  2#a&112sZ   F;C?F E 1F F;A
FF FF 	F8 F3-F8.F;3F88F;c                 $  K   d}	 ddl m} ddlm} t        j
                  j                  dt        t        t              dz  dz               ddl
}|j                         } ||j                  |j                  t              }|j                         j                   D ]6  }	 |j#                  |j$                  |j'                  | g             |d	z  }8 d
|dS # t(        $ r Y Iw xY w# t(        $ r}dt        |      dcY d}~S d}~ww xY ww)z1Delete a point from all Qdrant collections by ID.r   r   Nr   r   r   )r   )r   points_selectorr   T)r   deleted_from_collectionsFr   )r   r   r   r   r   r   r   r0   r   r   r   r   r   r   rU   r   r   deleterm   PointIdsListr]   )	r   deletedr   r   r   r   r^   r   ra   s	            r)   delete_qdrantr    s     G2..3tL1F:=MMNO,,.&**fnnn]))+77 	C$'HH$+$8$8$8$I   1	 GDD    2#a&112sY   DBC, #3CC, D	C)&C, (C))C, ,	D5DDDDDc                 `  K   g }	 ddl }t        j                  j                  dt	        t        t              dz  dz               ddl} |j                  d"i |j                  j                         }|j                  d       |j                         }d| z   dz   }| j                         D cg c]!  }t        |      dkD  s|j                         # }	}d	j!                  d
gt#        t        |	      d      z        }
	 |j%                  d||f       |j'                         D ]`  }|\  }}}}|j)                  t+        dt	        |      dd t-        t/        t1        t	        |      |	      dz   d      d      ||d             b 	 	 |j%                  d||||f       |j'                         D ]Z  }|\  }}}}}t	        |      }|r|d| z  }|j)                  t+        d|dd t-        t5        |xs d      d      ||d             \ 	 	 |j%                  d||||f       |j'                         D ]]  }|\  }}}}}| d|xs d }|j)                  t+        d|dd t-        t/        t5        |xs d      dz  d      d      ||d             _ 	 |j7                          |j7                          |S c c}w # t2        $ r Y @w xY w# t2        $ r Y w xY w# t2        $ r Y Qw xY w# t2        $ r7}|j)                  t+        dd| d d!t	        |      i             Y d}~|S d}~ww xY ww)#z.Full-text search across key PostgreSQL tables.r   Nr   r   T)
autocommit%r   z OR zcontent ILIKE %sr   z
                SELECT content, memory_type, source, created_at
                FROM memory_bloodstream
                WHERE content ILIKE %s
                ORDER BY created_at DESC
                LIMIT %s
                zpostgres:memory_bloodstreamr   g333333?rM   )memory_typer   rP   a  
                SELECT quote, context, category, source_title, confidence
                FROM ponte_goldmine
                WHERE quote ILIKE %s OR context ILIKE %s OR category ILIKE %s
                ORDER BY confidence DESC NULLS LAST
                LIMIT %s
                z

Context: zpostgres:ponte_goldminer   )categorysource_titlea   
                SELECT name, description, category, priority_score, source
                FROM technologies
                WHERE name ILIKE %s OR description ILIKE %s OR category ILIKE %s
                ORDER BY priority_score DESC NULLS LAST
                LIMIT %s
                : rF   zpostgres:technologiesr   )r  r   postgresz"[ERROR] PostgreSQL search failed: rQ   rR   r4   )psycopg2r   r   r   r0   r   r   r   connectPostgresConfigget_connection_paramsset_sessioncursorrx   r   r   rY   maxexecutefetchallr[   r   r   r\   r   r]   r2   close)r5   r6   rC   r  r   conncursearch_patternr   r   keyword_conditionsrowr   r  r   
created_atquotecontextr  r  
confidencerm   descriptionpriority_scorera   s                            r)   search_postgresr.    sf    "$Gh
3tL1F:=MMNOxX."?"?"U"U"WXD)kkmus*',{{}C!A
AGGICC#[[*<)=CMST@U)UV	KK  '	 ||~ 	;>8fj < #GTc 2"'N3w<,RUX,XZ](^`a"b1<!O			KK  G	 ||~ EHBw,
e*WI66G 8 '"'j.?C(@!"D.6!U	"	KK  G	 ||~ 
FICk8^V!F"[%6B$78 6 '"'E.2GC,H4,OQT(UWX"Y.6&!I	
 			

 N} D2  		8  		4  		  
!<QC@!3q6*		
 	
 N
s   L.B*K+ 0J8J8*K+ BJ= K+ 
BK K+ BK !K+ 6L.8K+ =	K
K+ 	K

K+ 	KK+ KK+ 	K(%K+ 'K((K+ +	L+4,L& L.&L++L.c                   K   	 ddl }t        j                  j                  dt	        t        t              dz  dz               ddl} |j                  di |j                  j                         }|j                         }t	        t        j                               }|j                  dd      }|j                  dd      }t        j                   |j#                         D 	
ci c]  \  }	}
|	d	vs|	|
 c}
}	      }|j%                  d
|| |||f       |j'                          |j)                          |j)                          d|dS c c}
}	w # t*        $ r}dt	        |      dcY d}~S d}~ww xY ww)z5Store content in PostgreSQL memory_bloodstream table.r   Nr   r   type	hub_storer   r   )r0  r   a   
            INSERT INTO memory_bloodstream (id, content, memory_type, source, metadata, created_at)
            VALUES (%s, %s, %s, %s, %s, NOW())
            ON CONFLICT (id) DO UPDATE SET content=EXCLUDED.content, metadata=EXCLUDED.metadata
            T)r  rO   Fr  rR   r4   )r  r   r   r   r0   r   r   r   r  r  r  r  r   r   rG   rB   r   itemsr   commitr"  r]   )r   r   r  r   r#  r$  	memory_idr  r   kv
extra_metara   s                r)   store_postgresr9  u  s7    43tL1F:=MMNOxX."?"?"U"U"WXkkm

%	ll6;7h(<=ZZ(..2B b$!QaOaFaA bc

 fjA	
 			

 	22 !c  4!CF334sN   E5C!E %E
2E
7AE 
E5E 	E2E-'E2(E5-E22E5c                   K   	 ddl }t        j                  j                  dt	        t        t              dz  dz               ddl} |j                  d
i |j                  j                         }|j                         }|j                  d| f       |j                  }|j                          |j                          |j                          d|dS # t         $ r}dt	        |      d	cY d}~S d}~ww xY ww)z.Delete a record from memory_bloodstream by ID.r   Nr   r   z,DELETE FROM memory_bloodstream WHERE id = %sT)r  r  Fr2  r4   )r  r   r   r   r0   r   r   r   r  r  r  r  r   rowcountr4  r"  r]   )r   r  r   r#  r$  r  ra   s          r)   delete_postgresr<    s     43tL1F:=MMNOxX."?"?"U"U"WXkkmBVIN,,		

 W55 4!CF334s5   C:CC C:	C7C2,C7-C:2C77C:c                      ddl } t        j                  j                  dt	        t        t              dz  dz               ddl}|j                  j                         } | j                  di |S )z&Get Redis client using Elestio config.r   Nr   r   r4   )redisr   r   r   r0   r   r   r   RedisConfigr  Redis)	redis_libr   rp   s      r)   _get_redis_clientrB    sW    HHOOAs4-69IIJK''==?F9??$V$$r+   r   c                     	 t               }|j                  d|        }||S t        |      S # t        $ r%}t        j                  d| d|        Y d}~yd}~ww xY w)z2Fast Redis recall by key. Returns None if missing.gmh:NzRedis recall failed for key=r  )rB  rG   r0   r]   logwarning)r   r   valuera   s       r)   recall_redisrH    sc    SEl#u53u:5 23'A3?@s   !/ 
/ 	AAArG  ttl_secondsc                     	 t               }|j                  d|  ||       y# t        $ r%}t        j	                  d| d|        Y d}~yd}~ww xY w)z;Store key/value in Redis with TTL. Returns True on success.rD  TzRedis store failed for key=r  NF)rB  setexr]   rE  rF  )r   rG  rI  r   ra   s        r)   store_redisrL    sU    	$sek51 1#1#>?s    # 	AAAc                     	 t               }|j                  d|        }|dkD  S # t        $ r%}t        j	                  d| d|        Y d}~yd}~ww xY w)z5Delete a key from Redis. Returns True if key existed.rD  r   zRedis delete failed for key=r  NF)rB  r  r]   rE  rF  )r   r   r  ra   s       r)   delete_redisrN    sZ    ((T#<({ 23'A3?@s   "% 	AAA)rL   r   file_kgr   r  
   r   systemsverbosec                 X  K   |xs t        t        j                               }|D cg c]  }|t        v st        |   | |       }}t        j                         }t	        j
                  |ddi d{   }t        j                         |z
  }	g }
|D cg c]  }|t        v s| }}t        |      D ]|  \  }}|t        |      k  r||   nd}t        |t              r0|
j                  t        |d| d| ddt        |      i	             [t        |t               sl|
j                  |       ~ t               }g }|
D ]  }|j                  j!                         j#                         dd
 }|j%                  d      s|j%                  d      r|r|j                  |       d||vsi|j'                  |       |j                  |        |j)                  d d       |r2|j                  t        dd|	ddt        |       dd|	|d	             |d| S c c}w 7 c c}w w)a  
    Search ALL Genesis memory systems in parallel.
    Returns merged, deduplicated, relevance-sorted results.

    Args:
        query: Natural language search query
        max_results: Maximum total results to return
        systems: Which systems to query (default: all). Options:
                 supermemory, graphiti, file_kg, qdrant, postgres
        verbose: If True, includes timing info in error results
    return_exceptionsTNunknownz[ERROR] z	 failed: rQ   rR   rP   x   z[error]z[skip]c                     | j                   S r   r   )xs    r)   r   zquery_all.<locals>.<lambda>  r   r+   r   _metazQuery completed in r%   z	s across z systems)elapsedrQ  )r   ALL_SYSTEMSkeystimeasynciogatherr   r   r   r]   r[   r   r0   extendsetr   rZ   r   ry   addr   )r5   r   rQ  rR  selectedstasksstartraw_resultsrZ  all_resultssystem_namesir   sys_nameseendedupedr   s                     r)   	query_allrn    s    " 2${//12H9AVAQ+EU[^E;/VEVIIKEFFFKiikE!G&(K'<!1+;A<L<+& "1&'#l*;&;<?a##&xj	!=!%s1v.	 4 q!" UD"$G iioo%%'->>)$x(@q!d?HHSMNN1 LL*DL9-gc])CM?RZ[%,B		
 <K  a W G =sH   &H*HH.H*5H"6!H*H%%H%)A8H*"B	H*,A7H*%H*c                 F    t        j                  t        | |||            S )z"Synchronous wrapper for query_all.r   rQ  rR  )r^  runrn  )r5   r   rQ  rR  s       r)   
query_syncrr  ,  s     ;;yKZabccr+   top_nc                 
   t        | |      }|sd|  S d|  dg}t        |      D ]  \  }}|j                  j                  d      s|j                  j                  d      r=|j	                  |dz    d|j
                   d	|j                  d
d|j                  dd         |j                  j                  d      r!|j	                  d|j                  d           |j	                  d        dj                  |      S )z
    Quick search returning formatted text. Ideal for injecting into agent context.

    Usage:
        context = quick_search("voice agent pricing")
        # Returns formatted text ready to paste into a prompt
    )r   zNo memories found for: z=== Genesis Memory Search: 'z' ===
[ERROR][SKIP]r   . [] (relevance: r%   z)
   N   r   z	   File: rF   r"   )
rr  r   r   ry   r[   r   r   r   rG   rY   )r5   rs  rC   linesrj  r   s         r)   quick_searchr{  6  s    E2G(00+E7':;E'" 	199	*aii.B.B8.L1ugS
.S0A B))DS/"$	
 ::>>&!LL9QZZ%7$89:R	 99Ur+   systemc                      t        | ||g      S )zSearch a single system only.r   rQ  )rr  )r5   r|  r6   s      r)   search_by_systemr  Q  s    eAAr+   r   indexc                    d| d| j                    d| j                  ddd| j                  j                  t	        d      t	        d      dz         dd	  g}| j
                  j                  d
      r!|j                  d| j
                  d
           | j
                  j                  d      r!|j                  d| j
                  d           dj                  |      S )z'Format a single result for CLI display.  rw  rx  r%   )z     rP  Nr   r   z     File: r  z     Category: r"   )	r   r   r   r&   chrr   rG   r[   rY   )r   r  rz  s      r)   _format_resultr  V  s     UG3qxxjq{{3.?qA
		!!#b'3r7W+<=dsCDEE 	zz~~f{1::f#5"678zz~~j!qzz*'=&>?@99Ur+   c                      e Zd ZdZd Zdeeef   fdZ	 	 ddede	e   de	e
e      deeef   fd	Z	 	 dd
edede	e
e      de
e   fdZdede	e   fdZddedededefdZdedeeef   fdZdeeef   fdZdefdZy)GenesisMemoryHubu  
    Class-based interface for the Genesis Bloodstream Memory Architecture.

    Unifies 5 backends:
      - PostgreSQL  (Elestio) — episodic + structured memory
      - Qdrant      (Elestio) — vector/semantic search
      - Redis       (Elestio) — fast working memory / recall
      - Supermemory (API)     — semantic long-term memory
      - File-based KG         — axioms, entities, relationships (local)

    Usage:
        hub = GenesisMemoryHub()
        await hub.connect()
        await hub.store("pricing is $497/month", {"category": "pricing"})
        results = await hub.search("what is the price?")
        value = hub.recall("last_session_id")
    c                 ~    t        j                  d      | _        d| _        d| _        d| _        d| _        d| _        y )Nr  F)logging	getLoggerrE  
_connected_pg_ok
_qdrant_ok	_redis_ok_supermemory_ok)r'   s    r)   __init__zGenesisMemoryHub.__init__y  s9    $$%78$r+   r    c                   K   | j                          d{   }|j                  dd      | _        |j                  dd      | _        |j                  dd      | _        |j                  dd      | _        d| _        t        d |j                         D              }| j                  j                  d	| d
t        |       d       |S 7 w)zX
        Connect and verify all 5 backends.
        Returns health status dict.
        Nr  Fr   r>  rL   Tc              3   &   K   | ]	  }|sd   ywr   r4   )rH   r7  s     r)   rJ   z+GenesisMemoryHub.connect.<locals>.<genexpr>  s     8aa8s   zGenesisMemoryHub connected: /z backends online)health_checkrG   r  r  r  r  r  r   valuesrE  infor   )r'   status	connecteds      r)   r  zGenesisMemoryHub.connect  s     
 ((**jjU3 **Xu5GU3%zz-?86==?88	4YKqVM]^_ +s   CCB5CNr   r   backendsc                   	
K   |i }|g d}i }d|v rt        |      |d<   d|v rt        |      |d<   d|v rt        |      |d<   d|v r|j                  dt	        j
                  j                               j                         dd       	t        |j                  d	d
            
 t        j                  	
fd             |d<   |si S t        j                  |j                         ddi d{   }i }t        |j                         |      D ],  \  }}t        |t               rt#        |      dd||<   (|||<   . |S 7 Qw)ag  
        Store content to all backends (or specified subset).

        Args:
            content:  Text content to store
            metadata: Optional dict of metadata (type, source, category, etc.)
            backends: Which backends to store to. Default: postgres + qdrant + supermemory

        Returns:
            Dict with results per backend
        N)r  r   rL   r  r   rL   r>  r      ttl  c                  "    dt               iS )Nr>  rL  )r   r   r  s   r)   r   z(GenesisMemoryHub.store.<locals>.<lambda>  s    SRY[^A_7` r+   rT  TF)rR   stored)r9  r	  rf   rG   hashlibmd5encode	hexdigestintr^  	coroutiner_  r  zipr\  r   r]   r0   )r'   r   r   r  re  results_listrC   r6  r   r   r  s    `       @@r)   storezGenesisMemoryHub.store  sR    " H<H! .w AE*x*7H=E(OH$#4Wh#GE- h,,ugkk'..2B&C&M&M&OPSQS&TUChll5$/0CaW../`acE'NI$^^U\\^TtTT"$

l3 	DAq!Y''*1v?

		  Us   C5E:E;AEr5   r6   rQ  c                 :   K   t        |||       d{   S 7 w)a5  
        Semantic search across all memory systems.

        Args:
            query:   Natural language query
            limit:   Maximum results to return
            systems: Specific systems to search. Default: all.

        Returns:
            List of MemoryResult objects sorted by relevance.
        r~  N)rn  )r'   r5   r6   rQ  s       r)   searchzGenesisMemoryHub.search  s     " u%IIIIs   r   c                     t        |      S )z
        Fast Redis recall by key.

        Args:
            key: Lookup key (will be prefixed with 'gmh:')

        Returns:
            String value if found, None if not found or Redis unavailable.
        )rH  )r'   r   s     r)   recallzGenesisMemoryHub.recall  s     C  r+   rG  rI  c                     t        |||      S )a'  
        Store a key/value pair in Redis working memory.

        Args:
            key:         Lookup key
            value:       String value to store
            ttl_seconds: Time-to-live in seconds (default: 1 hour)

        Returns:
            True on success, False on failure.
        r  )r'   r   rG  rI  s       r)   rememberzGenesisMemoryHub.remember  s     3{33r+   r   c                   K   t        |      }t        |      }t        j                  ||d       d{   }|\  }}t	        |      }t        |t              s|ndt        |      it        |t              s|ndt        |      id|idS 7 Vw)z
        Remove a memory from all backends by ID.

        Args:
            doc_id: The document/point/row ID to delete

        Returns:
            Dict with deletion status per backend.
        T)rT  NrR   r  )r  r   r>  )r<  r  r^  r_  rN  r   r]   r0   )r'   r   pg_taskqdrant_taskr  	pg_resultqdrant_resultredis_deleteds           r)   forgetzGenesisMemoryHub.forget  s      "&)#F+$^^G[TXYY#/ 	=$V, *4Iy)I	PWY\]fYgOh+5mY+OmV]_bcp_qUr/
 	
 Zs   2BBABc                 F  K   i }	 ddl }t        j                  j                  dt	        t        t              dz  dz               ddl}ddl}|j                  |        |j                  di |j                  j                         }|j                         }|j                  d       |j                          d|d<   	 dd	lm} t        j                  j                  dt	        t        t              dz  dz               ddl}|j'                         }	 ||	j(                  |	j*                  d
      }
|
j-                          d|d<   	 t/               }|j1                          d|d<   	 t3        j4                  d
      4 d{   }
|
j7                  dddt8         iddi       d{   }|j:                  dv |d<   ddd      d{    	 t<        j?                         }||d<   |S # t         $ r}d| |d<   Y d}~Fd}~ww xY w# t         $ r}d| |d<   Y d}~d}~ww xY w# t         $ r}d| |d<   Y d}~d}~ww xY w7 7 7 # 1 d{  7  sw Y   xY w# t         $ r}d| |d<   Y d}~d}~ww xY w# t         $ r}d| |d<   Y d}~|S d}~ww xY ww)z
        Check the health/connectivity of all 5 backends.

        Returns:
            Dict mapping backend name to True/False (or error string).
        r   Nr   r   zSELECT 1Tr  zERROR: r   ru   r   r   r>  r8   rd   r=   r:   r6   r   )rA   rp   )ry     rL   rO  r4   ) r  r   r   r   r0   r   r   	importlibr   reloadr  r  r  r  r   r"  r]   r   r   r   r   r   r   rB  pingrS   rT   rG   r   status_coder   r   )r'   r  r  r  r   r#  r$  ra   r   cfgr^   r   r_   	kg_existss                 r)   r  zGenesisMemoryHub.health_check  s     "$	/HHOOAs4#5#>AQ#QRS,^,#8##\n&C&C&Y&Y&[\D++-CKK
#JJL!%F:
	-2HHOOAs4#5#>AQ#QRS! --/C!cggs{{ANF""$#F8
	,!#AFFH"F7O
		2((3 G Gv#ZZ<,8K7L.MN#Q< (  
 )-(8(8J(F}%G G	.I )F9 Y  	/#*1#F:	/  	-!(}F8	-  	, 'smF7O	,
GG G G G  	2&-aSMF=!	2  	.")!F9	.s  J!B9G.  B
H H+ +I$ I	I$ 	#I,I-II$ II$ J ,J!.	H
7H?J!H

J!	H(H#J!#H((J!+	I4I<J!IJ!	I$ II$ I!II!I$ $	I?-I:5J!:I??J!	JJJ!JJ!c                 .    | j                   rdnd}d| dS )Nr  znot connectedzGenesisMemoryHub(r  )r  )r'   states     r)   r*   zGenesisMemoryHub.__repr__I  s    #O"5'++r+   )NN)rP  Nr  )r,   r-   r.   r/   r  r   r0   boolr  r   r   r
   r  r  r   r  r  r  r  r  r*   r4   r+   r)   r  r  f  s%   $%tCI & $((,	-- 4.- 49%	-
 
c3h-d '+	JJ J $s)$	J
 
l	J&
!# 
!(3- 
!4C 4 4# 4 4
3 
4S> 
0BDcN BH,# ,r+   r  __main__z<Genesis Memory Hub - Unified query across all memory systems)r,  ?zSearch query)nargshelpz	--systems+z@Systems to search (supermemory graphiti file_kg qdrant postgres)z--max-results)r0  defaultz	--verbose
store_true)actionz--healthzRun health check)r  r  z"
=== Genesis Memory Hub Health ===Tz[OK]z[FAIL]r  r#   r  r   rp  z
=== Genesis Memory Hub: 'z' ===zFound z results in r%   zs
ru  rv  rY  z
--- System Errors ---r"   )ru   r   r  )rP  NF)rP  )kr/   r^  rB   osrer   r]  r   r  r  dataclassesr   r   pathlibr   typingr   r   r   r	   r
   r   rS   environrG   r   r   r   rW   rv   r   rU   r   r   r0   r  rE  r   r  rb   rf   r3   r|   r   r2   r   r   r   r	  r  r.  r9  r<  rB  rH  r  rL  rN  r[  rn  rr  r{  r  r  r  r,   argparseArgumentParserparseradd_argument
parse_argsargshealthhubrq  r  r  printr3  backendokiconexitr5   rY   argv
query_text
print_help
start_timer   rQ  rR  rC   
total_timer   errorsgoodr   r   ry   r[   r   r   rj  ra   metamr   s   0r)   <module>r     s3  8   	 	 
     (  8 8 
 zz~~n.EF	l	/	/ jjnn`  

'BOT  zz~~02RS 3Y?  3tL)F25EEF Gg,- 
 
 
&/C / /D<N /d7S 7D 7T#s(^ 76 -0=A	0G GS Gl9K GZ6 6S	 6e 6E EC E\8J EVXs X3 XtL7I Xx ;?)2)2 )2*23-)2	#s(^)2X2 2S#X 2<l lS ll9K l^4# 4 4$sCx. 4@4# 4$sCx. 4.%c hsm S  3 $ c d  & #'	B!B!B! d3i B! 	B!
 
,B!N #'	ddd d3i d 	d
 
,d C  6BC B BS B$|BT B

l 
3 
3 
 e, e,V z$X$$RF s@
35wx
c2>
L9

<>PQD{{ S--/034!<<> 	/KGR4Z6XDBtfAgYb-.	/ 	5sxx5JJ$$	G z)J	'
|5
9:	F3w<.Z,<C
@AFD 99	*aii.B.B8.LMM!XX KKN	 $" 1nQ"# $,,'( 	0ABqxxj199+./	0 ||":aahh'&9: 	$ABqyyk"#	$ q r ;s   )U$>U$