
    ٟiU                        d Z ddlZddlZddlZddlZddlmZmZmZm	Z	  ej                  dd      Z ej                  dd      ZdZd	Zd
Z ej                  dd      ZeszdZej$                  j'                  e      r] ee      5 ZeD ]G  Zej/                  d      sej1                  dd      d   j3                         j3                  d      Z n ddd       dad Zdedee   fdZ	 	 	 d dee   dedede	e   deeeef      f
dZ 	 	 	 d dededede	e   deeeef      f
dZ!d!dededefdZ"d Z#e$dk(  r e#        yy# 1 sw Y   rxY w)"a  
Genesis RAG Query Engine
========================
Semantic search across the bloodstream knowledge base.

Embeds a query with gemini-embedding-001 (3072d), searches Qdrant
genesis_memories collection, optionally enriches with PostgreSQL metadata.

Usage:
    python3 -m core.rag_query "How does Telnyx assistant creation work?"
    python3 -m core.rag_query --top 10 "GHL pipeline setup"
    python3 -m core.rag_query --json "SubAIVA provisioning"
    N)ListDictAnyOptional
QDRANT_URLz/https://qdrant-b3knu-u50607.vm.elestio.app:6333QDRANT_API_KEY@7b74e6621bd0e6650789f6662bca4cbf4143d3d1d710a0002b3b563973ca6876genesis_memorieszgemini-embedding-001i   GEMINI_API_KEY z(/mnt/e/genesis-system/config/secrets.envzGEMINI_API_KEY==   z'"c                  R    t         ddlm}  | j                  t              a t         S )Nr   )genai)api_key)_clientgoogler   Clientr   )google_genais    '/mnt/e/genesis-system/core/rag_query.py_get_genai_clientr   6   s"    0%%n%=N    textreturnc                     t               }|j                  j                  t        |       }t	        |j
                  d   j                        S )z2Embed a query string using Gemini embedding model.)modelcontentsr   )r   modelsembed_contentEMBED_MODELlist
embeddingsvalues)r   clientresults      r   embed_queryr&   >   sG     F]](( ) F !!!$++,,r   query_vectortop_kscore_thresholdtype_filterc                    ddl m} ddlm}m}m}  |t        t              }d}	|r' | |d ||j                                     g	      }	|j                  t        | |||	d
      }
g }|
j                  D ]  }|j                  xs i }|j                  t        |j                        t!        |j"                  d      |j%                  dd      |j%                  dd      |j%                  dd      xs |j%                  dd      |j%                  dd      xs |j%                  dd      |j%                  dg       |j%                  dd      |j%                  dd      d	        |S )z*Search Qdrant genesis_memories collection.r   )QdrantClient)FilterFieldCondition
MatchValue)urlr   Ntype)value)keymatch)mustT)collection_namequerylimitr)   query_filterwith_payload   titler   
source_urlsourcer   contenttagsplatform
confidence)	idscorer<   r1   r>   r?   r@   rA   rB   )qdrant_clientr,   qdrant_client.modelsr-   r.   r/   r   r   upperquery_points
COLLECTIONpointspayloadappendstrrC   roundrD   get)r'   r(   r)   r*   r,   r-   r.   r/   r$   r9   resultshitspointrK   s                 r   search_qdrantrS   K   sP    +GGj.AFLj{7H7H7J&K
 !!"'! " G D 
--%2%((mu{{A. Wb1FB/!++lB7T7;;xQS;T";;vr2Pgkk)R6PFB/#KK
B7%kk,:
	

  Kr   questionc                 6    t        |       }t        ||||      S )ai  
    Full RAG query: embed question -> search Qdrant -> return results.

    Args:
        question: Natural language query
        top_k: Number of results to return
        score_threshold: Minimum similarity score (0-1)
        type_filter: Optional type filter (e.g., "PRODUCT_SPEC")

    Returns:
        List of matching knowledge entries with scores
    )r'   r(   r)   r*   )r&   rS   )rT   r(   r)   r*   vectors        r   	rag_queryrW      s'    $ "F'	 r   c                 b   t        | |      }|sydt        |       dg}t        |d      D ]p  \  }}|j                  d| d|d    d	|d
    d|d    d	       |j                  d|d           |d   dd }|j                  d|        |j                  d       r dj	                  |      S )z
    RAG query that returns a formatted context string ready for LLM injection.

    This is the function agents should call to get relevant knowledge
    before generating a response.
    r(   z,[No relevant knowledge found in bloodstream]z=== BLOODSTREAM KNOWLEDGE (z matches) ===
r   [] r<   z	 (score: rD   z, type: r1   )z    Source: r>   r?   Ni  z    r   
)rW   len	enumeraterL   join)rT   r(   rP   linesirr?   s          r   rag_contextrd      s     .G=*3w<.HIE'1% 1q2aj\1W:,hqykQRST|AhK=12I,t$tG9%&R 99Ur   c            
      |   t        j                  d      } | j                  dd       | j                  dt        dd	       | j                  d
t        dd	       | j                  ddd       | j                  ddd       | j                  ddd       | j                         }|j                  r+t        t        |j                  |j                               y t        |j                  |j                  |j                  |j                        }|j                  r&t        t        j                  |dt                      y |st        d       y t        dd        t        d|j                          t        dt#        |       d t$         d!t&                t        d d       t)        |d"      D ]  \  }}t        d#| d$|d%           t        d&|d'    d(|d)    d*|d+           |d,   d d- }t        d.| d/       |d0   r#t        d1d2j+                  |d0   d d               t                 y )3NzGenesis RAG Query Engine)descriptionr7   zSearch query)helpz--top   zNumber of results)r1   defaultrg   z--threshold333333?z	Min scorez--typer*   zFilter by type)destrg   z--json
store_truezJSON output)actionrg   z	--contextzLLM context formatrY   )r(   r)   r*      )indentri   zNo results found.r]   zF======================================================================z  RAG QUERY: z  Results: z | Collection: z | Dim: r   z  [r[   r<   z      Score: rD   z  |  Type: r1   z  |  Source: r>   r?      z      z...r@   z      Tags: z, )argparseArgumentParseradd_argumentintfloat
parse_argscontextprintrd   r7   toprW   	thresholdr*   jsondumpsrM   r^   rI   
VECTOR_DIMr_   r`   )parserargsrP   rb   rc   r?   s         r   mainr      s   $$1KLF
n5
c1;NO
E3[Q
};KL
MJ
L?STD||k$**DHH56

hh$$	G yydjjC89!"	Bvh-	M$**
&'	KG~_ZL
UV	VHB-'1% 1A3b7%&aj\QvYK}Qx[MZ[I,t$wis#$V9L1V9Ra=!9 :;<r   __main__)rh   rj   N)rh   )%__doc__ossysr{   rq   typingr   r   r   r   getenvr   r   rI   r    r}   r   secrets_pathpathexistsopenfline
startswithsplitstripr   r   rM   ru   r&   rt   rS   rW   rd   r   __name__ r   r   <module>r      s   
 
   , ,
 RYYC
 F  
$
+R0=L	ww~~l#, 	1 ??#45%)ZZQ%7%:%@%@%B%H%H%ON	 -c -d5k -  !%	0u+00 0 #	0
 
$sCx.0p  !%	  #	
 
$sCx.6# c # 2)X zF q	 	s   E5EE