
    `gj=                       U 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	m
Z
 ddlmZmZmZmZ ddlmZ ddlmZ  ej(                  e      ZdZd	ZdZd
Zd$d%dZd&dZ ej:                         Zdade d<   d'dZ!edf	 	 	 d(dZ"d)dZ#dddddddidgddZ$dddddddidgddZ%dd di g ddZ& G d! d"e      Z'd*d#Z(y)+u  ByteRover memory plugin — MemoryProvider interface.

Persistent memory via the ByteRover CLI (``brv``). Organizes knowledge into
a hierarchical context tree with tiered retrieval (fuzzy text → LLM-driven
search). Local-first with optional cloud sync.

Original PR #3499 by hieuntg81, adapted to MemoryProvider ABC.

Requires: ``brv`` CLI installed (npm install -g byterover-cli or
curl -fsSL https://byterover.dev/install.sh | sh).

Config via environment variables (profile-scoped via each profile's .env):
  BRV_API_KEY   — ByteRover API key (for cloud features, optional for local)

Config via config.yaml:
  memory:
    byterover:
      auto_extract: false  # disable automatic brv curate hooks

Working directory: $HERMES_HOME/byterover/ (profile-scoped context tree)
    )annotationsN)Path)AnyDictListOptional)MemoryProvider)
tool_error
   x      c                    t        | t              r| S | |S t        | t        t        f      rt        |       S t        | t              r(| j                         j                         }|dv ry|dv ry|S )N>   1onyestrueT>   0noofffalseF)
isinstanceboolintfloatstrstriplower)valuedefaulttexts      T/root/.hermes/venv/lib/python3.12/site-packages/plugins/memory/byterover/__init__.py_coerce_boolr"   0   sn    %}%#u&E{%{{}""$--..N    c                 D   	 ddl m}   |        }|j                  di       }t        |t              si S |j                  di       }t        |t              r|rt	        |      S |j                  di       }t        |t              rt	        |      S 	 i S # t
        $ r Y i S w xY w)a  Read ByteRover's profile-scoped memory config.

    New memory-provider setup stores non-secret provider settings under
    ``memory.<provider>``.  Some users also set ``memory.provider_config`` from
    early docs/issues, so accept it as a compatibility fallback.
    r   )load_configmemory	byteroverprovider_config)hermes_cli.configr%   getr   dict	Exception)r%   configmemory_configr(   legacy_configs        r!   _load_plugin_configr0   @   s    1

8R0-.I'++K<ot,((%))*;R@mT*&& + I  Is   0B .B ",B 	BBOptional[str]_cached_brv_pathc                    t         5  t        t        dk7  rt        ndcddd       S 	 ddd       t        j                  d      } | sXt	        j
                         }|dz  dz  dz  t	        d      |dz  dz  dz  g}|D ]  }|j                         st        |      }  n t         5  t        t        dk7  rt        ndcddd       S | xs daddd       | S # 1 sw Y   xY w# 1 sw Y   | S xY w)z<Find the brv binary on PATH or well-known install locations.N brvz.brv-clibinz/usr/local/bin/brvz.npm-global)_brv_path_lockr2   shutilwhichr   homeexistsr   )foundr:   
candidatescs       r!   _resolve_brv_pathr?   c   s    
 H''72'=#4H H'H LLEyy{:%-%&= 5(50


  	AxxzA	
 
 '''72'=#4' ' !;B' L+H H"' Ls   C&C#C#C #C-c           	     V   t               }|sdddS |g| z   }|xs t        t                     }t        |      j	                  dd       t
        j                  j                         }t        t        |      j                        }|t
        j                  z   |j                  dd      z   |d<   	 t        j                  |dd|||t        j                        }|j                  j                         }	|j                   j                         }
|j"                  d	k(  rd|	d
S d|
xs |	xs d|j"                   dS # t        j$                  $ r dd| ddcY S t&        $ r& t(        5  daddd       n# 1 sw Y   nxY wdddcY S t,        $ r}dt        |      dcY d}~S d}~ww xY w)z8Run a brv CLI command. Returns {success, output, error}.Fz8brv CLI not found. Install: npm install -g byterover-cli)successerrorTparentsexist_okPATHr4   )capture_outputr    timeoutcwdenvstdinr   )rA   outputzbrv exited zbrv timed out after sNzbrv CLI not found)r?   r   _get_brv_cwdr   mkdirosenvironcopyparentpathsepr*   
subprocessrunDEVNULLstdoutr   stderr
returncodeTimeoutExpiredFileNotFoundErrorr7   r2   r,   )argsrH   rI   brv_pathcmdeffective_cwdrJ   brv_bin_dirresultrX   rY   es               r!   _run_brvrd   ~   s    !"H +eff*t
C.3|~.MdT:
**//
Cd8n++,K

*SWWVR-@@CK34C$$

 $$&$$&!#v66 6+`V+`VM^M^L_?`aa$$ N -A'!+LMM @ 	$#	$ 	$ 	$ +>?? 3 3q6223sI   1A1D= #D= =F(F()E5,	F(5E>	:F(F(F#F(#F(c                 "    ddl m}   |        dz  S )z:Profile-scoped working directory for the brv context tree.r   get_hermes_homer'   )hermes_constantsrg   rf   s    r!   rN   rN      s    0{**r#   	brv_queryzSearch ByteRover's persistent knowledge tree for relevant context. Returns memories, project knowledge, architectural decisions, and patterns from previous sessions. Use for any question where past context would help.objectquerystringzWhat to search for.)typedescription)rm   
propertiesrequired)namern   
parameters
brv_curateu  Store important information in ByteRover's persistent knowledge tree. Use for architectural decisions, bug fixes, user preferences, project patterns — anything worth remembering across sessions. ByteRover's LLM automatically categorizes and organizes the memory.contentzThe information to remember.
brv_statusuM   Check ByteRover status — CLI version, context tree stats, cloud sync state.c                      e Zd ZdZdddZedd       ZddZd ZddZ	ddZ
d	d
ddZd	d
ddZd	d
ddZddZddZd dZd!dZd"dZd#dZd#dZddZy)$ByteRoverMemoryProviderz,ByteRover persistent memory via the brv CLI.Nc                    |t        |      n	t               | _        t        | j                  j	                  d      d      | _        d| _        d| _        d| _        d | _	        y )Nauto_extractTr4   r   )
r+   r0   _configr"   r*   _auto_extract_cwd_session_id_turn_count_sync_thread)selfr-   s     r!   __init__z ByteRoverMemoryProvider.__init__   sU    '-'9tF|?R?T)$,,*:*:>*JDQ	8<r#   c                     y)Nr'    r   s    r!   rq   zByteRoverMemoryProvider.name   s    r#   c                    t               duS )z0Check if brv CLI is installed. No network calls.Nr?   r   s    r!   is_availablez$ByteRoverMemoryProvider.is_available   s     "$..r#   c                $    ddddddddd	d	d
gdgS )Napi_keyz,ByteRover API key (optional, for cloud sync)TBRV_API_KEYzhttps://app.byterover.dev)keyrn   secretenv_varurlry   zAAutomatically curate completed turns and compression/memory hooksr   r   )r   rn   r   choicesr   r   s    r!   get_config_schemaz)ByteRoverMemoryProvider.get_config_schema   s:     !M(2 &b!"G,	
 	
r#   c                    t        t                     | _        || _        d| _        t        | j                        j                  dd       y )Nr   TrC   )r   rN   r|   r}   r~   r   rO   )r   
session_idkwargss      r!   
initializez"ByteRoverMemoryProvider.initialize   s;    '	%TYYdT:r#   c                    t               sy	 y)Nr4   z# ByteRover Memory
Active. Persistent knowledge tree with hierarchical context.
Use brv_query to search past knowledge, brv_curate to store important facts, brv_status to check state.r   r   s    r!   system_prompt_blockz+ByteRoverMemoryProvider.system_prompt_block  s     ":	
r#   r4   )r   c               *   |r t        |j                               t        k  ryt        dd|j                         dd gt        | j
                        }|d   r;|j                  d      r*|d   j                         }t        |      t        kD  rd	| S y)
zRun brv query synchronously before the agent's first LLM call.

        Blocks until the query completes (up to _QUERY_TIMEOUT seconds), ensuring
        the result is available as context before the model is called.
        r4   rk   --N  rH   rI   rA   rL   z## ByteRover Context
)lenr   _MIN_QUERY_LENrd   _QUERY_TIMEOUTr|   r*   _MIN_OUTPUT_LEN)r   rk   r   rb   rL   s        r!   prefetchz ByteRoverMemoryProvider.prefetch  s     EKKM*^;dEKKM%401"		
 )H!5H%++-F6{_,/x88r#   c                    y)z7No-op: prefetch() now runs synchronously at turn start.Nr   )r   rk   r   s      r!   queue_prefetchz&ByteRoverMemoryProvider.queue_prefetch"  s    r#   c                    xj                   dz  c_          j                  st        j                  d       yt	        j                               t        k  ry fd} j                  r6 j                  j                         r j                  j                  d       t        j                  |dd	       _         j                  j                          y)
z:Curate the conversation turn in background (non-blocking).   z3ByteRover sync_turn skipped (auto_extract disabled)Nc                     	 dd d  dd d  } t        dd| gt        j                         y # t        $ r }t        j                  d|       Y d }~y d }~ww xY w)NzUser: i  z
Assistant: curater   r   zByteRover sync failed: %srd   _CURATE_TIMEOUTr|   r,   loggerdebug)combinedrc   assistant_contentr   user_contents     r!   _syncz0ByteRoverMemoryProvider.sync_turn.<locals>._sync1  sl    =#L$$7#8FWX]Y]F^E_`tX.+  =8!<<=s   -1 	AAAg      @rH   Tzbrv-synctargetdaemonrq   )r~   r{   r   r   r   r   r   r   is_alivejoin	threadingThreadstart)r   r   r   r   r   s   ```  r!   	sync_turnz!ByteRoverMemoryProvider.sync_turn&  s    A!!LLNO |!!#$~5	= !2!2!;!;!=""3"/%,,J
 	!r#   c                      j                   st        j                  d       y|dvssy fd}t        j                  |dd      }|j                          y)z+Mirror built-in memory writes to ByteRover.z7ByteRover memory mirror skipped (auto_extract disabled)N>   addreplacec                     	 dk(  rdnd} t        ddd|  d gt        j                         y # t        $ r }t        j                  d	|       Y d }~y d }~ww xY w)
NuserzUser profilezAgent memoryr   r   [z] r   z"ByteRover memory mirror failed: %sr   )labelrc   rt   r   r   s     r!   _writez7ByteRoverMemoryProvider.on_memory_write.<locals>._writeL  se    F*0F*:tqr'%;<+  FA1EEFs   .2 	AAATzbrv-memwriter   )r{   r   r   r   r   r   )r   actionr   rt   r   ts   ` ``  r!   on_memory_writez'ByteRoverMemoryProvider.on_memory_writeD  sO    !!LLRS++7	F F4nM		r#   c                     j                   st        j                  d       y|syg |dd D ]f  }|j                  dd      }|j                  dd      }t	        |t
              s8|j                         sI|dv sNj                  | d|dd	         h syd
j                         fd}t        j                  |dd      }|j                          y)z;Extract insights before context compression discards turns.z?ByteRover pre-compression flush skipped (auto_extract disabled)r4   iNrolert   >   r   	assistantz: i  
c                     	 t        ddd gt        j                         t        j	                  dt                     y # t        $ r } t        j                  d|        Y d } ~ y d } ~ ww xY w)Nr   r   z[Pre-compression context]
r   z,ByteRover pre-compression flush: %d messagesz*ByteRover pre-compression flush failed: %s)rd   r   r|   r   infor   r,   r   )rc   r   partsr   s    r!   _flushz7ByteRoverMemoryProvider.on_pre_compress.<locals>._flushn  sf    Nt'B8*%MN+ JCPUJW NI1MMNs   AA 	A.A))A.Tz	brv-flushr   )r{   r   r   r*   r   r   r   appendr   r   r   r   )	r   messagesmsgr   rt   r   r   r   r   s	   `      @@r!   on_pre_compressz'ByteRoverMemoryProvider.on_pre_compressY  s    !!LLZ[ CD> 	9C7762&Dggi,G'3'GMMOH]@]vR78		9 99U#	N F4kJ		r#   c                $    t         t        t        gS N)QUERY_SCHEMACURATE_SCHEMASTATUS_SCHEMAr   s    r!   get_tool_schemasz(ByteRoverMemoryProvider.get_tool_schemas|  s    m];;r#   c                    |dk(  r| j                  |      S |dk(  r| j                  |      S |dk(  r| j                         S t        d|       S )Nri   rs   ru   zUnknown tool: )_tool_query_tool_curate_tool_statusr
   )r   	tool_namer]   r   s       r!   handle_tool_callz(ByteRoverMemoryProvider.handle_tool_call  s]    ###D)),&$$T**,&$$&&N9+677r#   c                    | j                   r8| j                   j                         r| j                   j                  d       y y y )Ng      $@r   )r   r   r   r   s    r!   shutdownz ByteRoverMemoryProvider.shutdown  s;    !2!2!;!;!=""4"0 ">r#   c                   |j                  dd      }|st        d      S t        dd|j                         d d gt        | j
                        }|d   st        |j                  dd	            S |j                  d
d      j                         }|rt        |      t        k  rt        j                  ddi      S t        |      dkD  r|d d dz   }t        j                  d|i      S )Nrk   r4   zquery is requiredr   r   r   rA   rB   zQuery failedrL   rb   zNo relevant memories found.i@  z

[... truncated])
r*   r
   rd   r   r   r|   r   r   jsondumps)r   r]   rk   rb   rL   s        r!   r   z#ByteRoverMemoryProvider._tool_query  s    "%122dEKKM%401"		

 i fjj.ABBHb)//1V6::x)FGHH v;ET]%::Fzz8V,--r#   c                    |j                  dd      }|st        d      S t        dd|gt        | j                        }|d   st        |j                  dd	            S t        j                  d
di      S )Nrt   r4   zcontent is requiredr   r   r   rA   rB   zCurate failedrb   zMemory curated successfully.)r*   r
   rd   r   r|   r   r   )r   r]   rt   rb   s       r!   r   z$ByteRoverMemoryProvider._tool_curate  ss    ((9b)344tW%#

 i fjj/BCCzz8%CDEEr#   c                    t        dgd| j                        }|d   st        |j                  dd            S t	        j
                  d|j                  dd      i      S )	Nstatus   r   rA   rB   zStatus check failedrL   r4   )rd   r|   r
   r*   r   r   )r   rb   s     r!   r   z$ByteRoverMemoryProvider._tool_status  sT    8*bdii@i fjj2GHIIzz8VZZ"%=>??r#   r   )r-   zOptional[Dict[str, Any]])returnr   )r   r   )r   r   r   None)rk   r   r   r   r   r   )rk   r   r   r   r   r   )r   r   r   r   r   r   r   r   )r   r   r   r   rt   r   r   r   )r   List[Dict[str, Any]]r   r   )r   r   )r   r   r]   r+   r   r   r   r   )r]   r+   r   r   )__name__
__module____qualname____doc__r   propertyrq   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r#   r!   rw   rw      s~    6=  /
";
 9; $ ?A  Y[ "<*!F<81..F@r#   rw   c                6    | j                  t                      y)z/Register ByteRover as a memory provider plugin.N)register_memory_providerrw   )ctxs    r!   registerr     s      !8!:;r#   )F)r   r   r   r   r   r   )r   zDict[str, Any])r   r1   )r]   z	List[str]rH   r   rI   r   r   r+   )r   r   r   ))r   
__future__r   r   loggingrP   r8   rU   r   pathlibr   typingr   r   r   r   agent.memory_providerr	   tools.registryr
   	getLoggerr   r   r   r   r   r   r"   r0   Lockr7   r2   __annotations__r?   rd   rN   r   r   r   rw   r   r   r#   r!   <module>r      s:  , #   	     , , 0 %			8	$   >  !"& - &6 .<$3$3!%$3N+ 	 h7LM
 I$ 	> 9WX
 K$ b#22F\@n \@F<r#   