o
    i                     @   s   d dl Z d dlZd dlm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
 d dlmZ d dlmZ d d	lmZ d d
lmZ eeZG dd dZG dd dZG dd dZdS )    N)Path)RLock)time)Any)Optional)Union)
get_logger)DEFAULT_PROMPTS_CACHE_TTL)ManagedPromptc                   @   sl   e Zd ZdZdededdfddZdedefd	d
Zde	e
ef fddZede	e
ef dd fddZdS )
CacheEntryprompt	timestampr   r   returnNc                 C   s   || _ || _d S Nr   )selfr   r    r   Q/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/llmobs/_prompts/cache.py__init__   s   
zCacheEntry.__init__ttlc                 C   s   t  | j |kS r   )r   r   )r   r   r   r   r   is_stale   s   zCacheEntry.is_stalec                 C   s   | j  | jdS )Nr   )r   
_serializer   r   r   r   r   r      s   zCacheEntry._serializedatac                 C   s   | t |d |d dS )Nr   r   r   )r
   _deserialize)clsr   r   r   r   r       s   zCacheEntry._deserialize)__name__
__module____qualname__	__slots__r
   floatr   boolr   dictstrr   r   classmethodr   r   r   r   r   r      s     r   c                   @   s   e Zd ZdZefdeddfddZdedee	e
ef  fdd	Zded
e
ddfddZdeddfddZdddZdefddZdS )HotCachezT
    In-memory cache with TTL for prompt templates.

    Thread-safe via RLock.
    ttl_secondsr   Nc                 C   s   i | _ || _t | _d S r   )_cache_ttlr   _lock)r   r&   r   r   r   r   ,   s   zHotCache.__init__keyc                 C   sb   | j $ | j|}|du r	 W d   dS |j|| jfW  d   S 1 s*w   Y  dS )z~
        Get a prompt from cache.

        Returns:
            Tuple of (prompt, is_stale) if found, None otherwise.
        N)r)   r'   getr   r   r(   )r   r*   entryr   r   r   r+   4   s   $zHotCache.getr   c                 C   s@   | j  t|t d| j|< W d   dS 1 sw   Y  dS )z Add or update a prompt in cache.r   N)r)   r   r   r'   )r   r*   r   r   r   r   setA   s   "zHotCache.setc                 C   s:   | j  | j|d W d   dS 1 sw   Y  dS )z#Remove a specific entry from cache.N)r)   r'   pop)r   r*   r   r   r   deleteF   s   "zHotCache.deletec                 C   s6   | j  | j  W d   dS 1 sw   Y  dS )zClear all entries from cache.N)r)   r'   clearr   r   r   r   r0   K   s   "zHotCache.clearc                 C   s4   | j  t| jW  d    S 1 sw   Y  d S r   )r)   lenr'   r   r   r   r   __len__P   s   $zHotCache.__len__r   N)r   r   r   __doc__r	   r    r   r#   r   tupler
   r!   r+   r-   r/   r0   intr2   r   r   r   r   r%   %   s    

r%   c                	   @   s   e Zd ZdZedefddZddefdee	ee
f  ded	eddfd
dZdddZde
defddZde
deeeef  fddZde
deddfddZde
ddfddZdddZdS )	WarmCachez
    File-based cache for prompt persistence across restarts.

    Can be disabled via environment variable or constructor.
    r   c                   C   sF   zt  d d d d W S  ty"   t t d d d  Y S w )zMGet the default cache directory, with fallback for environments without HOME.z.cachedatadogllmobsprompts)r   homeRuntimeErrortempfile
gettempdirr   r   r   r   _get_default_cache_dir\   s
   z WarmCache._get_default_cache_dirNT	cache_direnabledr&   c                 C   sT   || _ || _t | _| j st | _d S |d u r|  | _nt| | _|   d S r   )	_enabledr(   r   r)   r   
_cache_dirr?   
expanduser_ensure_cache_dir)r   r@   rA   r&   r   r   r   r   f   s   zWarmCache.__init__c              
   C   sR   z| j jdddd W d S  ty( } ztd| d| _W Y d }~d S d }~ww )Ni  T)modeparentsexist_okz+Failed to create prompt cache directory: %sF)rC   mkdirOSErrorlogwarningrB   )r   er   r   r   rE   {   s   zWarmCache._ensure_cache_dirr*   c                 C   s,   | dd dd dd}| j| d S )N:_/\z.json)replacerC   )r   r*   safe_keyr   r   r   _key_to_path   s   zWarmCache._key_to_pathc                 C   s   | j sdS | |}zL| j2 | s	 W d   W dS t|ddd}t|}W d   n1 s4w   Y  W d   n1 sCw   Y  t|}|j	|
| jfW S  ttjttfyt } ztd| W Y d}~dS d}~ww )z{Load a prompt from file cache.

        Returns:
            Tuple of (prompt, is_stale) if found, None otherwise.
        Nrutf-8encodingz$Failed to read prompt from cache: %s)rB   rT   r)   existsopenjsonloadr   r   r   r   r(   rJ   JSONDecodeErrorKeyError	TypeErrorrK   debug)r   r*   pathfr   r,   rM   r   r   r   r+      s(   

zWarmCache.getr   c              
   C   s   | j sdS | |}t|t d}| }z;| j- t|ddd}t|| W d   n1 s2w   Y  t	
|d W d   W dS 1 sIw   Y  W dS  tyi } ztd| W Y d}~dS d}~ww )zSave a prompt to file cache.Nr   wrV   rW   i  z#Failed to write prompt to cache: %s)rB   rT   r   r   r   r)   rZ   r[   dumposchmodrJ   rK   r`   )r   r*   r   ra   r,   r   rb   rM   r   r   r   r-      s    
&zWarmCache.setc                 C   s   | j sdS | |}| j4 z
| r|  W n ty0 } ztd| W Y d}~nd}~ww W d   dS W d   dS 1 sDw   Y  dS )z)Remove a specific prompt from file cache.Nz&Failed to delete prompt from cache: %s)rB   rT   r)   rY   unlinkrJ   rK   r`   )r   r*   ra   rM   r   r   r   r/      s    
"zWarmCache.deletec                 C   s   | j sdS | j1 | jdD ]!}z|  W q ty0 } ztd|| W Y d}~qd}~ww W d   dS 1 s<w   Y  dS )zClear all cached prompts.Nz*.jsonz%Failed to delete cached prompt %s: %s)rB   r)   rC   globrg   rJ   rK   r`   )r   ra   rM   r   r   r   r0      s   "zWarmCache.clearr3   )r   r   r   r4   staticmethodr   r?   r	   r   r   r#   r!   r    r   rE   rT   r5   r
   r+   r-   r/   r0   r   r   r   r   r7   U   s,    

r7   )r[   re   pathlibr   r=   	threadingr   r   typingr   r   r   ddtrace.internal.loggerr   ddtrace.llmobs._constantsr	   ddtrace.llmobs._prompts.promptr
   r   rK   r   r%   r7   r   r   r   r   <module>   s     0