
    `gj              	         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mZ ddlmZ ddlmZmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ  ej6                  e      ZdZ e       Z dddi g ddZ!dddddddddddgddZ"dddddddidgddZ#dddddddg d d!d"d#d$dd%d&gddZ$d'd(dd)dd*did)gddZ%d+d,ddd-ddd.ddg d/d0d"d1d2dd3d4gddZ&d5d6ddd7ddd8dd9g 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)dAdBdd<ddCdid<gddZ* G dD dE      Z+ G dF dG      Z,dLdMdHZ- G dI dJe      Z.dNdKZ/y)OuR  RetainDB memory plugin — MemoryProvider interface.

Cross-session memory via RetainDB cloud API.

Features:
- Correct API routes for all operations
- Durable SQLite write-behind queue (crash-safe, async ingest)
- Semantic search + user profile retrieval
- Context query with deduplication overlay
- Dialectic synthesis (LLM-powered user understanding, prefetched each turn)
- Agent self-model (persona + instructions from SOUL.md, prefetched each turn)
- Shared file store tools (upload, list, read, ingest, delete)
- Explicit memory tools (profile, search, context, remember, forget)

Config (env vars or hermes config.yaml under retaindb:):
  RETAINDB_API_KEY     — API key (required)
  RETAINDB_BASE_URL    — API endpoint (default: https://api.retaindb.com)
  RETAINDB_PROJECT     — Project identifier (optional — defaults to "default")
    )annotationsN)datetimetimezone)Path)AnyDictList)quote)MemoryProvider)raise_if_read_blocked)
tool_errorzhttps://api.retaindb.comretaindb_profileub   Get the user's stable profile — preferences, facts, and patterns recalled from long-term memory.object)type
propertiesrequired)namedescription
parametersretaindb_searchzUSemantic search across stored memories. Returns ranked results with relevance scores.stringzWhat to search for.)r   r   integerz"Max results (default: 8, max: 20).)querytop_kr   retaindb_contextuc   Synthesized context block — what matters most for the current task, pulled from long-term memory.zCurrent task or question.retaindb_rememberzFPersist an explicit fact, preference, or decision to long-term memory.zThe fact to remember.)factual
preferencegoalinstructioneventopinionzCategory (default: factual).)r   enumr   numberzImportance 0-1 (default: 0.7).)contentmemory_type
importancer%   retaindb_forgetzDelete a specific memory by ID.	memory_idzMemory ID to delete.retaindb_upload_filez_Upload a file to the shared RetainDB file store. Returns an rdb:// URI any agent can reference.zLocal file path to upload.z&Destination path, e.g. /reports/q1.pdf)USERPROJECTORGz Access scope (default: PROJECT).booleanz>Also extract memories from file after upload (default: false).)
local_pathremote_pathscopeingestr/   retaindb_list_filesz$List files in the shared file store.z(Path prefix to filter by, e.g. /reports/zMax results (default: 50).prefixlimitretaindb_read_filez6Read the text content of a stored file by its file ID.file_idz%File ID returned from upload or list.retaindb_ingest_filezUChunk, embed, and extract memories from a stored file. Makes its contents searchable.zFile ID to ingest.retaindb_delete_filezDelete a stored file.zFile ID to delete.c                      e Zd ZddZddZddddddZdddZdddZdd	Zddd
Z	d dZ
d!d"dZd#d$dZd%dZd&d'dZd(dZd)d*dZd+dZd,dZd-d.dZd+dZy)/_Clientc                X    || _         t        j                  dd|      | _        || _        y )N/+$ )api_keyresubbase_urlproject)selfr@   rC   rD   s       S/root/.hermes/venv/lib/python3.12/site-packages/plugins/memory/retaindb/__init__.py__init__z_Client.__init__   s$    vr84    c                    | j                   j                  dd      j                         }d| ddd}|j                  d      r||d<   |S )NBearer r?   zapplication/jsonhermes-plugin)AuthorizationzContent-Typex-sdk-runtime)
/v1/memoryz/v1/contextz	X-API-Key)r@   replacestrip
startswith)rE   pathtokenhs       rF   _headersz_Client._headers   sU    $$Y399;&ug..,

 ??89"AkNrH   N       @)params	json_bodytimeoutc                  dd l }| j                   | }|j                  |j                         |||j                         dvr|nd | j	                  |      |      }	 |j                         }	|j                  shd}
t        |	t              r1t        |	j                  d      xs |	j                  d      xs d      }
t        d| d| d	|j                   d
|
xs |	       |	S # t        $ r |j                  }	Y w xY w)Nr   >   GETDELETE)rW   jsonheadersrY   r?   messageerrorz	RetainDB  z	 failed (z): )requestsrC   requestupperrU   r]   	Exceptiontextok
isinstancedictstrgetRuntimeErrorstatus_code)rE   methodrR   rW   rX   rY   rb   urlresppayloadmsgs              rF   rc   z_Client.request   s    v&LLNC$lln4EE4MM$'   
	 iikG wwC'4('++i0NGKK4HNBO6(!D64CSCSBTTWX[Xf_fWghii  	 iiG	 s   C$ $C<;C<c                L    | j                  dd| j                  |||d|d      S )NPOSTz/v1/context/queryT)rD   r   user_id
session_idinclude_memories
max_tokensrX   rc   rD   )rE   ru   rv   r   rx   s        rF   query_contextz_Client.query_context   s6    ||F$7||$ $$D
|  	rH   c                L    | j                  dd| j                  ||||dd      S )Nrt   z/v1/memory/searchT)rD   r   ru   rv   r   include_pendingry   rz   )rE   ru   rv   r   r   s        rF   searchz_Client.search   s6    ||F$7||$#D
|  	rH   c           	         	 | j                  ddt        |d       | j                  dd      S # t        $ r% | j                  dd| j                  |d	d
      cY S w xY w)Nr[   /v1/memory/profile/r?   safetrue)rD   r}   rW   /v1/memories200)rD   ru   r6   )rc   r
   rD   re   )rE   ru   s     rF   get_profilez_Client.get_profile   s|    	}<<)<U7QS=T<U'Vkokwkw  MS  `T<  U  U 	}<<~$,,cjuz>{<||	}s   .1 +AAc                    	 | j                  dd| j                  |||||ddd      S # t        $ r) | j                  dd| j                  |||||dd      cY S w xY w)	Nrt   rN   sync)rD   r%   r&   ru   rv   r'   
write_mode      @rX   rY   r   )rD   r%   r&   ru   rv   r'   )rc   rD   re   )rE   ru   rv   r%   r&   r'   s         rF   
add_memoryz_Client.add_memory   s    		<<<<GK"*JflA       	<<<<GK"*JC     	s   &) /AAc           	         	 | j                  ddt        |d       d      S # t        $ r% | j                  ddt        |d       d      cY S w xY w)Nr\   z/v1/memory/r?   r   r   rY   z/v1/memories/)rc   r
   re   )rE   r)   s     rF   delete_memoryz_Client.delete_memory  sd    	d<<Kib8Q7R*S]`<aa 	d<<M%	PR:S9T*U_b<cc	ds   !$ +AAc           
     L    | j                  dd| j                  |||dd|      S )Nrt   z/v1/memory/ingest/sessionr   )rD   rv   ru   messagesr   r   rz   )rE   ru   rv   r   rY   s        rF   ingest_sessionz_Client.ingest_session  s8    ||F$?||:' L
    	rH   c                f    | j                  ddt        |d       d| j                  ||dd      S )	Nrt   r   r?   r   z/ask)rD   r   reasoning_levelrV   r   rc   r
   rD   )rE   ru   r   r   s       rF   ask_userz_Client.ask_user  sC    ||F&9%b:Q9RRV$W||ed
   	rH   c                b    | j                  ddt        |d       dd| j                  id      S )	Nr[   /v1/memory/agent/r?   r   z/modelrD   g      @)rW   rY   r   )rE   agent_ids     rF   get_agent_modelz_Client.get_agent_model  sD    ||E%6uXB7O6PPV#Wajlplxlx`y  DG|  H  	HrH   c                f    | j                  ddt        |d       d| j                  ||dd      S )	Nrt   r   r?   r   z/seed)rD   r%   sourceg      4@r   r   )rE   r   r%   r   s       rF   seed_agent_identityz_Client.seed_agent_identity  sC    ||F&7hR8P7QQV$W||6d
   	rH   c                \   dd l }dd l}| j                   d}	| j                  j	                  dd      j                         }
d|
 dd}||j                         d}|r||d<   |j                  |	d	||j                  |      |fi||d
      }|j                          |j                         S )Nr   	/v1/filesrJ   r?   rK   rL   rM   )rR   r1   
project_idfile   )filesdatar^   rY   )iorb   rC   r@   rO   rP   rd   postBytesIOraise_for_statusr]   )rE   r   filenamer0   	mime_typer1   r   r   rb   ro   rS   r^   fieldsrp   s                 rF   upload_filez_Client.upload_file  s    y)$$Y399;&-eW$5X%>#-F< }}S(BJJt<Li1X(Y`fpw  BD}  Eyy{rH   c                @    d|i}|r||d<   | j                  dd|      S )Nr6   r5   r[   r   r   )rc   )rE   r5   r6   rW   s       rF   
list_filesz_Client.list_files*  s.    '%F8||E;v|>>rH   c                B    | j                  ddt        |d             S )Nr[   
/v1/files/r?   r   rc   r
   rE   r8   s     rF   get_filez_Client.get_file0  s"    ||EZgB0G/H#IJJrH   c                   dd l }| j                  j                  dd      j                         }| j                   dt        |d       d}|j                  |d| ddd	d
      }|j                          |j                  S )Nr   rJ   r?   r   r   z/contentrK   r   r   T)r^   rY   allow_redirects)	rb   r@   rO   rP   rC   r
   rk   r   r%   )rE   r8   rb   rS   ro   rp   s         rF   read_file_contentz_Client.read_file_content3  s    $$Y399;z%b*A)B(K||CWUG;L_n)oy{  NR|  S||rH   c                j    i }|r||d<   |r||d<   | j                  ddt        |d       d|d	      S )
Nru   r   rt   r   r?   r   z/ingestg      N@r   r   )rE   r8   ru   r   bodys        rF   ingest_filez_Client.ingest_file;  sJ    %DO'D||FjwR1H0I$Q]ako|pprH   c                F    | j                  ddt        |d       d      S )Nr\   r   r?   r   r   r   r   r   s     rF   delete_filez_Client.delete_fileC  s'    ||H
5r3J2K&LVY|ZZrH   )r@   rj   rC   rj   rD   rj   )rR   rj   returnri   )rn   rj   rR   rj   rY   floatr   r   )i  )
ru   rj   rv   rj   r   rj   rx   intr   ri   )   )
ru   rj   rv   rj   r   rj   r   r   r   ri   )ru   rj   r   ri   )r   ffffff?)ru   rj   rv   rj   r%   rj   r&   rj   r'   r   r   ri   )r)   rj   r   ri   )g      .@)
ru   rj   rv   rj   r   listrY   r   r   ri   )low)ru   rj   r   rj   r   rj   r   ri   )r   rj   r   ri   )soul_md)r   rj   r%   rj   r   rj   r   ri   )r   bytesr   rj   r0   rj   r   rj   r1   rj   r   
str | Noner   ri   )N2   )r5   r   r6   r   r   ri   )r8   rj   r   ri   )r8   rj   r   r   )NN)r8   rj   ru   r   r   r   r   ri   )__name__
__module____qualname__rG   rU   rc   r{   r~   r   r   r   r   r   r   r   r   r   r   r   r   r    rH   rF   r<   r<      sl    
	 9=_b .}
d
H?Kq[rH   r<   c                  P    e Zd Z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
)_WriteQueueuU   SQLite-backed async write queue. Survives crashes — pending rows replay on startup.c           	        || _         || _        t        j                         | _        t        j                  | j                  dd      | _        | j                  j                  j                  dd       t        j                         | _        | j                          | j                  j                          | j                         D ]9  \  }}}}| j                  j!                  |||t#        j$                  |      f       ; y )Nzretaindb-writerTtargetr   daemon)parentsexist_ok)_client_db_pathqueueQueue_q	threadingThread_loop_threadparentmkdirlocal_local_init_dbstart_pending_rowsputr]   loads)rE   clientdb_pathrow_idru   rv   	msgs_jsons          rF   rG   z_WriteQueue.__init__N  s    ${{} ''tzz@QZ^_""4$"?oo'6:6H6H6J 	N2FGZGGKK*djj6KLM	NrH   c                    t        | j                  dd      }|Pt        j                  t	        | j
                        d      }t        j                  |_        || j                  _        |S )z2Return a cached connection for the current thread.connNr   r   )	getattrr   sqlite3connectrj   r   Rowrow_factoryr   rE   r   s     rF   	_get_connz_WriteQueue._get_conn\  sO    t{{FD1<??3t}}#5rBD&{{D#DKKrH   c                f    | j                         }|j                  d       |j                          y )NzCREATE TABLE IF NOT EXISTS pending (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            user_id TEXT, session_id TEXT, messages_json TEXT,
            created_at TEXT, last_error TEXT
        ))r   executecommitr   s     rF   r   z_WriteQueue._init_dbe  s*    ~~  	
 	rH   c                `    | j                         }|j                  d      j                         S )NzTSELECT id, user_id, session_id, messages_json FROM pending ORDER BY id ASC LIMIT 200)r   r   fetchallr   s     rF   r   z_WriteQueue._pending_rowsn  s'    ~~||rs||~~rH   c           	     R   t        j                  t        j                        j	                         }| j                         }|j                  d||t        j                  |d      |f      }|j                  }|j                          | j                  j                  ||||f       y )NzUINSERT INTO pending (user_id, session_id, messages_json, created_at) VALUES (?,?,?,?)F)ensure_ascii)r   nowr   utc	isoformatr   r   r]   dumps	lastrowidr   r   r   )rE   ru   rv   r   r   r   curr   s           rF   enqueuez_WriteQueue.enqueuer  s~    ll8<<(224~~llcj$**XE"JCP
 VWj(;<rH   c                   	 | j                   j                  |||       | j                         }|j                  d|f       |j	                          y # t
        $ rr}t        j                  d|       | j                         }|j                  dt        |      |f       |j	                          t        j                  d       Y d }~y d }~ww xY w)Nz DELETE FROM pending WHERE id = ?z'RetainDB ingest failed (will retry): %sz.UPDATE pending SET last_error = ? WHERE id = ?   )r   r   r   r   r   re   loggerwarningrj   timesleep)rE   r   ru   rv   r   r   excs          rF   
_flush_rowz_WriteQueue._flush_row}  s    
	LL''XF>>#DLL;fYGKKM 	NNDcJ>>#DLLICPSHV\K]^KKMJJqMM	s   AA 	CA(C		Cc                    	 	 | j                   j                  d      }|t        u ry  | j                  |  6# t        j
                  $ r Y Lt        $ r }t        j                  d|       Y d }~9d }~ww xY w)N   r   zRetainDB writer error: %s)	r   rk   _ASYNC_SHUTDOWNr	  r   Emptyre   r  r`   )rE   itemr  s      rF   r   z_WriteQueue._loop  so    ?ww{{1{-?*&  ;;  ?8#>>?s   $8 8 A5A5A00A5c                z    | j                   j                  t               | j                  j	                  d       y )N
   r   )r   r   r  r   joinrE   s    rF   shutdownz_WriteQueue.shutdown  s'    O$"%rH   N)r   r<   r   r   )r   zsqlite3.Connectionr   None)r   r   )ru   rj   rv   rj   r   r   r   r  )
r   r   ru   rj   rv   rj   r   r   r   r  )r   r   r   __doc__rG   r   r   r   r  r	  r   r  r   rH   rF   r   r   K  s/    _N	=
?&rH   r   c                0   dddfd}|xs g D cg c]  } ||      s ||       }}g }t        | xs i j                  d      xs g       d d D ]S  } |xs i j                  d      xs d      } ||      }	|s-|	|vs2|j                  |	       |j                  |       U g }
t        |xs i j                  d      xs g       d d D ]S  } |xs i j                  d      xs d      } ||      }	|s-|	|vs2|j                  |	       |
j                  |       U |s|
sydd	g}||D cg c]  }d
| 	 c}xs dgz  }|j                  d       ||
D cg c]  }d
| 	 c}xs dgz  }dj                  |      S c c}w c c}w c c}w )Nc                l    t        j                  ddt        | xs d            j                         d d S )Nz\s+ra   r?   i@  )rA   rB   rj   rP   )ss    rF   _compactz _build_overlay.<locals>._compact  s-    vvfc3qwB<0668#>>rH   c                Z    t        j                  dd |       j                               S )Nz
[^a-z0-9 ]r?   )rA   rB   lower)r  r  s    rF   _normz_build_overlay.<locals>._norm  s#    vvmR!):):)<==rH   memoriesr  r%   r?   resultsz[RetainDB Context]zProfile:- z- NonezRelevant memories:
)r  rj   r   rj   )r   rk   appendr  )profilequery_resultlocal_entriesr  eseenprofile_itemsmcnquery_itemsrlinesir  s                 @rF   _build_overlayr0    s   ?> +8*=2KA%(uQxKDK!M7=b%%j17R8!< $ag2]]9-34!H$KKN  #$  K<%2**95;<Ra@ "ag2]]9-34!H$KKNq!" !:.E	.11#h.<8*<E	LL%&	,11#h,:
:E99U1 L* /,s   F	
F	6F"Fc                      e Zd ZdZd Zedd       ZddZddZddZ	ddZ
ddZd	d
ddZddZddZddZe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y)&RetainDBMemoryProvideru\   RetainDB cloud memory — durable queue, semantic search, dialectic synthesis, shared files.c                    d | _         d | _        d| _        d| _        d| _        t        j                         | _        d| _        d| _	        i | _
        g | _        y )Ndefaultr?   hermes)r   _queue_user_id_session_id	_agent_idr   Lock_lock_context_result_dialectic_result_agent_model_prefetch_threadsr  s    rF   rG   zRetainDBMemoryProvider.__init__  sX    '+*.!!^^%
  "!#"$ :<rH   c                     y)Nretaindbr   r  s    rF   r   zRetainDBMemoryProvider.name  s    rH   c                R    t        t        j                  j                  d            S )NRETAINDB_API_KEY)boolosenvironrk   r  s    rF   is_availablez#RetainDBMemoryProvider.is_available  s    BJJNN#5677rH   c                2    dddddddddt         d	d
ddd	gS )Nr@   zRetainDB API keyTrC  zhttps://retaindb.com)keyr   secretr   env_varro   rC   zAPI endpoint)rI  r   r4  rD   uC   Project identifier (optional — uses 'default' project if not set)r?   )_DEFAULT_BASE_URLr  s    rF   get_config_schemaz(RetainDBMemoryProvider.get_config_schema  sI    .@D^b  pB  Ka  b~J[\.s  AC  D
 	
rH   c                d   t         j                  j                  dd      }t        j                  ddt         j                  j                  dt
                    }t         j                  j                  d      }|r|}nKt        |j                  dd            }|rt         j                  j                  |      nd}|r	|dvrd| nd	}t        |||      | _
        || _        |j                  d
d	      xs d	| _        |j                  dd      xs d| _        ddlm}	  |	       }
|
dz  }t!        | j                  |      | _        |
dz  }|j%                         rW|j'                  dd      j)                         }|r3t+        j,                  | j.                  |fdd      j1                          y y y )NrC  r?   r>   RETAINDB_BASE_URLRETAINDB_PROJECThermes_home>   .hermesr?   zhermes-r4  ru   r   r5  r   )get_hermes_homezretaindb_queue.dbzSOUL.mdutf-8rO   )encodingerrorszretaindb-soul-seedTr   argsr   r   )rE  rF  rk   rA   rB   rL  rj   rR   basenamer<   r   r8  r7  r9  hermes_constantsrS  r   r6  exists	read_textrP   r   r   
_seed_soulr   )rE   rv   kwargsr@   rC   explicitrD   rQ  profile_namerS  hermes_home_pathr   	soul_pathsoul_contents                 rF   
initializez!RetainDBMemoryProvider.initialize  sx   **..!3R866&"bjjnn5HJ[&\] ::>>"45Gfjj;<K<G277++K8RL3?LXgDg~.nwGw':%

9i8EIJ9EX4*,"%88!$,,8 %y0	$..	.RXXZL  ??&-	
 %'  rH   c                    	 | j                   j                  | j                  |d       y # t        $ r }t        j                  d|       Y d }~y d }~ww xY w)Nr   )r   zRetainDB soul seed failed: %s)r   r   r9  re   r  debug)rE   r%   r  s      rF   r]  z!RetainDBMemoryProvider._seed_soul  sF    	?LL,,T^^WY,W 	?LL8#>>	?s   (+ 	AAAc                V    | j                   r| j                   j                  nd}d| dS )NrA  z## RetainDB Memory
Active. Project: z.
Use retaindb_search to find memories, retaindb_remember to store facts, retaindb_profile for a user overview, retaindb_context for current-task context.)r   rD   )rE   rD   s     rF   system_prompt_blockz*RetainDBMemoryProvider.system_prompt_block  s4    *.,,$,,&&J  'y )__	
rH   r?   )rv   c               r   | j                   sy| j                  D ]  }|j                  d        t        j                  | j
                  |fdd      t        j                  | j                  |fdd      t        j                  | j                  dd	      g}|| _        |D ]  }|j                           y)
z@Fire context + dialectic + agent model prefetches in background.Ng       @r   zretaindb-ctxTrW  zretaindb-dialecticzretaindb-agent-modelr   )	r   r?  r  r   r   _prefetch_context_prefetch_dialectic_prefetch_agent_modelr   )rE   r   rv   tthreadss        rF   queue_prefetchz%RetainDBMemoryProvider.queue_prefetch  s    || '' 	 AFF3F	  D$:$:%P^gklD$<$<E8RfostD$>$>E[dhi

 ") 	AGGI	rH   c                r   	 | j                   j                  | j                  | j                  |      }| j                   j	                  | j                        }t        ||      }| j                  5  || _        d d d        y # 1 sw Y   y xY w# t        $ r }t        j                  d|       Y d }~y d }~ww xY w)Nz$RetainDB context prefetch failed: %s)r   r{   r7  r8  r   r0  r;  r<  re   r  rf  )rE   r   r$  r#  overlayr  s         rF   rj  z(RetainDBMemoryProvider._prefetch_context0  s    	F<<55dmmTEUEUW\]Lll..t}}=G$Wl;G /'.$/ / / 	FLL?EE	Fs6   A.B 0B8B B
B 
B 	B6B11B6c                ^   	 | j                   j                  | j                  || j                  |            }t	        |j                  d      xs d      }|r| j                  5  || _        d d d        y y # 1 sw Y   y xY w# t        $ r }t        j                  d|       Y d }~y d }~ww xY w)N)r   answerr?   z&RetainDB dialectic prefetch failed: %s)r   r   r7  _reasoning_levelrj   rk   r;  r=  re   r  rf  )rE   r   resultrs  r  s        rF   rk  z*RetainDBMemoryProvider._prefetch_dialectic:  s    	H\\**4==%QUQfQfglQm*nFH-34FZZ 4-3D*4 4 4 4 	HLLA3GG	Hs6   A#B %A7-B 7B <B  B 	B,B''B,c                $   	 | j                   j                  | j                        }|j                  dd      dkD  r| j                  5  || _        d d d        y y # 1 sw Y   y xY w# t        $ r }t        j                  d|       Y d }~y d }~ww xY w)Nmemory_countr   z(RetainDB agent model prefetch failed: %s)	r   r   r9  rk   r;  r>  re   r  rf  )rE   modelr  s      rF   rl  z,RetainDBMemoryProvider._prefetch_agent_modelD  s    	JLL00@Eyy+a/ZZ .(-D%. . 0. . 	JLLCSII	Js6   AA& AA& A#A& #A& &	B/B

Bc                2    t        |       }|dk  ry|dk  ryy)Nx   r   i  mediumhigh)len)r   r+  s     rF   rt  z'RetainDBMemoryProvider._reasoning_levelM  s"    Js7s7rH   c                  | j                   5  | j                  }| j                  }| j                  }d| _        d| _        i | _        ddd       g }r|j	                  |       r|j	                  d|        r|j                  dd      dkD  rg }|j                  d      r|j	                  d|d           |j                  d      r-|j	                  d	d
j                  d |d   D              z          |j                  d      r|j	                  d|d           |r#|j	                  dd
j                  |      z          dj                  |      S # 1 sw Y   xY w)z>Consume prefetched results and return them as a context block.r?   Nz[RetainDB User Synthesis]
rw  r   personaz	Persona: persistent_instructionszInstructions:
r!  c              3  &   K   | ]	  }d |   yw)r   Nr   ).0r/  s     rF   	<genexpr>z2RetainDBMemoryProvider.prefetch.<locals>.<genexpr>j  s     @za2aS@zs   working_stylezWorking style: z[RetainDB Agent Self-Model]
z

)r;  r<  r=  r>  r"  rk   r  )rE   r   rv   context	dialecticagent_modelpartsmodel_liness           rF   prefetchzRetainDBMemoryProvider.prefetchV  sP   ZZ 	#**G..I++K#%D %'D" "D	# LL!LL6ykBC;??>1=A%'Ky)""Y{9/E.F#GH89""#4tyy@zS^_xSy@z7z#z{/""_[5Q4R#ST<tyy?UUV{{5!!1	# 	#s   :EE!c          	        | j                   r|syt        j                  t        j                        j                         }| j                   j                  | j                  |xs | j                  d||dd||dg       y)z1Queue turn for async ingest. Returns immediately.Nuser)roler%   	timestamp	assistant)	r6  r   r   r   r   r   r  r7  r8  )rE   user_contentassistant_contentrv   r   s        rF   	sync_turnz RetainDBMemoryProvider.sync_turnt  sk    {{,ll8<<(224MM*$**LsK$1BQTU	
rH   c           
     j    t         t        t        t        t        t
        t        t        t        t        g
S N)
PROFILE_SCHEMASEARCH_SCHEMACONTEXT_SCHEMAREMEMBER_SCHEMAFORGET_SCHEMAFILE_UPLOAD_SCHEMAFILE_LIST_SCHEMAFILE_READ_SCHEMAFILE_INGEST_SCHEMAFILE_DELETE_SCHEMAr  s    rF   get_tool_schemasz'RetainDBMemoryProvider.get_tool_schemas  s'    M>] 02B 2	
 	
rH   c                    | j                   st        d      S 	 t        j                  | j	                  ||            S # t
        $ r}t        t        |            cY d }~S d }~ww xY w)NzRetainDB not initialized)r   r   r]   r   	_dispatchre   rj   )rE   	tool_namerX  r^  r  s        rF   handle_tool_callz'RetainDBMemoryProvider.handle_tool_call  sS    ||899	(::dnnY=>> 	(c#h''	(s   $> 	A%A A% A%c                	   | j                   }|dk(  r|j                  | j                        S |dk(  rd|j                  dd      }|sddiS |j	                  | j                  | j
                  |t        t        |j                  dd            d	      
      S |dk(  rk|j                  dd      }|sddiS |j                  | j                  | j
                  |      }|j                  | j                        }t        ||      }||dS |dk(  rk|j                  dd      }|sddiS |j                  | j                  | j
                  ||j                  dd      t        |j                  dd                  S |dk(  r)|j                  dd      }	|	sddiS |j                  |	      S |dk(  r>|j                  dd      }
|
sddiS t        |
      }|j                         sdd|
 iS 	 t        t!        |             |j%                         }dd l}|j)                  |j*                        d   xs d}|j                  d      xs d|j*                   }|j-                  ||j*                  |||j                  d d!      d       }|j                  d"      rT|j                  d#i       j                  d$      r3|j/                  |d#   d$   | j                  | j0                  %      }||d"<   |S |d&k(  r;|j3                  |j                  d'      t        |j                  d(d)            *      S |d+k(  r|j                  d,d      }|sdd-iS |j5                  |      }|j                  d#      xs i j                  d.      xs dj7                         }|j9                  |      }|j;                  d/      s:t=        fd0d1D              s&|j                  d2      j                  d3      d d4d5S |j?                  d6d78      }|j                  d2      j                  d3      |d d9 tA        |      d9kD  d:S |d;k(  r@|j                  d,d      }|sdd-iS |j/                  || j                  | j0                  %      S |d<k(  r)|j                  d,d      }|sdd-iS |jC                  |      S dd=| iS # t"        $ r}dt!        |      icY d }~S d }~ww xY w)>Nr   r   r   r?   r`   zquery is requiredr   r      )r   r   )r  rawr   r%   zcontent is requiredr&   r   r'   r   )r&   r'   r(   r)   zmemory_id is requiredr*   r/   zlocal_path is requiredzFile not found: r   zapplication/octet-streamr0   /r1   r,   r2   r   id)ru   r   r3   r5   r6   r   r4   r7   r8   zfile_id is requiredr   ztext/c              3  `   K   | ]%  }j                  d d      j                  |       ' yw)r   r?   N)rk   endswith)r  r&  	file_infos     rF   r  z3RetainDBMemoryProvider._dispatch.<locals>.<genexpr>  s/       4g^_IMM&"4M4V4VWX4Y  4gs   +.)z.txtz.mdz.jsonz.csvz.yamlz.ymlz.xmlz.htmlrdb_urir   uE   Binary file — use retaindb_ingest_file to extract text into memory.)r8   r  r   r%   noterT  rO   )rV  i }  )r8   r  r   r%   	truncatedr9   r:   zUnknown tool: )"r   r   r7  rk   r~   r8  minr   r{   r0  r   r   r   r   r[  r   rj   
ValueError
read_bytes	mimetypes
guess_typer   r   r   r9  r   r   r  r   rQ   anydecoder}  r   )rE   r  rX  r*  r   r$  r#  rq  r%   r)   r/   path_objr  r   r  mimer0   ru  r2   r8   metar  rf   r  s                          @rF   r  z RetainDBMemoryProvider._dispatch  s   LL**==//))HHWb)E!45588DMM4+;+;U#cRVRZRZ[bdeRfNgikJl8mm**HHWb)E!455??4==$:J:JERLmmDMM2G$Wl;G&|<<++hhy"-G!677<<t// HH]I> ,!<=     ))b1I!899??9-- ..,3J!9::J'H??$#3J<!@AA+%c(m4 &&(D''6q9W=WD((=1Hq5HK]]4T488T[]fKgimnFxx!fjj&<&@&@&Fvf~d';T]]]a]k]kl#)x M--<<txx'9TXXgWYEZA[<\\,,hhy"-G!677::g&D(.BIMM+.4";;=D%%g.COOG,  4g  df  4g  1g#*y}}Y7OYbYfYfgmYn{  JQ  R  R::gi:8D&9==3KU^UbUbciUjw{  }C  ~C  xD  SV  W[  S\  _d  Sd  e  e..hhy"-G!677==$--$..=YY..hhy"-G!677==))>)566Q  +S**+s   &R. .	S7S	S	Sc                    |dk7  s|r| j                   sy	 |dk(  rdnd}| j                   j                  | j                  | j                  ||       y# t        $ r }t
        j                  d|       Y d}~yd}~ww xY w)z*Mirror built-in memory writes to RetainDB.addNr  r   r   )r&   z!RetainDB memory mirror failed: %s)r   r   r7  r8  re   r  rf  )rE   actionr   r%   r&   r  s         rF   on_memory_writez&RetainDBMemoryProvider.on_memory_write  sr    U?'	C*0F*:,	KLL##DMM43C3CWZe#f 	CLL<cBB	Cs   <A 	A<A77A<c                    | j                   D ]  }|j                  d        | j                  r| j                  j                          y y )Ng      @r   )r?  r  r6  r  )rE   rm  s     rF   r  zRetainDBMemoryProvider.shutdown  sA    '' 	 AFF3F	 ;;KK  " rH   N)r   rj   )r   rD  )r   zList[Dict[str, Any]])rv   rj   r   r  )r%   rj   r   r  )r   rj   rv   rj   r   r  )r   rj   r   r  r  )r   rj   r   rj   )r   rj   rv   rj   r   rj   )r  rj   r  rj   rv   rj   r   r  )r  rj   rX  ri   r   rj   )r  rj   rX  ri   r   r   )r  rj   r   rj   r%   rj   r   r  )r   r   r   r  rG   propertyr   rG  rM  rd  r]  rh  ro  rj  rk  rl  staticmethodrt  r  r  r  r  r  r  r  r   rH   rF   r2  r2    s    f<$  8
"H?
 ?A "FHJ   9; "< Y[ 
 
(X7xC#rH   r2  c                6    | j                  t                      y)z.Register RetainDB as a memory provider plugin.N)register_memory_providerr2  )ctxs    rF   registerr    s      !7!9:rH   r  )r#  ri   r$  ri   r%  zlist[str] | Noner   rj   r  )0r  
__future__r   r]   loggingrE  r   rA   r   r   r  r   r   pathlibr   typingr   r   r	   urllib.parser
   agent.memory_providerr   agent.file_safetyr   tools.registryr   	getLoggerr   r  rL  r   r  r  r  r  r  r  r  r  r  r  r  r<   r   r0  r2  r  r   rH   rF   <module>r     s  ( #   	  	    '  " "  0 3 %			8	$. ( w#22F j&7LM'8\]
 I xh7RS
 I
  [ (9PQ \=
 $,<\]
 K& 4(;QR
 !M
 #t#+<XY$,=ef&0J[}~(9yz	
 "N	   "9'8bc'8TU
   !K9`a
 K
  #j9MN
 K
  #*9MN
 K
 "P[ P[nM& M&hLy#^ y#x	;rH   