+
    WjZ                      a  0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RI	t]P                  P                  RR4      P                  R4      t]P                  P                  RR4      t]P                  P                  RR4      tR	 R
 ltRLtRMtR R ltR R ltR^ R^R^R^R^R^R^/tR^R^R^R^R^R^R^R^R^	R^
R ^R!^/tR" R# ltR$ R% ltRNR& R' lltROR( R) lltRPR* R+ lltR, R- ltRQR. R/ lltR0 R1 ltR2 R3 ltR4 R5 lt RRR6 R7 llt!R8 R9 lt"RSR: R; llt#R< R= lt$R> R? lt%R@ RA lt&RTRB RC llt'RDRRERF/t(RG])RH&   RI RJ lt*RK t+R# )Uu  Jarvis long-term memory — thin client to the Railway brain.

This is the CLIENT side: it does NO heavy work. It calls the always-on memory
service (a FalkorDB-backed fact graph deployed on Railway — see memory-service/)
over HTTPS. The SERVER now owns the whole WRITE pipeline: on /remember it dedups
against what's already stored and decides add / update (supersede) / no-op
(Mem0-style) via DeepSeek, extracts the event date (``when``) and entities +
relations from the text, and cleans raw utterances into atomic facts. So the
client just ships the note (fire-and-forget) and the graph does the thinking;
searching returns ranked, linked context in ~100ms, with reinforcement-on-access
and optional temporal (`when_from`/`when_to`) filtering.

This is the cross-device brain: the Mac, the Windows box, and the phone all
point at the SAME MEMORY_API_URL, so a fact learned on one device is known on
all of them, and linked to everything else.

Runs IN-PROCESS via the Agent SDK MCP server (key ``"memory"``; Claude sees
``mcp__memory__<name>``). Pure stdlib HTTP — no heavy deps on the device.

Config (``.env``):
  MEMORY_API_URL   the deployed service, e.g. https://jarvis-memory.up.railway.app
  MEMORY_API_KEY   the shared bearer key (matches the service)
  MEMORY_GROUP     namespace (default "ahmed") — lets one brain serve many users
  MEM_SERVER_PIPELINE  set 0 to fall back to the OLD client-side supersede path
                       (the server owns dedup/supersede by default)
Set ``MCP_MEMORY=0`` to disable.
)annotationsNMEMORY_API_URL /MEMORY_API_KEYMEMORY_GROUPahmedc                   V ^8  d   QhRR/# )   returnbool )formats   "voice/memory_control.py__annotate__r   *   s           c                 n    \         P                  P                  RR4      R8X  d   R# \        \        4      # )z0On only when a memory service URL is configured.
MCP_MEMORY10F)osenvirongetr   _URLr   r   r   enabledr   *   s&    	zz~~lC(C/:r   c                    V ^8  d   QhRRRR/# )r
   textstrr   floatr   )r   s   "r   r   r   8   s      c e r   c                d  a T ;'       g    RP                  4       o\        ;QJ d#    V3R l\         4       F  '       g   K   RM	  RM! V3R l\         4       4      '       d   R# \        ;QJ d#    V3R l\         4       F  '       g   K   RM	  RM! V3R l\         4       4      '       d   R# R# )	u   Light heuristic — hedged facts recall weaker, firm facts stronger. The
service uses this in salience ranking (latest+confident wins), never to drop.r   c              3  ,   <"   T F	  qS9   x  K  	  R # 5iNr   .0wts   & r   	<genexpr>_confidence.<locals>.<genexpr><        
!5a65   TFg?c              3  ,   <"   T F	  qS9   x  K  	  R # 5ir!   r   r"   s   & r   r&   r'   >        
"6a66r)   g      ?g      ?lowerany_FIRM_HEDGEr   r%   s   &@r   _confidencer2   8   sd     
A
s
!5
!sss
!5
!!!
s
"6
"sss
"6
"""r   c                    V ^8  d   QhRRRR/# )r
   r   r   r   intr   )r   s   "r   r   r   C   s      c c r   c                d  a T ;'       g    RP                  4       o\        ;QJ d#    V3R l\         4       F  '       g   K   RM	  RM! V3R l\         4       4      '       d   ^# \        ;QJ d#    V3R l\         4       F  '       g   K   RM	  RM! V3R l\         4       4      '       d   ^# ^# )z1-10 importance the server weighs in dedup/salience. Reuses the FIRM/HEDGE
heuristic: firm/committed facts matter more (8), hedged guesses less (3).r   c              3  ,   <"   T F	  qS9   x  K  	  R # 5ir!   r   r"   s   & r   r&   _importance.<locals>.<genexpr>G   r(   r)   TFc              3  ,   <"   T F	  qS9   x  K  	  R # 5ir!   r   r"   s   & r   r&   r7   I   r+   r)   r,   r1   s   &@r   _importancer9   C   sd     
A
s
!5
!sss
!5
!!!
s
"6
"sss
"6
"""r   mondaytuesday	wednesdaythursdayfridaysaturdaysundayjanuaryfebruarymarchaprilmayjunejulyaugust	septemberoctobernovemberdecemberc                    V ^8  d   QhRRRR/# )r
   qr   r   ztuple[str | None, str | None]r   )r   s   "r   r   r   V   s     6 6s 6< 6r   c           	       a ^ RI o^ RIpT ;'       g    RP                  4       pSP                  P	                  4       pR R lpR V3R llpVP                  RV4      pV'       dm    SP                  \        VP                  ^4      4      \        VP                  ^4      4      \        VP                  ^4      4      4      pV! V4      V! V4      3# RV9   d   V! V4      V! V4      3# R	V9   d*   VSP                  ^R
7      ,
          pV! V4      V! V4      3# RV9   dO   VSP                  VP                  4       R
7      ,
          p	V! V	4      V! V	SP                  ^R
7      ,           4      3# RV9   dV   VSP                  VP                  4       ^,           R
7      ,
          p	V! V	4      V! V	SP                  ^R
7      ,           4      3# RV9   d)   VP                  ^R7      p	V! V	4      V! V! V	4      4      3# RV9   dJ   VP                  ^R7      SP                  ^R
7      ,
          p
V! V
P                  ^R7      4      V! V
4      3# VP                  RV4      pV'       dl   VP                  4       \        VP                  ^4      ,          ,
          ^,          ;'       g    ^pVSP                  VR
7      ,
          pV! V4      V! V4      3# VP                  RV4      pV'       dt   \        VP                  ^4      ,          pWP                  8:  d   VP                  MVP                  ^,
          pSP                  W^4      p	V! V	4      V! V! V	4      4      3# R#   \         d     ELi ; i)u   Best-effort: turn a relative-time phrase in the query into an ISO date
window (when_from, when_to) for /search. English phrases + ISO numeric dates
only — deliberately simple, no deps, returns (None, None) if nothing time-like
is present. Kept in sync with the copy in gateway/tools.py.Nr   c                    V ^8  d   QhRRRR/# )r
   d
'_dt.date'r   r   r   )r   s   "r   r   %_temporal_range.<locals>.__annotate__`   s      
 s r   c                "    V P                  4       # r!   )	isoformat)rQ   s   &r   _iso_temporal_range.<locals>._iso`   s    {{}r   c                    V ^8  d   QhRRRR/# )r
   rQ   rR   r   r   )r   s   "r   r   rS   c   s     $ $j $Z $r   c                   < V P                  ^R7      SP                  ^ R7      ,           P                  ^R7      SP                  ^R7      ,
          # )   daydays)replace	timedelta)rQ   _dts   &r   
_month_end#_temporal_range.<locals>._month_endc   sG    		a	 3==b=#99BBqBImmm#$ 	$r   z\b(\d{4})-(\d{2})-(\d{2})\btoday	yesterdayr]   z	this weekz	last weekz
this monthr[   z
last monthzH\b(?:on\s+)?(monday|tuesday|wednesday|thursday|friday|saturday|sunday)\bz`\bin\s+(january|february|march|april|may|june|july|august|september|october|november|december)\b)NN)datetimerer-   daterd   searchr4   group
ValueErrorr`   weekdayr_   	_WEEKDAYS_MONTHSmonthyear)rN   _rer%   rd   rV   rb   mrQ   ystartenddeltamorp   ra   s   &             @r   _temporal_rangerx   V   s   
 	
bAHHNNE$ $ 	

115A	QWWQZ#aggaj/3qwwqz?KA7DG## !|E{DK''aCMMqM))AwQa5==?;;E{DA)>!>???a5==?Q+>??E{DA)>!>???q!$E{DE!2333qmmm"S]]]%::CKKAK&'c22

 )*+	-A9QWWQZ#88A=BBCMMuM--AwQ

 DEF	HAQWWQZ ;;.uzzEJJN1%E{DE!2333A  		s   (A*M M-,M-c                    V ^8  d   QhRRRR/# )r
   msgr   r   dictr   )r   s   "r   r   r      s     8 8s 8t 8r   c                    R RRRV /./# )contenttyper   r   )rz   s   &r   _textr      s    5677r   c               (    V ^8  d   QhRRRRRRRR/# )r
   methodr   pathbodyzdict | Nonetimeoutr4   r   )r   s   "r   r   r      s(     . . .C .{ .C .r   c                
   Ve%   \         P                  ! V4      P                  4       MR p\        P                  P                  \        V,           W@R7      p\        '       d   VP                  RR\         24       VP                  RR4       \        P                  P                  WSR7      ;_uu_ 4       pVP                  4       pV'       d   \         P                  ! V4      M/ uuR R R 4       #   + '       g   i     R # ; i)N)datar   AuthorizationzBearer zContent-Typezapplication/jsonr   )jsondumpsencodeurllibrequestRequestr   _KEY
add_headerurlopenreadloads)r   r   r   r   r   reqrraws   &&&&    r   _reqr      s    (,(84::d""$dD
..
 
 4
 
GCt'$(89NN>#56					5	5ffh"%tzz#2 
6	5	5	5s   60C11D	c                    V ^8  d   QhRRRR/# r
   limitr4   r   
list[dict]r   )r   s   "r   r   r      s     > >s >J >r   c                    \         P                  P                  R\        RV /4      p\	        RRV 24      P                  R. 4      # )z5Newest-first raw brain contents (browse, not search).rj   r   GETz
/memories?memoriesr   parse	urlencode_GROUPr   r   r   qss   & r   list_recentr      s@    			&'5 A	BBB4()--j"==r   c                    V ^8  d   QhRRRR/# r   r   )r   s   "r   r   r      s     > ># >j >r   c                    \         P                  P                  R\        RV RR/4      p\	        RRV 24      P                  R. 4      # )zFUnsurfaced findings from the nightly reflection engine (newest first).rj   r   unsurfaced_onlytruer   z
/insights?insightsr   r   s   & r   fetch_insightsr      sI    			&'5!2F!< 
=BB4()--j"==r   c                    V ^8  d   QhRRRR/# )r
   
insight_idr   r   Noner   )r   s   "r   r   r      s     K K# K$ Kr   c                D    V '       d   \        RRRV R\        /4       R# R# )z7Mark an insight surfaced so Jarvis raises it only once.POST/insight/seenidrj   Nr   r   )r   s   &r   mark_insight_seenr      s    V_tZ&&IJ r   c               $    V ^8  d   QhRRRRRR/# )r
   rN   r   kr4   r   r   r   )r   s   "r   r   r      s!     9 9C 9C 9 9r   c                    \         P                  P                  R V RVR\        /4      p\	        RRV 24      P                  R. 4      # )rN   r   rj   r   /search?factsr   )rN   r   r   s   && r   search_factsr      sC    			aa& A	BB"'++GR88r   c                    V ^8  d   QhRRRR/# )r
   mem_idr   r   r   r   )r   s   "r   r   r      s     = =3 =4 =r   c                0    \        RRRV R\        /4       R# )z"Permanently delete a wrong memory.r   z/forgetr   rj   Nr   )r   s   &r   forgetr      s    T67F;<r   c               $    V ^8  d   QhRRRRRR/# )r
   old_idr   r   r   r   )r   s   "r   r   r      s!       C C r   c                X    \        RRRV RVR\        RR/4      pVP                  RR	4      # )
z:Correct a memory: retire the old, add the new (supersede).r   
/superseder   r   rj   sourcejarvisr   r   )r   r   r   )r   r   outs   && r   editr      s:    
v|&&$($%C 774r   c                    V ^8  d   QhRRRR/# )r
   itemsr   r   r   )r   s   "r   r   r      s     	% 	% 	%
 	%r   c                   V  Uu. uF  qP                  R4      '       g   K  RVP                  RR4      RVP                  RVP                  RR4      4      RVP                  R4      ;'       g    RRVP                  R4      ;'       g    RR,          R	VP                  R	4      ;'       g    RR
\        VP                  R
4      4      /NK  	  up# u upi )z<Normalise /search facts and /memories rows to one HUD shape.r   r   r   factkindwhen	refers_toN
   N
created_atlinked)r   r   )r   fs   & r   _normr      s     % !daeeD"ofaeeFB/0f##{#))r3/aeeL)//R$quuX' % % %s   CAC/C
!C,"Cc                    V ^8  d   QhRRRR/# )r
   rN   r   r   r   r   )r   s   "r   r   r      s     ( (S ($ (r   c                   ^ RI Hp  V P                  4       '       d   \        V 4      M	\	        4       pV! RV \        V4      R7       R#   \         d5   p\        R\        T4      R,           24       T! RT . R7        Rp?R# Rp?ii ; i)uG   Push memories to the HUD viewer — search results if `q`, else recent.emitr   )rN   r   z!  [memory] panel refresh failed: Nd   NN)	voice.eventsr   stripr   r   r   	Exceptionprintr   )rN   r   r   es   &   r   refresh_panelr      sh    !(#$7799Q+-Z1E%L1 (1#a&,@AZ1B''(s   A	 )A	 	B)BBc                   V ^8  d   QhRR/# )r
   r   r{   r   )r   s   "r   r   r      s     J JT Jr   c                     \         P                  P                  R\        /4      p \	        RRV  24      pRVP                  R. 4      RVP                  R. 4      /# )u?   Full memory graph — nodes + edges — for the HUD graph view.rj   r   z/graph?nodesedgesr   )r   r   s     r   fetch_graphr      sR    			& 1	2B
utn
%CSWWWb)7CGGGR4HIIr   c               (    V ^8  d   QhRRRRRRRR/# )r
   ar   br~   r   r   r   )r   s   "r   r   r      s.     A AC AC As A4 Ar   c           
     ,    \        RRRV RVRV/4       R# )z"Connect two memories in the graph.r   z/linkfrom_idtor~   Nr   )r   r   r~   s   &&&r   linkr      s    9aq&$?@r   c               $    V ^8  d   QhRRRRRR/# )r
   r   r   r   r   r   r   )r   s   "r   r   r      s!     5 5c 5c 5d 5r   c                (    \        RRRV RV/4       R# )z8Cut the edge(s) between two memories (either direction).r   z/unlinkr   r   Nr   )r   r   s   &&r   unlinkr      s    Y434r   c                    V ^8  d   QhRRRR/# )r
   r   r   r   r   )r   s   "r   r   r      s     % %z %j %r   c                   V  Uu. uF  qP                  R4      '       g   K  R\        VP                  RR4      4      R\        VP                  RVP                  RR4      4      ;'       g    R4      R\        VP                  R4      ;'       g    R4      R\        VP                  R4      ;'       g    R4      /NK  	  up# u upi )z6Normalise /graph nodes to one HUD shape (all strings).r   r   r   r   r   r   )r   r   )r   ns   & r   _norm_nodesr      s     %
 !dc!%%b/"AEE&!%%"34::;AEE&M''R(c!%%-334	
 % % %s   CA	C,#C#C4Cc                   V ^8  d   QhRR/# r
   r   r   r   )r   s   "r   r   r     s     	* 	*t 	*r   c            	        ^ RI Hp   \        4       pV ! R\        VP	                  R. 4      4      VP	                  R. 4      R7       R#   \
         d5   p\        R\        T4      R,           24       T ! R. . R7        Rp?R# Rp?ii ; i)	z;Push the memory graph to the HUD viewer as a `graph` event.r   graphr   r   )r   r   z!  [memory] graph refresh failed: r   N)r   r   r   r   r   r   r   r   )r   gr   s      r   refresh_graphr     sr    !*MWKgr(:;55"%	' *1#a&,@AWBb))*s   >A B)BBc          
     ,    V ^8  d   QhRRRRRRRRRR/# )	r
   r   r   r   r   z
str | Nonetoner   r   r   )r   s   "r   r   r     s1     <6 <6C <6s <6: <6<6*.<6r   c                   a aaa \        4       '       d   S P                  4       '       g   R# ^ RIpR VV VV3R llpVP                  VRR7      P	                  4        R# )u  Fire-and-forget save — POSTs in a daemon thread and returns instantly, so
the conversation NEVER pauses to remember. Used by the inline
<remember>…</remember> path (the brain drops the note mid-reply; the engine
ships it here without a tool round-trip). Failures are logged, not raised.
`when` = the event date (ISO) if the caller knows it (else the server extracts
it from the text); `tone` = the vocal delivery the fact was said with.

The SERVER now owns dedup/supersede/cleanup (Mem0-style add/update/no-op), so
the default path is a plain /remember. Set MEM_SERVER_PIPELINE=0 to restore
the old client-side supersede round-trip (see memory_supersede.py).Nc                   V ^8  d   QhRR/# r   r   )r   s   "r   r   fire_save.<locals>.__annotate__  s     (H (H (Hr   c                 d  <  SP                  4       p . p\        P                  P                  R R4      R8w  d    ^ RIHp VP                  V 4      pRV R\        RRRSR	\        V 4      R
\        V 4      /pS
'       d   S
VR&   S	'       d   S	VR&   V'       d   WR&   \        P                  P                  RR4      R8X  d   \        P                  P                  RR4      R8w  db   Rp ^ RIHp VP                  V \        V ^R7      4      pV'       d4   WCR&   \        RRV4       \        RVR,           RV R,           R24       R# \        RRV4       R#   \         d     ELi ; i  \         d    Rp Lki ; i  \         d*   p\        R\!        T4      R,           24        Rp?R# Rp?ii ; i)MEM_ENTITIESr   r   )memory_entitiesr   rj   r   r   r   
confidence
importancer   r   entitiesMEM_SERVER_PIPELINEMEM_SUPERSEDEN)memory_supersede)r   r   r   r   z  [memory: superseded :N   Nu    ← ":N2   Nz"]	/rememberz#  [memory] background save failed: :Nx   N)r   r   r   r   voicer  extractr   r   r2   r9   r  find_supersededr   r   r   r   )r%   r  r  r   r   r  r   r   r   r   r   s          r   _gofire_save.<locals>._go  s   '	H

A  Hzz~~nc2c95.66q9H Aw(FD +a.,APD#V#V#+Z  zz~~3S9S@

<C"6-==<Q/1F %+Nt426":,gafXSQRd+7 ! ( ! "!F"  	H7At~FGG	Hsw   6E; E 8E; E; AE; )#E( E; 1E; E; E%!E; $E%%E; (E85E; 7E88E; ;F/F**F/T)targetdaemon)r   r   	threadingThreadrt   )r   r   r   r   r  r  s   ffff  r   	fire_saver    sG     99DJJLL(H (HX C-335r   r   atg        r{   _CORE_CACHEc                   V ^8  d   QhRR/# )r
   r   r   r   )r   s   "r   r   r   P  s       r   c                    \        4       '       g   R# ^ RIp V P                  4       p\        R,          '       d'   V\        R,          ,
          R8  d   \        R,          #  \        P                  P                  R\        /4      p\        RRV 2^R	7      pVP                  R4      ;'       g    RP                  4       pT\        R&   T\        R&   T#   \         d    \        R,          u # i ; i)
u(  The ~200-word pinned profile of Ahmed the nightly reflection maintains
server-side (GET /core_block → {text, updated_at}). Cached 30 min; returns ""
on ANY error and never blocks more than ~2s — safe to call while building the
voice brain's system prompt without stalling or crashing startup.r   Nr   r  i  rj   r   z/core_block?r   )r   timer  r   r   r   r   r   r   r   r   )r  nowr   r   r   s        r   get_core_blockr  P  s    
 99
))+C6s[%66=6""#\\##Wf$565L-q9%%2,,. KKK	  #6""#s   !AC /C C/.C/c                 2  a ^ RI o^ RIHp Hp V ! RRR\        R\        R\        R\        /4      R	 V3R
 ll4       pV ! RRR\        R\        R\        R\        /4      R V3R ll4       pV ! RRR\        R\
        /4      R V3R ll4       pV! RRW#V.R7      # )z6Build and return the in-process ``memory`` MCP server.N)toolcreate_sdk_mcp_servermemory_rememberuB  EXPLICITLY save one durable fact to Ahmed's shared memory — for memory CURATION work (dossier-card corrections, merges, backfills), NOT for conversational saving (that happens passively). `entities` = comma-separated people/companies/projects the fact is about; `when` = ISO date the fact refers to (event time), if any.r   r   r   r  c                    V ^8  d   QhRRRR/# r
   argsr{   r   r   )r   s   "r   r   "build_server.<locals>.__annotate__z  s     D DD DT Dr   c                x  <"   \        V P                  R R4      4      P                  4       pV'       g   \        R4      #  R TR\        RRR\        V P                  RR4      4      P                  4       ;'       g    RR^/pV P                  R	4      '       d$   \        V R	,          4      P                  4       VR	&   \        V P                  R
R4      4      P                  R4       Uu. uF-  pVP                  4       '       g   K  RVP                  4       /NK/  	  ppV'       d   WBR
&   SP                  \        RRV4      G Rj  xL
 pT;'       g    / P                  RR4      p\        RV RVR,           24      # u upi  L=  \         d)   p\        R\        T4      R,           24      u Rp?# Rp?ii ; i5i)r   r   z memory_remember failed: no text.rj   r   zjarvis-curationr   r   r  r   r  ,namer   r
  Nopaddzsaved (z): :NP   Nzmemory_remember failed: N   N)	r   r   r   r   r   split	to_threadr   r   )r#  r   r   r   entsr   r(  asyncios   &      r   r   %build_server.<locals>.memory_remembers  s     488FB'(..0;<<	DD'68=NS&"!56<<>HH& !%D xx"4<0668V488J34::3?N? -.CD779 (VQWWY'?  N#'Z ))$TJJC))u-B72$c$s)566N K  	D3CF4L>BCC	Dsl   =F::F <F AF (E=E=)F FF *F <F:=F F7F2,F7-F:2F77F:memory_updateu6  Use when something CHANGED — a fact is now different from what was saved (client changed, a plan moved, a preference flipped). Retires the old memory (kept as history, hidden from recall) and saves the new current one, linked to what it replaced. `old_id` from a search result; `text` = the new current fact.r   c                    V ^8  d   QhRRRR/# r"  r   )r   s   "r   r   r$    s     B B$ B4 Br   c                  <"   \        V P                  R R4      4      P                  4       p\        V P                  RR4      4      P                  4       pV'       d	   V'       g   \        R4      #  R TRTR\        RRRV P                  R4      ;'       g    R/pV P                  R	4      '       d   \        V R	,          4      VR	&   SP                  \        R
RV4      G Rj  xL
 p\        RVP                  RR4       R24      #  L#  \         d)   p\        R\        T4      R,           24      u Rp?# Rp?ii ; i5i)r   r   r   z3memory_update failed: need old_id and the new text.rj   r   r   r   r   r   r   r   NzUpdated (new id r   ?z).zmemory_update failed: r+  )r   r   r   r   r   r.  r   r   )r#  r   r   r   r   r   r0  s   &     r   r2  #build_server.<locals>.memory_update  s     TXXh+,224488FB'(..0TNOO	BffdGVh&1A1K1KVNDxx"4<0V))$dKKC+CGGD#,>+?rBCC L 	B1#a&,@AA	BsZ   A"D>&D>2$D D 20D "D#"D D>D D;D60D;1D>6D;;D>memory_searchuo  Search Ahmed's long-term memory by MEANING (not keywords) and get back connected facts — use this whenever the answer might depend on something he told you before ('what should I research for my meeting', 'what did the supplier quote', 'how do I like my coffee'). Returns up to `k` facts (default 10) — READ THEM ALL; the specific/detailed one is often not first.queryr   c                    V ^8  d   QhRRRR/# r"  r   )r   s   "r   r   r$    s"     KB KB$ KB4 KBr   c                  <a"   \        V P                  R R4      4      P                  4       pV'       g   \        R4      #  ^ RIHp VP                  V4        \        ^\        \        V P                  R4      ;'       g    ^
4      ^4      4      pRVRVR\        /p\        V4      w  rVV'       d   WTR&   V'       d   WdR&   \        P                  P                  V4      pSP!                  \"        R	R
V 24      G Rj  xL
 pVP                  R. 4      p	. p
V	 F  pVP                  R4      '       d   RMRpVP                  R4      ;'       g    RR,          pT
P%                  RVR,           V 2V'       d   RV R2MR,           RVP                  RR4       R2,           4       K  	   \        P                  P                  RVR^R\        /4      pSP!                  \"        R	RV 24      G Rj  xL
 P                  R. 4       F`  pV
P%                  RVP                  RR4       R24       SP!                  \"        RRRVP                  RR4      R\        /4      G Rj  xL
  Kb  	   ^ RIp0 R1moV.\)        V3R lVP+                  R VP-                  4       4       4       \.        R!R"7      R#,          ,           pV F  p\        P                  P                  R$VR\        /4      pSP!                  \"        R	R%V 24      G Rj  xL
 P                  R&. 4      p\1        R' V 4       R4      pV'       g   Ky  VP                  R(4      '       d(   V
P%                  R)VR$,           R*VR(,           R24       M=VP                  R+4      '       d'   V
P%                  R,VR$,           R*VR+,           R24        M	   V
'       g   \        R-4      # \        R.P3                  V
4      4      #   \         d     ELi ; i EL EL EL  \         d     ELi ; i EL  \         d     Lji ; i  \         d)   p\        R/\        T4      R0,           24      u Rp?# Rp?ii ; i5i)2r8  r   zmemory_search failed: no query.)entity_showr   rN   rj   	when_fromwhen_tor   r   Nr   r   z [connected]r   r   z- r   z  (re: )z  [id r   r5  ]z/insights/search?r   u{   - (a reflection of yours that may be relevant here — mention it ONLY if it genuinely fits, briefly, as your own thought: r   r   r   c              3  :   <"   T F  pVS9  g   K  Vx  K  	  R # 5ir!   r   )r#   r$   stops   & r   r&   6build_server.<locals>.memory_search.<locals>.<genexpr>  s!      ' E1 Q Es   	
z	[a-z]{4,}T)keyreverse:Nr
   Nr'  z/entity?r  c              3     "   T F7  pVP                  R 4      '       g   VP                  R4      '       g   K3  Vx  K9  	  R# 5i)r   summaryN)r   )r#   r   s   & r   r&   rB    s0       F4a#$55==AEE)4D !"4s   AA
Ar   z- (your read on z: rF  z- (on z (nothing relevant in memory yet)
zmemory_search failed: r+  >   costdealdoesfromhavemuchtellthatthiswhatr   withaboutthinkclientshouldapproach)r   r   r   r   r  r;  show_for_queryr   maxminr4   r   rx   r   r   r   r.  r   appendrg   sortedfindallr-   lennextjoin)r#  rN   _esr   paramswfwtr   r   r   linesr   tagr   iqsit_re2triesr'  eqsr/  hitr   rA  r0  s   &                      @r   r7  #build_server.<locals>.memory_search  s!     "%&,,.:;;	0q!?	BAs3txx}223R89A1c1gv6F$Q'FB&({#$&y!''/B))$"GGCGGGR(EE()hnRk*00b#6r!F)SE259'$q 1rC!'dC(8'9;< = ll,,c1c1gv-NO!(!2!2e'8%>"@ @ADZQSATUBLL((*vr(:';1>? "++D&/-1266$3CWf,UW W WU!B f'\1779 E ',/??AC C "D ,,00&$1PQC")"3"3exu%5#7 78;J8K   F4  FGKMCs776??!LL+;CK=,/K=*; < WWY//!LL6#f+bY@PPQ)RS " ?@@5)**  		 H@W 7  
  	B1#a&,@AA	Bs%  =QO% A$P& ?A P& ?O7 AP& )P& :1P& ,AP  2O:3A/P  "O=#P  ,BP P,P 8P =P 'P 4P& 5P 7P&  
P& 
QP& $Q%O40Q3O44Q7P& :P  =P   PP& PP& P P# P& "P##P& &Q1QQQQQmemoryz1.0.0)r'  versiontools)r0  claude_agent_sdkr  r  r   r4   )r  r  r   r2  r7  r0  s        @r   build_serverrr  f  s    < 

G
 3VS*c
BDDDD( 
/3
 S&#vsFC
@BBBB 
/- Cc
"$KB$KBZ !}= r   )maybemightpossiblyperhapszi thinkznot surearoundroughlyapproximatelyzor soprobablyzcould bezi guess)
signed	confirmed
definitelyzfor sureagreedpaid	committed	finalizedzclosed the dealz	locked in)N   )(   )rZ   )   )r   )related)r   NN),__conditional_annotations____doc__
__future__r   r   r   urllib.errorr   urllib.parseurllib.requestr   r   rstripr   r   r   r   r0   r/   r2   r9   rm   rn   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  __annotations__r  rr  )r  s   @r   <module>r     sa  8 #  	   	zz~~&+2237	zz~~&+		0
!	C q)QQ
Aq*a16	aQGQq1fa1k1b*b*b:
6r8.">>K9
=
	%($JA
5
%	*<6~ Rs+T +,Wr   