
    `gj8                       d Z ddlm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 ddlmZ ddlmZ ddlmZmZmZmZmZ d(d)d	Zd*d+d
Zd,dZd-d.dZd/dZd0dZd1dZd2dZd3dZ d2dZ!d2dZ"d4dZ#dZ$dZ%dZ&d5d6dZ'd6dZ(d7dZ)d8dZ*d9dZ+d:d;dZ,d<dZ-d=dZ.d>d Z/d?d!Z0d@d"Z1dAd#Z2dBd$Z3dCd%Z4dDd&Z5d>d'Z6y)EuB   Setup wizard for Mem0 plugin — interactive and flag-based modes.    )annotationsN)Path)Any)get_hermes_home   )LLM_PROVIDERSEMBEDDER_PROVIDERSVECTOR_PROVIDERS
KNOWN_DIMSvalidate_oss_configc                l    ddl m} |D cg c]  \  }}|r| d| n| }}} || |||      S c c}}w )z*Interactive single-select with arrow keys.r   )curses_radiolist  )selectedcancel_returns)hermes_cli.curses_uir   )titleitemsdefaultr   labeldescdisplay_itemss          M/root/.hermes/venv/lib/python3.12/site-packages/plugins/memory/mem0/_setup.py_curses_selectr      sS    5 !E4 #5'D6-M  E=7SZ[[	s   0c                V   |rd| dnd}|rt         j                  j                  d|  | d       t         j                  j                          t         j                  j                         rt        j                  d      }nt         j                  j                         j                         }not         j                  j                  d|  | d       t         j                  j                          t         j                  j                         j                         }|xs |xs dS )z<Prompt for a value with optional default and secret masking.z [] r   : )prompt)	sysstdoutwriteflushstdinisattygetpassreadlinestrip)r   r   secretsuffixvals        r   _promptr,   %   s     'r'!_RF

2eWVHB/0

99//,C))$$&,,.C

2eWVHB/0

ii  "((*!7=b!    c                 z     t        t        j                  dd         d   dk(  ryt         fddD              ryy)	z3Check if OSS-related flags are present in sys.argv.r   NmodeossTc              3  @   K   | ]  }j                  |        y wNget).0kflagss     r   	<genexpr>z has_oss_flags.<locals>.<genexpr>;   s     
VA599Q<
Vs   )oss_llm_keyoss_vector_pathoss_vector_urlF)parse_flagsr    argvany)r7   s   @r   has_oss_flagsr?   6   s;    %EV}

V!U
VVr-   c                   | | nt         j                  dd }i ddddddddd	dd
dddddddddddddddddddddddddddd}i dddddddddd	dd
ddd dd!dd"dd#dd$dd%dd&dd'dd(dd)dd*d+d,d-}d.}|t        |      k  rV||   d/k(  rd0|d1<   |dz  }n4||   |v r(|dz   t        |      k  r||dz      ||||      <   |d2z  }n|dz  }|t        |      k  rV|S )3z7Parse CLI flags from argv. Returns dict of flag values.Nr   r/   r   api_keyhostoss_llmopenair9   oss_llm_modeloss_llm_urloss_embeddeross_embedder_keyoss_embedder_modeloss_embedder_url
oss_vectorqdrantr:   r;   oss_vector_hostoss_vector_portoss_vector_userF)oss_vector_passwordoss_vector_dbnameuser_iddry_runz--modez	--api-keyz--hostz	--oss-llmz--oss-llm-keyz--oss-llm-modelz--oss-llm-urlz--oss-embedderz--oss-embedder-keyz--oss-embedder-modelz--oss-embedder-urlz--oss-vectorz--oss-vector-pathz--oss-vector-urlz--oss-vector-hostz--oss-vector-portz--oss-vector-userrP   rQ   rR   )z--oss-vector-passwordz--oss-vector-dbnamez	--user-idr   z	--dry-runTrS      )r    r=   len)r=   argsr7   flag_mapis        r   r<   r<   @   sn   #4!"D2 	 	8	
 	r 	 	r 	 	B 	b 	B 	h 	2 	" 	2  	2!" 	2#$  "+E0&Y 	& 	Y	
 	 	? 	 	. 	0 	 4 	0 	 	. 	, 	.  	.!" 	.#$ "72)H. 	
A
c$i-7k!#E)FA!W QUSY%6'+AE{E(47#$FAFA c$i- Lr-   c                X   | j                  dd      }t        |   }| j                  d      xs |d   }d|i}| j                  d      xs |j                  d      }|r|j                  d      r|||d   <   | j                  d	d      }t        |   }| j                  d
      xs |d   }d|i}	| j                  d      xs |j                  d      }
|
r|j                  d      r|
|	|d   <   t        j                   |      }|r||	d<   | j                  dd      }t        |   }t        |d         }|dk(  rE| j                  d      r| d   |d<   | j                  d      r|j                  dd       | d   |d<   n|dk(  r| j                  d      r| d   |d<   | j                  d      rt        | d         |d<   | j                  d      r| d   |d<   | j                  d      r| d   |d<   | j                  d      r| d   |d<   ||d ||	d ||d d!}i }|j                  d"      r| j                  d#      r| d#   ||d$   <   |j                  d"      r | j                  d%      r| d%   ||d$   <   ||fS |j                  d"      r!||k(  r| j                  d#      r| d#   ||d$   <   ||fS )&zBuild OSS config dict + env_writes from parsed flags.

    Returns (oss_config, env_writes) where oss_config goes into mem0.json
    and env_writes maps env var names to secret values for .env.
    rC   rD   rE   default_modelmodelrF   default_urlbase_url_keyrG   rI   rJ   embedding_dimsrK   rL   default_configr:   pathr;   NurlpgvectorrM   rB   rN   portrO   userrP   passwordrQ   dbname)providerconfig)llmembeddervector_store	needs_keyr9   env_varrH   )r4   r   r	   r   r
   dictpopint)r7   llm_idllm_def	llm_model
llm_configllm_urlembedder_idembedder_defembedder_modelembedder_configembedder_urldims	vector_id
vector_defvector_config
oss_config
env_writess                    r   build_oss_configr      s    YYy(+FF#G		/*Fgo.FI")9!5Jii&D'++m*DG7;;~..5
7>*+))NH5K%k2LYY34U_8UN'.&?O99/0SL4D4D]4SL((88D^45>>.)D,0()		,1I!),J$456MH99&'$)*;$<M&!99%&fd+#()9#:M% 	j	 99&'$)*;$<M&!99&'$'.?(@$AM&!99&'$)*;$<M&!99*+(-.C(DM*%99()&+,?&@M(# #j9!,H%.-HJ "$J{{;EIIm$<).})=
79%&$3E)F.34F.G
<	*+ z!! 
		+	&;&+@UYY}E].3M.B
<	*+z!!r-   c                h   | j                   j                  dd       g }| j                         r| j                         j	                         }t               }g }|D ]~  }d|v r4|j                  d      s#|j                  dd      d   j                         nd}|r/||v r+|j                  | d||           |j                  |       n|j                  |        |j                         D ]   \  }}||vs|j                  | d|        " | j                  dj                  |      dz          y)	z'Append or update env vars in .env file.Tparentsexist_ok=#r   r   N
)parentmkdirexists	read_text
splitlinesset
startswithsplitr(   appendaddr   
write_textjoin)	env_pathr   existing_linesupdated_keys	new_linesline	key_matchr6   vs	            r   
_write_envr      s.   OO$6 "N!++-88: ULI #58D[Y\I]DJJsA&q)//1cg	j0	{!Jy,A+BCDY'T"#   " )1L s!A3Z() 		),t34r-   c                "   t        |       dz  }i }|j                         r&	 t        j                  |j	                  d            }|j                  |       |j                  t        j                  |d      dz          y# t
        $ r Y Fw xY w)zMerge-write to mem0.json.	mem0.jsonzutf-8)encodingrT   )indentr   N)	r   r   jsonloadsr   	Exceptionupdater   dumps)hermes_homedataconfig_pathexistings       r   _save_mem0_jsonr      s    {#k1KH	zz+"7"7"7"IJH OOD4::hq9D@A  		s   %B 	BBc                   dddddddddd	d
dddd
dddddgdg}i }t        |       dz  }|j                         r$	 t        j                  |j	                               }t        |      }i }t        d       |D ]  }|d   }	|j                  d|	      }
|j                  d      }|j                  dd      }|j                  d      }|j                  d      }|j                  d      }|j                  d      r|	dk(  r	|d   |d<   |r|s|D cg c]  }|df }}|j                  |	|      }d}|rCt        |      j                         |v r(|j                  t        |      j                               }t        d|
 ||       }||   ||	<   |r~|r t        j                  j                  |d      nd}|r,t        |      d!kD  rd"|d#d$  nd%}t!        |
 d&| d'd(      }n|rt        d)|        t!        |
d(      }|s|s|||<   |j                  |	      }|xs |}t!        |
|rt        |      nd$       }|s|||	<    |j                  d*      r't        d+|        |rt        d,       t        d-       y$d.|d/<   d|d0<   t        j                  j                  d1d      j#                         r t        d2t        j                  d1    d3       dd4lm} d5|d6   d7<    ||       dd8lm}  |       }|j'                  ||        |rt-        t        |       d9z  |       t        d:       t        d;       t        d<       |rt        d=       t        d>       y$# t
        $ r Y w xY wc c}w )?u   Platform mode setup — uses the framework's schema-based flow.

    Delegates to the same code path the framework uses when post_setup
    doesn't exist, preserving the original platform onboarding experience.
    rA   zMem0 Platform API keyTMEM0_API_KEYzhttps://app.mem0.ai)keydescriptionr)   requiredrm   ra   rR   User identifierhermes-user)r   r   r   agent_idAgent identifierhermesrerankzEnable reranking for recallfalsetrue)r   r   r   choicesr   z
  Configuring mem0:
r   r   r   r)   Fr   rm   ra   r   r   r   r      ...Nr   z (current: , blank to keep)r)   z  Get yours at rS   z 
  [dry-run] Would save config: '  [dry-run] Would write API key to .env  [dry-run] No files written.
platformr/   rB   	MEM0_HOSTu-   
  ⚠ MEM0_HOST is set in your environment (u   ). It overrides platform mode — remove it from ~/.hermes/.env (or unset it) or Hermes will keep routing to the self-hosted server.save_configmem0memoryrg   Mem0MemoryProvider.envz
  Memory provider: mem0!  Activation saved to config.yaml  Provider config savedz  API keys saved to .env$
  Start a new session to activate.
)r   r   r   r   r   r   rn   printr4   strlowerindexr   osenvironrU   r,   r(   hermes_cli.configr   plugins.memory.mem0r   r   )r   rh   r7   schemaexisting_configr   provider_configr   fieldr   r   r   	is_secretr   rm   ra   cchoice_itemscurrentcurrent_idxselr   maskedr+   effective_defaultr   r   rg   s                               r   _setup_platformr      s    *AT_cp~  H]  	^*;V+=(S)FSZhnpwgxy	F O{#k1K	"jj)>)>)@AO ?+O!#J	
#$ %+Elyy,))I&IIh.	))I&))I&ii99YC9$4).y)9J~&9-45QG5L5%))#w7GK3w<--/7:%mmCL,>,>,@A 2dVlKPC#*3<OC 6=rzz~~gr22H25h-!2C3x}o.k&9IJSWXOC512d40w&)
7#%))#.G ' 27$BS,=(>Y]^C'*$K%+N yy1/1BCD;</0(OF !OF
 
zz~~k2&,,.

;'( )11	
 .#)F8Z 6!#H+64$v-z:	
%&	
-.	
#$()	
23u  		, 6s   #M* M:*	M76M7c                2   ddl }ddlm} 	 |j                  | j	                  d       dd      }|j                  |d       t        d	|         y# |j                  j                  $ r t        d
|         Y yt        $ r t        d|  d       Y yw xY w)zIBest-effort reachability check for a self-hosted Mem0 server (non-fatal).r   N/z/docsGETmethod   timeoutu     ✓ Mem0 server reachable at u      ✓ Mem0 server responding at u     ⚠ Could not reach u2    — check the URL and that the server is running.)
urllib.errorurllib.requestrequestRequestrstripurlopenr   error	HTTPErrorr   )rB   urllib_urlreqreqs       r   _check_selfhosted_serverr   R  s    $aooS!1 2%8oGQ'/v67<<!! 9078 a&tf,^_`as   AA 'B<BBc                6   i }t        |       dz  }|j                         r$	 t        j                  |j	                               }t        |      }t        d       |j                  d      xs  t        d|j                  d      xs d      }|st        dt        j                         y|j                  d	      }i }|j                  d
      r	|d
   |d<   n`t        j                  j                  dd      }|r*t        |      dkD  rd|dd  nd}	t        d|	 dd      }
nt        dd      }
|
r|
|d<   |j                  d      xs  t        d|j                  d      xs d      }t        d|j                  d      xs d      }|j                  d      r8t        d| d| d|        |rt        d        t!        |       t        d!       yd"|d#<   ||d<   ||d<   ||d<   d$d%lm} d&|d'   d(<    ||       d$d)lm}  |       }|j%                  ||        |rt+        t        |       d*z  |       t!        |       t        d+       t        d,|        t        d-       t        d.       |rt        d/       t        d0       y# t
        $ r Y Rw xY w)1u   Self-hosted mode setup — point at an existing Mem0 dashboard server.

    For users already running the Dockerized Mem0 FastAPI server: stores the
    server URL (behavioral -> mem0.json) and an optional API key
    (secret -> .env as MEM0_API_KEY).
    r   z*
  Configuring mem0 (self-hosted server):
rB   z,Mem0 server URL (e.g. http://localhost:8888)Nr   z7  Error: a server URL is required for self-hosted mode.filer   rA   r   r   r   r   r   r   zServer API key (current: r   Tr   z'Server API key (blank if AUTH_DISABLED)rR   r   r   r   r   r   rS   z%
  [dry-run] Would save config: host=z
, user_id=z, agent_id=r   r   r   r/   r   r   r   r   rg   r   r   z&
  Memory provider: mem0 (self-hosted)z
  Server: r   r   z  API key saved to .envr   )r   r   r   r   r   r   rn   r   r4   r,   r    stderrr   r   r   rU   r   r   r   r   r   r   )r   rh   r7   r   r   r   rB   r   existing_keyr   r+   rR   r   r   r   rg   s                   r   _setup_selfhostedr   b  s    O{#k1K	"jj)>)>)@AO ?+O	
8999V 6##F+3t!D GcjjY;;sD!#Jyy%*9%5
>"zz~~nb925l2Ca2Gs<,-.UF5fX=MNW[\CCDQC),J~&ii	" g?#6#6y#A#R]'G )?3F3Fz3R3^V^_Hyy6tfJwi{[cZdef;< &/0(OF"OF!(OI"*OJ-#)F8Z 6!#H+64$v-z:T"	
34	Jtf
	
-.	
#$'(	
23C  		s   #J 	JJc           	        |j                  d      st        | |       yt        |      \  }}t        |      }|r:|D ]   }t	        d| t
        j                         " t        j                  d       |j                  d      xs t        j                  dd      }|d	   d
   }|d   d
   }	|d   d
   }
|j                  d      rt	        d       t	        d|d	   d
    d|d	   d   j                  dd       d       t	        d|d   d
    d|d   d   j                  dd       d       t	        d|
        |r+t	        ddj                  |j                                       t        |       t	        d       y|rt        t        |       dz  |       t        | d|d|d       t!        ||	|
       ddlm} d |d!   d
<    ||       t        |       t	        d"       t	        d#|d	   d
    d|d	   d   j                  dd       d       t	        d|d   d
    d|d   d   j                  dd       d       t	        d$|
        |rt	        d%       t	        d&       t	        d'       t	        d(       y))u   OSS mode setup — build config from flags or interactive prompts.

    Non-interactive when --mode was set explicitly via flags (post_setup already
    resolved mode). Interactive only when mode was chosen via curses picker.
    _mode_from_flagNz	  Error: r   r   rR   USERr   ri   rg   rj   rk   rS   z!
  [dry-run] OSS config would be:z	    LLM:  (rh   r[   r   )    Embedder: z    Vector: z    Env vars: z, r   r   r0   r   r/   rR   r   r0   r   r   r   r   !   
  ✓ Mem0 configured (OSS mode)    LLM:          Vector:       API keys saved to .env    Config saved to mem0.json    Provider set in config.yamlr   )r4   _setup_oss_interactiver   r   r   r    r   exitr   getenvr   keys_run_connectivity_checksr   r   r   _install_provider_depsr   r   )r   rh   r7   r   r   errorserR   rq   rv   r|   r   s               r   
_setup_ossr    s    99&'{F3-e4J
 ,F 	4AIaS/

3	4ii	"Fbii&FGz*FZ(4K>*:6Iyy23	*U+J78:e;LX;V;Z;Z[bdf;g:hhijkz*5jAB"ZPZE[\dEeEiEijqsuEvDwwxyzYK()N499Z__->#?"@AB ,/04$v-z:K%GQYbl!mn6;	:-#)F8Z Z(	
./	N:e,Z89Ju<Mh<W<[<[\ceg<h;iij
kl	N:j1*=>bJAWX`AaAeAefmoqAr@sst
uv	N9+
&'*+	
)*	
+,	
23r-   c                   t         j                  j                  |d      }|szt        |      dz  }|j	                         r\|j                         j                         D ];  }|j                  | d      s|j                  dd      d   j                         } n |rBt        |      dkD  rd|dd  nd	}t        j                  d
|  d| d      j                         S t        j                  d
|  d      j                         S )z;Prompt for API key, showing masked existing value if found.r   r   r   r   r   r   r   Nr   r   z API key (current: z, blank to keep): z
 API key: )r   r   r4   r   r   r   r   r   r   r(   rU   r&   )r   rm   r   r   r   r   r   s          r   _prompt_api_keyr    s    zz~~gr*H$v-?? **,779 ??gYa=1#zz#q1!4::<H *-h-!*;3x}o&E7*=fXEWXY__aa??Rwj1288::r-   zhermes-pgvectorzpgvector/pgvector:pg17r   c                   t        | |      \  }}|rt        d|  d|        yt        d|  d|        t        j                  d      r	 t	        j
                  ddt        ddgd	d	d
t        j                        }|j                  dk(  rzd|j                  v rlt        dt         d       t	        j
                  ddt        gd	dt        j                         t        | |d       t        | |      \  }}|rt        d       yt        d      j                         j                         }|dv rt        | |      S t        d       yt        d       t        d       y# t        $ r Y ew xY w)zEnsure pgvector is reachable; offer Docker setup if not.

    Returns updated vector_config dict if Docker was started, None otherwise.
    u     ✓ PostgreSQL reachable at :Nz  PostgreSQL not reachable at dockerinspectz--formatz{{.State.Status}}T
   )capture_outputtextr   r$   r   exitedz  Found stopped container 'z', restarting...start   r  r   r$   r   u$     ✓ PostgreSQL container restartedz$  Start pgvector via Docker? [Y/n]: )r   yyeszG  Skipping Docker setup. Make sure PostgreSQL with pgvector is running.z:  Docker not found. Install Docker to auto-start pgvector,z+  or run PostgreSQL with pgvector manually.)_check_pgvectorr   shutilwhich
subprocessrun_PGVECTOR_CONTAINERDEVNULL
returncoder!   _wait_for_portr   inputr(   r   _start_pgvector_docker)rB   rc   ok_resultanswers         r   _ensure_pgvectorr0    sq   
 D$'EB	.tfAdV<=	*4&$
89 ||H	^^9&9:GZ[#$*BTBTF   A%(fmm*C34G3HHXYZ'3FG.2B%/%7%79 tT26'd3A@A =>DDFLLN%%)$55[\JK;<  		s   B9E 	E+*E+c                   	 t        dt         d       t        j                  ddt        gddt        j                         t        j                  ddd	t
        gdd
t        j                         t        dt
         d| d       t        j                  ddddt
        ddt         d| dt        g
dddt        j                         t        | |d       t        | |      \  }}|rt        d|  d|        | |dt        ddS t        d       t        d       | |dt        ddS # t        j                  $ r}t        d|        Y d}~yd}~wt        $ r}t        d |        Y d}~yd}~ww xY w)!z)Pull and start pgvector Docker container.z
  Pulling r   r  pullTx   r  rmz-fr  z  Starting container 'z
' on port r%  z-dz--namez-ezPOSTGRES_PASSWORD=z-pz:5432   )r  r   checkr$      r   u     ✓ pgvector running on r  postgres)rB   rc   rd   re   rf   zJ  Warning: Container started but PostgreSQL not yet accepting connections.zD  It may need a few more seconds. Config will be saved; retry later.z$  Failed to start Docker container: Nz  Docker error: )r   _PGVECTOR_IMAGEr$  r%  r'  r&  _PGVECTOR_PASSWORDr)  r!  CalledProcessErrorr   )rB   rc   r,  r-  r  s        r   r+  r+  +  s   *
?+3/0&/:&*C'//	1
 	$.AB&*B'//	1 	&':&;:dV3OPeT)&'9&:;TF%.
 $j>P>P	R 	tT2.d+A.tfAdV<=d"0B$  ^_XYd"0B$ 
 (( 4QC89  $%s*   DD* !D* *E4=EE4E//E4c                   d}t        j                  d      }t        |      \  }}|s|rlt        d       	 t	        j
                  |dgt        j                  t        j                         t        ddd	       t        |      \  }}|rt        d
       n"t        d       t        d       t        d       y|st        d       y| D ]j  }t        ||      rt        d| d       t        d| d       	 t	        j                  |xs dd|gdt        j                         t        d| d       l y# t        $ r}t        d|        Y d}~d}~ww xY w# t        $ r)}t        d| d|        t        d|        Y d}~d}~ww xY w)zEnsure Ollama is running and required models are pulled.

    Returns True if Ollama is ready, False if user needs to handle it manually.
    http://localhost:11434ollamaz/  Ollama installed but not running. Starting...serve)r!   r   	localhosti,  r  r   u     ✓ Ollama startedz  Could not start Ollama: Nz  Ollama not found. Install it:z1    curl -fsSL https://ollama.com/install.sh | shz"  Or on macOS: brew install ollamaFz9  Warning: Ollama not reachable. Models cannot be pulled.u     ✓ Model 'z' availablez  Pulling 'z"'... (this may take a few minutes)r2  iX  )r   r$   z' pulledz  Warning: Could not pull 'z': z  Run manually: ollama pull T)r"  r#  _check_ollamar   r$  Popenr'  r)  r   _ollama_has_modelr%  )modelsra   
ollama_binr,  r-  r  r[   s          r   _ensure_ollamarF  Z  s   
 #Ch'J#EBCD
8  )%--j6H6H {E2>%c*A01 34EF67IJ  >S%(M%45Kw&HIJ>
 6hFPS%/%7%79eWH56> 5  821#6778,  >3E7#aSAB4UG<==>s0   AD6 7<E6	E?EE	F#FFc                   	 t         j                  j                  |  dd      }t         j                  j                  |d      }t	        j
                  |j                               }|j                  dg       D cg c]  }|j                  dd       }}j                  d	      d
   t        fd|D              S c c}w # t        $ r Y yw xY w)z+Check if Ollama already has a model pulled.	/api/tagsr   r   r   r   rD  namer   r  r   c              3  2   K   | ]  }|v xs |v   y wr2    )r5   n
base_modelr[   s     r   r8   z$_ollama_has_model.<locals>.<genexpr>  s!     @Q5A:0q0@s   F)r   r   r   r   r   r   readr4   r   r>   r   )ra   r[   r   respr   mnamesrM  s    `     @r   rC  rC    s    nn$$uI%6u$E~~%%c1%5zz$))+&,0HHXr,BCqvr"CC[[%a(
@%@@@ D  s$   A<C	  C*C	 C	 		CCc                    	 ddl }| j                  dd      | j                  dd      | j                  dd      | j                  d	d      d
}| j                  d      r| d   |d<   	  |j                  di |}d|_        |j                         }|j                  d       |j                          |j                          t        d       y# t        $ r Y yw xY w# t        $ r}t        d|        Y d}~yd}~ww xY w)z2Create the pgvector extension if it doesn't exist.r   NrB   r@  rc   8  rd   r8  rf   rB   rc   rd   rf   re   Tz%CREATE EXTENSION IF NOT EXISTS vectoru      ✓ pgvector extension enabledz0  Warning: Could not enable pgvector extension: rK  )
psycopg2ImportErrorr4   connect
autocommitcursorexecutecloser   r   )	pg_configrU  conn_paramsconncurr  s         r   _ensure_pgvector_extensionr`    s     fk2fd+fj1--*5	K }}Z "+J"7J	Fx.+.kkm;<		

01#  $  F@DEEFs*   C 'A%C 	CC	C=%C88C=c                   ddl }|j                         |z   }|j                         |k  r,	 t        j                  | |fd      }|j	                          yyy# t
        $ r |j                  d       Y nw xY w|j                         |k  ra7)z/Wait until a TCP port is accepting connections.r   Nr   r   g      ?)time	monotonicsocketcreate_connectionr[  OSErrorsleep)rB   rc   r   rb  deadlinesocks         r   r)  r)    s    ~~')H
..
X
%	++T4L!DDJJL	 &
  	JJsO	 ..
X
%s   )A A54A5c                `    | j                  dd      }| j                  d      }|r| d| dS |S )z?Description for LLM/embedder picker: model + URL if applicable.rZ   r   r\   r   r   r3   )r   r[   ra   s      r   _provider_descriptionrk    s;    EE/2&E
%%
C
3%q!!Lr-   c                    |j                  di       }| dk(  r|j                  dd      S | dk(  r'|j                  dd       d|j                  d	d
       S | S )Nr_   rL   r`   zlocal storagerb   rB   r@  r  rc   rS  r3   )pidr   cfgs      r   _vector_descriptionro    sa    
%% "
%C
hwwv//
j''&+./q1F0GHHJr-   c           
     `   t        j                         D cg c]  \  }}|d   t        |      f }}}t        d|d      }t	        t        j
                               |   }t         |   }i }|d   }	|j                  d      }
|d   rt        |d   |d   |       }|r|||d   <   |dk(  rNt        d	|d    d
      j                         xs |d   }	t        d|d    d
      j                         xs |d   }
t        j                         D cg c]  \  }}|d   t        |      f }}}t        d|d      }t	        t        j
                               |   }t        |   }|d   }|j                  d      }|d   r&||k7  r!t        |d    d|d   |       }|r4|||d   <   n+|d   r&||k(  r!|j                  d      |v r||d      ||d   <   |dk(  rNt        d|d    d
      j                         xs |d   }t        d|d    d
      j                         xs |d   }t        j                         D cg c]  \  }}|d   t        ||      f }}}t        d|d      }t	        t        j
                               |   }g }|dk(  r|j                  |	       |dk(  r|j                  |       |rt        |       d}|dk(  rt               }|st!        j"                  dd      }t        d| d
      j                         xs |}t        d      j                         xs d}t        d      j                         xs d}t        d      j                         xs d}t%        j$                  d      j                         }|t'        |      ||d}|r||d<   t        dt!        j"                  dd       d
      j                         }|xs t!        j"                  dd      }t        d      j                         }|xs d }||j                  d      r|j                  |d   d!      nd!|	|
xs d!|||xs d!||d"	}|rB|d#   |d$<   t)        |d%         |d&<   |d'   |d(<   |j                  d      r|d   |d)<   |d*   |d+<   t+        |      \  } }!|rt-        t/        |       d,z  |       t1        | d-||| d.       t3        |||       |dk(  r|rt5        |       dd/lm}" d0|d1   d2<    |"|       t;        |        t=        d3       t=        d4| d5   d2    d6| d5   d7   j                  d8d!       d9       t=        d:| d;   d2    d6| d;   d7   j                  d8d!       d9       t=        d<|        |rt=        d=       t=        d>       t=        d?       t=        d@       yc c}}w c c}}w c c}}w )Az+Interactive OSS setup using curses pickers.r   zLLM Providerr   rZ   r\   rl   rm   r>  z  LLM model [z]: z  Ollama URL [zEmbedder Providerz	 embedderz  Embedder model [zVector StoreNrb   r   r8  z  PostgreSQL user [z  PostgreSQL host [localhost]: r@  z  PostgreSQL port [5432]: 5432z"  PostgreSQL database [postgres]: z'  PostgreSQL password (blank if none): rT  re   z  User ID [r   z  Agent ID [hermes]: r   r   )	rC   r9   rE   rF   rG   rI   rJ   rK   rR   rB   rM   rc   rN   rd   rO   rP   rf   rQ   r   r0   r  r   r   r   rg   r  r  ri   r   rh   r[   r   r  rj   r  r  r  r  r   )r   r   rk  r   listr  r4   r  r*  r(   r	   r
   ro  r   rF  r0  r   r  r&   rp   r   r   r   r   r   r  r`  r   r   r  r   )#r   rh   rm  r   	llm_itemsllm_idxrq   rr   r   rs   ru   r   embedder_itemsembedder_idxrv   rw   rx   rz   vector_items
vector_idxr|   ollama_modelspgvector_configdefault_userpg_userpg_hostpg_port	pg_dbnamepg_passwordrR   r   r7   r   r-  r   s#                                      r   r	  r	    s7   FSFYFYF[\FC!G*3A67\I\^Y:G-$$&'0FF#G!#J(Ikk-(G{gg.	0BKP-0Jwy)*M'/*B)C3GHNNPlT[\kTl	.)?(@DEKKMgQXYfQgK]KcKcKefaqz#8#;<fNf!"5~qIL)..01,?K%k2L!/2N##M2LK [F%:g!6 7yA<PYCZ\gh25J|I./	k	"{f'<;;y!Z/2<WY=O2PJ|I./h!3L4Q3RRUVW]]_  Acop  dA~l=.I-J#NOUUWv[ghu[vL\LbLbLde&#qQwZ!4S!!<=eLea@J%**,-j9I MY'h^,}% OJ*,99VZ8L1,sCDJJL\P\G=>DDFU+G89??AKVGBCIIKYzI!//*STZZ\KW9O .9
+k"))FM"B!C3GHNNPG96=9G,-335H#8H AHYAWz~~gi&8"=]_"}"#,(.B
E #26#: #&v'>#? #26#: z*+::+FE'(%4X%>!"$U+MJ4$v-z:K%GQYbl!mn6;	:J?"?3-#)F8Z Z(	
./	N:e,Z89Ju<Mh<W<[<[\ceg<h;iij
kl	N:j1*=>bJAWX`AaAeAefmoqAr@sst
uv	N9+
&'*+	
)*	
+,	
23i ]  g$ fs   VV$8V*c           	        t               }t        | ft        |ft        |ffD ]:  \  }}|j	                  |i       j	                  d      }|s*|j                  |       < t        |      D ]L  }	 t        d| d       t        j                  ddddt        j                  |gdd	
       t        d|        N |rddl}|j                          yy# t        $ r t        d| d|        Y w xY w)z5Install all optional pip deps for selected providers.pip_depz  Installing r   uvpipinstallz--pythonT<   )r  r   u     ✓ Installed z  Warning: Could not install z#. Install manually: uv pip install r   N)r   r   r	   r
   r4   r   sortedr   r$  r%  r    
executabler   	importlibinvalidate_caches)rq   rv   r|   depsregistryrm  depr  s           r   r  r  K  s	   UD(&14F3T+Y79 #ll3#''	2HHSM	
 d| 	a	aM#c*+NNuiS^^SI#R $SE*+	a ##%   	a1#6YZ]Y^_`	as   .A	CC.-C.c                    t        |       j                         }|j                  }	 |j                  dd       dd| fS # t        $ r}dd| d| fcY d}~S d}~ww xY w)z7Check that qdrant local storage parent dir is writable.Tr   zDirectory writable: FzCannot write to r   N)r   
expanduserr   r   rf  )r`   pr   r  s       r   _check_qdrant_pathr  b  sn    T
AXXF7TD1+F8444 7(1#6667s   A 	A
	AAAc                    	 t         j                  j                  | j                  d       dd      }t         j                  j	                  |d       y# t
        $ r}dd	|  d
| fcY d}~S d}~ww xY w)z(Check Ollama is reachable via /api/tags.r   rH  r   r      r   )TzOllama reachableFzOllama not reachable at r   N)r   r   r   r   r   r   )ra   r   r  s      r   rA  rA  m  ss    <nn$$

3'8	%B5$QsA.' <0Rs;;;<s   AA 	A4 	A/)A4/A4c                    	 t        j                  | |fd      }|j                          dd|  d| fS # t        $ r}dd|  d| d| fcY d	}~S d	}~ww xY w)
zCheck PGVector via TCP socket.r  r   TzPGVector reachable at r  FzPGVector not reachable at r   N)rd  re  r[  r   )rB   rc   ri  r  s       r   r!  r!  w  sq    F''ta@

-dV1TF;;; F24&$r!EEEFs   25 	AA
AAc                   | j                  di       }|j                  d      dk(  r|j                  di       j                  d      }|j                  di       j                  d      }|rt        |      \  }}|st        d|        n|r	 t        j                  j                  |j                  d       d	d
      }t        j                  j                  |d       ne|j                  d      dk(  rQ|j                  di       }t        |j                  dd      |j                  dd            \  }}|st        d|        | j                  di       }	|	j                  d      dk(  rB|	j                  di       j                  dd      }t        |      \  }}|st        d|        yyy# t        $ r}t        d| d|        Y d}~d}~ww xY w)z+Run connectivity checks and print warnings.rk   rg   rL   rh   r`   ra   z  Warning: r   z/healthzr   r   r  r   z#  Warning: Qdrant not reachable at r   Nrb   rB   r@  rc   rS  ri   r>  ollama_base_urlr=  )r4   r  r   r   r   r   r   r   r   r!  rA  )
r   vsr`   ra   r,  msgr   r  rn  ri   s
             r   r  r    s   		+B	vvjX%vvh#''/ffXr"&&u-(.GBC5)*Hnn,,

3/@-IRW,X&&sA&6 

	z	)ffXr"!#''&+">PT@UVCKu%&
..
#C
wwzh&ggh#''(9;ST$CKu%&  '  H;C51#FGGHs   AF0 0	G9GGc                 L   	 ddl } t        | dd      }|syt        d |j                  d      dd D              }d}||k  rKdj	                  d |D              }t        d	| d
| d       t        dt        j                   d| d       yy# t        $ r Y yt        $ r Y yw xY w)z9Ensure mem0ai meets the minimum version from plugin.yaml.r   N__version__c              3  2   K   | ]  }t        |        y wr2   )rp   r5   xs     r   r8   z)_check_min_dep_version.<locals>.<genexpr>  s     M1AM   .r  )rT   r      c              3  2   K   | ]  }t        |        y wr2   )r   r  s     r   r8   z)_check_min_dep_version.<locals>.<genexpr>  s     >!s1v>r  u   
  ⚠ mem0ai z installed but >=z
 required.z  Run: uv pip install --python z
 'mem0ai>=')
r   getattrtupler   r   r   r    r  rV  r   )r   installed_verinstalled_partsrequired_partsreq_strs        r   _check_min_dep_versionr    s    mT:M0C0CC0H!0LMM"^+hh>~>>GOM?2CG9JWX3CNN3C:gYVWXY ,   s   B A5B 	B#B#"B#c                n   t                t        t        j                  dd       }|d   dk(  rd|d<   t	        | ||       y|d   dv rt        | ||       y|d   dk(  rt        | ||       yg d	}t        d
|d      }|dk(  rt        | ||       y|dk(  rd|d<   t	        | ||       yt        | ||       y)aJ  Entry point called by hermes memory setup framework.

    Routes on --mode (platform / selfhosted / oss); with no flag it shows an
    interactive picker with all three modes. Platform keeps the framework's
    original schema-based onboarding; selfhosted points at an existing Mem0
    server; oss builds a local SDK config.
    r   Nr/   r0   Tr   )
selfhostedzself-hostedr   ))Platformz3Mem0 Cloud API (lightweight, just needs an API key))zSelf-hosted serverz?Connect to an existing self-hosted Mem0 server (Docker/FastAPI))zOpen Sourcez1Run Mem0 locally (self-hosted LLM + vector store)z  Select moder   rT   F)r  r<   r    r=   r  r   r   r   )r   rh   r7   
mode_itemsmode_idxs        r   
post_setupr    s     %EV}#' ;.V}55+vu5V}
"VU3J
 oz1=H1}+vu5	Q#( ;.VU3r-   )r   )r   r   r   zlist[tuple[str, str]]r   rp   returnrp   )NF)r   r   r   z
str | Noner)   boolr  r   )r  r  r2   )r=   zlist[str] | Noner  dict[str, str])r7   r  r  ztuple[dict, dict[str, str]])r   r   r   r  r  None)r   r   r   rn   r  r  )r   r   rh   rn   r7   r  r  r  )rB   r   r  r  )r   r   rm   r   r   r   r  r   )r@  rS  )rB   r   rc   rp   r  zdict | None)rD  z	list[str]r  r  )ra   r   r[   r   r  r  )r\  rn   r  r  )r  )rB   r   rc   rp   r   rp   r  r  )r   rn   r  r   )rm  r   r   rn   r  r   )r   r   rh   rn   r  r  )rq   r   rv   r   r|   r   r  r  )r`   r   r  tuple[bool, str])ra   r   r  r  )rB   r   rc   rp   r  r  )r   rn   r  r  )r  r  )7__doc__
__future__r   r&   r   r   r"  rd  r$  r    r   r   pathlibr   typingr   hermes_constantsr   _oss_providersr   r	   r
   r   r   r   r,   r?   r<   r   r   r   r   r   r   r  r  r&  r9  r:  r0  r+  rF  rC  r`  r)  rk  ro  r	  r  r  rA  r!  r  r  r  rK  r-   r   <module>r     s    H "   	    
    , \""=@<"~5.
Bl4^a M4`54p;  ( * )X,^/d
F4
v4r&.7<F'<&%4r-   