o
    i'                     @   s   d dl Z d dlZd dlZd dlmZ d dlmZ d dlmZ d dlmZ 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 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!dS )    N)Optional)Union)quote)	urlencode)
get_logger)
_telemetry)DEFAULT_PROMPTS_CACHE_TTL)DEFAULT_PROMPTS_TIMEOUT)PROMPTS_ENDPOINT)get_connection)HotCache)	WarmCache)ManagedPrompt)	cache_key)extract_error_detail)extract_template)PromptFallbackc                   @   s  e Zd ZdZeeddfdededededed	e	e d
dfddZ
		d8dede	e ded
efddZ	d9deeef dedede	e deded
e	e fddZd:deded
dfddZd;dede	e d
e	e fddZdeded
dfd d!Zded
dfd"d#Z	d9dede	e ded$ed
ee	e ef f
d%d&Zdedede	e d
dfd'd(Zdedede	e d
dfd)d*Zd<d+d,Zdede	e ded
ee	e eef fd-d.Zdede	e d
efd/d0Zd1edede	e d
e	e fd2d3Z		4d=deded5ed
efd6d7ZdS )>PromptManagerz%Manages prompt retrieval and caching.TNapi_keybase_url	cache_ttltimeoutfile_cache_enabled	cache_dirreturnc                 C   sv   d|v r|nd| | _ || _|dd| _|dk| _t|d| _t|||d| _i | _t	
 | _|r9t| j d S d S )Nz://zhttps://python)z
DD-API-KEYzX-Datadog-SDK-Languager   )ttl_seconds)enabledr   r   )	_base_url_timeout_headers_cache_enabledr   
_hot_cacher   _warm_cache_refresh_threads	threadingLock_refresh_lockatexitregister_wait_for_refreshes)selfr   r   r   r   r   r    r,   S/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/llmobs/_prompts/manager.py__init__   s   	

zPromptManager.__init__	prompt_idlabelfallbackc                 C   s   t ||}| jr*| | j|||d}|dur|S | j| j|||ddd}|dur*|S | j|||dd\}}|dur@td |S td	 | j|||d
S )z-Retrieve a prompt template from the registry.	hot_cacheN
warm_cacheT)populate_hotFevict_on_not_foundregistryr1   )reason)	r   r!   
_try_cacher"   r#   _fetch_and_cache	telemetryrecord_prompt_source_create_fallback_prompt)r+   r/   r0   r1   keypromptfetched_promptr8   r,   r,   r-   
get_prompt7   s   


zPromptManager.get_promptFcacher>   source_namer4   c           
      C   sP   | |}|du rdS |\}}	|r| j|| |	r!| ||| t| |S )z7Try to get prompt from cache, trigger refresh if stale.N)getr"   set_trigger_background_refreshr;   r<   )
r+   rB   r>   r/   r0   rC   r4   resultr?   is_staler,   r,   r-   r9   U   s   


zPromptManager._try_cachehotwarmc                 C   s$   |r| j   |r| j  dS dS )zClear the prompt cache.N)r"   clearr#   )r+   rI   rJ   r,   r,   r-   clear_cachej   s
   
zPromptManager.clear_cachec                 C   s$   t ||}| j|||dd\}}|S )z?Force refresh a prompt from the registry, or None if not found.Tr5   )r   r:   )r+   r/   r0   r>   r?   _r,   r,   r-   refresh_promptq   s   
zPromptManager.refresh_promptr?   c                 C   s4   | j sdS |d}| j|| | j|| dS )z?Store a prompt in both hot and warm caches with source='cache'.NrB   )r!   _with_sourcer"   rE   r#   )r+   r>   r?   cached_promptr,   r,   r-   _update_cachesw   s
   
zPromptManager._update_cachesc                 C   s&   | j sdS | j| | j| dS )z!Remove a prompt from both caches.N)r!   r"   deleter#   )r+   r>   r,   r,   r-   _evict_caches   s   zPromptManager._evict_cachesr6   c                 C   sj   | j ||| jd\}}}|dur| || |dfS |r,td |r(| | d|fS td d|fS )z!Fetch a prompt and update caches.r   N NotFound
FetchError)_fetch_from_registryr   rQ   r;   record_prompt_fetch_errorrS   )r+   r/   r0   r>   r6   r?   	not_foundr8   r,   r,   r-   r:      s   


zPromptManager._fetch_and_cachec                    s    fdd}j "  jv r	 W d   dS tj|dd}|j < W d   n1 s1w   Y  z|  W dS  tyg   j  j d W d   n1 sYw   Y  td Y dS w )z8Trigger a background refresh if not already in progress.c                      s   z%   W j j d  W d    d S 1 sw   Y  d S j j d  W d    w 1 s;w   Y  w N)_background_refreshr'   r$   popr,   r>   r0   r/   r+   r,   r-   run_refresh   s   *z>PromptManager._trigger_background_refresh.<locals>.run_refreshNT)targetdaemonz7Failed to start background refresh thread for prompt %s)	r'   r$   r%   ThreadstartRuntimeErrorr]   logdebug)r+   r>   r/   r0   r_   threadr,   r^   r-   rF      s    
z)PromptManager._trigger_background_refreshc                 C   s   | j |||dd dS )z#Refresh a prompt in the background.Tr5   N)r:   )r+   r>   r/   r0   r,   r,   r-   r\      s   z!PromptManager._background_refreshc                 C   sP   | j  t| j }W d   n1 sw   Y  |D ]	}|j| jd qdS )z2Wait for background refreshes to complete on exit.NrT   )r'   listr$   valuesjoinr   )r+   threadsrg   r,   r,   r-   r*      s   z!PromptManager._wait_for_refreshesc              
   C   s@  d}zzgt | j|d}|jd| ||| jd | }|j}| d}|dkr?| 	|||ddfW W |dur>|
  S S |d	k}t|}	|rRtd
|||	 n	td||||	 d||	fW W |durj|
  S S  ty }
 ztd|||
 ddt|
fW  Y d}
~
W |dur|
  S S d}
~
ww |dur|
  w w )z9Fetch from registry. Returns (prompt, not_found, reason).NrT   GET)headerszutf-8   FrU   i  z3Prompt not found: prompt_id=%s label=%s detail="%s"z@Prompt fetch failed: prompt_id=%s label=%s status=%d detail="%s"z1Prompt fetch exception: prompt_id=%s label=%s: %s)r   r   request_build_pathr    getresponsestatusreaddecode_parse_responsecloser   re   rf   warning	Exceptionstr)r+   r/   r0   r   connresponserr   bodyrZ   detailer,   r,   r-   rX      sD   




z"PromptManager._fetch_from_registryc                 C   s:   t |dd}|rt d| dtd|i S t d| S )z6Build the absolute request path for fetching a prompt.rU   )safe/?r0   )r   r
   r   )r+   r/   r0   
escaped_idr,   r,   r-   rp      s   zPromptManager._build_pathr|   c              
   C   s   z8t |}t|tstdt|j W dS t|	d||	dd|	d|dt
|g d|	d	|	d
dW S  t jttfyU } ztd| W Y d}~dS d}~ww )z,Parse the API response into a ManagedPrompt.z8Failed to parse prompt response: expected object, got %sNr/   versionunknownr0   r7   )defaultprompt_uuidprompt_version_uuid)idr   r0   sourcetemplate_uuid_version_uuidz#Failed to parse prompt response: %s)jsonloads
isinstancedictre   rw   type__name__r   rD   r   JSONDecodeErrorKeyError	TypeError)r+   r|   r/   r0   datar~   r,   r,   r-   ru      s&   





	zPromptManager._parse_responserU   r8   c                 C   sB   |du rd |}|rd ||}t|td| t||S )z*Create a fallback prompt when fetch fails.Nz=Prompt '{}' could not be fetched and no fallback was providedz{}: {}z*Using user-provided fallback for prompt %s)format
ValueErrorre   rf   r   from_fallback)r+   r/   r1   r8   messager,   r,   r-   r=      s   
z%PromptManager._create_fallback_prompt)NN)F)TTr[   )r   N)NrU   )r   
__module____qualname____doc__r   r	   ry   floatboolr   r.   r   r   rA   r   r   r   r9   rL   rN   rQ   rS   tupler:   rF   r\   r*   rX   rp   ru   r=   r,   r,   r,   r-   r      s    

%

 


 "r   )"r(   r   r%   typingr   r   urllib.parser   r   ddtrace.internal.loggerr   ddtrace.llmobsr   r;   ddtrace.llmobs._constantsr   r	   r
   ddtrace.llmobs._httpr   ddtrace.llmobs._prompts.cacher   r   ddtrace.llmobs._prompts.promptr   ddtrace.llmobs._prompts.utilsr   r   r   ddtrace.llmobs.typesr   r   re   r   r,   r,   r,   r-   <module>   s,    