o
    3i*                  	   @   s  d Z ddlZddlZddlZddlZddlmZmZm	Z	m
Z
 ddlmZmZ ddlmZ edZdZdZeee
eeeef f Zeee	e f ZG d	d
 d
Zdede	e defddZdddede	e dedefddZdedefddZG dd dZdS )zv
Prompt management for PostHog AI SDK.

Fetch and compile LLM prompts from PostHog with caching and fallback support.
    N)AnyDictOptionalUnion)
USER_AGENT_get_session)remove_trailing_slashposthogzhttps://us.posthog.comi,  c                   @   s"   e Zd ZdZdedefddZdS )CachedPromptzCached prompt with metadata.prompt
fetched_atc                 C   s   || _ || _d S Nr   r   )selfr   r    r   `/lsinfo/ai/hellotax_ai/llm_service/venv_embed/lib/python3.10/site-packages/posthog/ai/prompts.py__init__   s   
zCachedPrompt.__init__N)__name__
__module____qualname____doc__strfloatr   r   r   r   r   r
      s    r
   nameversionreturnc                 C   s   | |fS )z9Build a cache key for latest or versioned prompt fetches.r   )r   r   r   r   r   
_cache_key!   s   r   F
capitalizer   c                C   s6   |rdnd}| d|  d}|dur| d| S |S )z.Format a prompt reference for logs and errors.Promptr   z ""Nz	 version r   )r   r   r   prefixlabelr   r   r   _prompt_reference&   s
   r#   datac                 C   s"   t | tod| v ot | dtS )z5Check if the response is a valid prompt API response.r   )
isinstancedictgetr   )r$   r   r   r   _is_prompt_api_response1   s
   
r(   c                   @   s   e Zd ZdZ	dddddddee dee dee dee dee f
d	d
Zdddddedee dee dee def
ddZ	dede
defddZ	ddddee dee ddfddZddedee defddZdS )Promptsa  
    Fetch and compile LLM prompts from PostHog.

    Can be initialized with a PostHog client or with direct options.

    Examples:
        ```python
        from posthog import Posthog
        from posthog.ai.prompts import Prompts

        # With PostHog client
        posthog = Posthog('phc_xxx', host='https://us.posthog.com', personal_api_key='phx_xxx')
        prompts = Prompts(posthog)

        # Or with direct options (no PostHog client needed)
        prompts = Prompts(
            personal_api_key='phx_xxx',
            project_api_key='phc_xxx',
            host='https://us.posthog.com',
        )

        # Fetch with caching and fallback
        template = prompts.get('support-system-prompt', fallback='You are a helpful assistant.')

        # Fetch a specific published version
        prompt_v1 = prompts.get('support-system-prompt', version=1)

        # Compile with variables
        system_prompt = prompts.compile(template, {
            'company': 'Acme Corp',
            'tier': 'premium',
        })
        ```
    N)personal_api_keyproject_api_keyhostdefault_cache_ttl_secondsr	   r*   r+   r,   r-   c                C   s|   |pt | _i | _|dur+t|ddpd| _t|ddpd| _tt|ddp&t| _dS |p.d| _|p3d| _t|p9t| _dS )a  
        Initialize Prompts.

        Args:
            posthog: PostHog client instance (optional if personal_api_key provided)
            personal_api_key: Direct personal API key (optional if posthog provided)
            project_api_key: Direct project API key (optional if posthog provided)
            host: PostHog host (defaults to app endpoint)
            default_cache_ttl_seconds: Default cache TTL (defaults to 300)
        Nr*    api_keyraw_host)	DEFAULT_CACHE_TTL_SECONDS_default_cache_ttl_seconds_cachegetattr_personal_api_key_project_api_keyr   APP_ENDPOINT_host)r   r	   r*   r+   r,   r-   r   r   r   r   ^   s   


zPrompts.__init__)cache_ttl_secondsfallbackr   r   r9   r:   r   r   c             
   C   s   |dur|n| j }t||}| j|}t }|dur(||j |k }	|	r(|jS z| ||}
t }t|
|d| j|< |
W S  t	yw } z-t
||}|dur_td|| |jW  Y d}~S |durrtd|| |W  Y d}~S  d}~ww )aV  
        Fetch a prompt by name from the PostHog API.

        Caching behavior:
        1. If cache is fresh, return cached value
        2. If fetch fails and cache exists (stale), return stale cache with warning
        3. If fetch fails and fallback provided, return fallback with warning
        4. If fetch fails with no cache/fallback, raise exception

        Args:
            name: The name of the prompt to fetch
            cache_ttl_seconds: Cache TTL in seconds (defaults to instance default)
            fallback: Fallback prompt to use if fetch fails and no cache available
            version: Specific prompt version to fetch. If None, fetches the latest
                version

        Returns:
            The prompt string

        Raises:
            Exception: If the prompt cannot be fetched and no fallback is available
        Nr   z;[PostHog Prompts] Failed to fetch %s, using stale cache: %sz8[PostHog Prompts] Failed to fetch %s, using fallback: %s)r2   r   r3   r'   timer   r   _fetch_prompt_from_apir
   	Exceptionr#   logwarning)r   r   r9   r:   r   ttl	cache_keycachednowis_freshr   r   errorprompt_referencer   r   r   r'      sF    

zPrompts.getr   	variablesc                    s&   dt jdtf fdd}t d||S )az  
        Replace {{variableName}} placeholders with values.

        Unmatched variables are left unchanged.
        Supports variable names with hyphens and dots (e.g., user-id, company.name).

        Args:
            prompt: The prompt template string
            variables: Object containing variable values

        Returns:
            The compiled prompt string
        matchr   c                    s(   |  d}| v rt | S |  dS )N   r   )groupr   )rH   variable_namerG   r   r   replace_variable   s   

z)Prompts.compile.<locals>.replace_variablez\{\{([\w.-]+)\}\})reMatchr   sub)r   r   rG   rM   r   rL   r   compile   s   zPrompts.compile)r   c                   s~   |dur du rt d du r| j  dS |dur'| jt |d dS  fdd| jD }|D ]	}| j|d q3dS )z
        Clear cached prompts.

        Args:
            name: Specific prompt name to clear. If None, clears all cached prompts.
            version: Specific prompt version to clear. Requires name.
        Nz('version' requires 'name' to be providedc                    s   g | ]
}|d   kr|qS )r   r   ).0keyr   r   r   
<listcomp>   s    z'Prompts.clear_cache.<locals>.<listcomp>)
ValueErrorr3   clearpopr   )r   r   r   keys_to_clearrS   r   rT   r   clear_cache   s   

zPrompts.clear_cachec                 C   s<  | j std| jstdtjj|dd}d| ji}|dur#||d< tj|}| j d| d	| }t||}t||d
d}d| j  t	d}	t
 j||	dd}
|
jsz|
jdkrbtd| d|
jdkrotd| dtd| d|
j z|
 }W n ty   td| w t|std| |d S )a  
        Fetch prompt from PostHog API.

        Endpoint:
            {host}/api/environments/@current/llm_prompts/name/{encoded_name}/
            ?token={encoded_project_api_key}[&version={version}]
        Auth: Bearer {personal_api_key}

        Args:
            name: The name of the prompt to fetch
            version: Specific prompt version to fetch. If None, fetches the latest

        Returns:
            The prompt string

        Raises:
            Exception: If the prompt cannot be fetched
        zz[PostHog Prompts] personal_api_key is required to fetch prompts. Please provide it when initializing the Prompts instance.zy[PostHog Prompts] project_api_key is required to fetch prompts. Please provide it when initializing the Prompts instance.r.   )safetokenNr   z,/api/environments/@current/llm_prompts/name/z/?Tr   zBearer )Authorizationz
User-Agent
   )headerstimeouti  z[PostHog Prompts] z
 not foundi  z$[PostHog Prompts] Access denied for zf. Check that your personal_api_key has the correct permissions and the LLM prompts feature is enabled.z"[PostHog Prompts] Failed to fetch z: HTTP z.[PostHog Prompts] Invalid response format for r   )r5   r=   r6   urllibparsequote	urlencoder8   r#   r   r   r'   okstatus_codejsonr(   )r   r   r   encoded_namequery_paramsencoded_queryurlrF   prompt_labelr_   responser$   r   r   r   r<     sT   





zPrompts._fetch_prompt_from_apir   )r   r   r   r   r   r   r   intr   r'   PromptVariablesrQ   rZ   r<   r   r   r   r   r)   :   sZ    %
'
Q
 r)   ) r   loggingrN   r;   urllib.parsera   typingr   r   r   r   posthog.requestr   r   posthog.utilsr   	getLoggerr>   r7   r1   r   rn   r   boolro   tuplePromptCacheKeyr
   r   r#   r(   r)   r   r   r   r   <module>   s6    

	