
    jKj>              	          d 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mZmZ ddlmZmZ ddlmZ  ej*                  d      ZdZd	Zeeeeeeef   f   Zeeee   f   Zed
   Z  ed       G d d             Z! G d d      Z"dedee   defdZ#dddedee   dedefdZ$de
defdZ% G d d      Z&y)zv
Prompt management for PostHog AI SDK.

Fetch and compile LLM prompts from PostHog with caching and fallback support.
    N)	dataclass)AnyDictLiteralOptionalUnionoverload)
USER_AGENT_get_session)remove_trailing_slashposthogzhttps://us.posthog.comi,  )apicachestale_cachecode_fallbackT)frozenc                   N    e Zd ZU dZeed<   eed<   dZee   ed<   dZ	ee
   ed<   y)PromptResultz8Result of a prompt fetch with metadata about its source.sourcepromptNnameversion)__name__
__module____qualname____doc__PromptSource__annotations__strr   r   r   int     c/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/posthog/ai/prompts.pyr   r      s,    BKD(3-!GXc]!r"   r   c                   (    e Zd ZdZdedededefdZy)CachedPromptzCached prompt with metadata.r   
fetched_atr   r   c                 <    || _         || _        || _        || _        y Nr   r&   r   r   )selfr   r&   r   r   s        r#   __init__zCachedPrompt.__init__*   s    $	r"   N)r   r   r   r   r   floatr    r+   r!   r"   r#   r%   r%   '   s&    &s  S 3 r"   r%   r   r   returnc                 
    | |fS )z9Build a cache key for latest or versioned prompt fetches.r!   r   r   s     r#   
_cache_keyr0   1   s    '?r"   F
capitalizer2   c                4    |rdnd}| d|  d}|| d| S |S )z.Format a prompt reference for logs and errors.Promptr   z ""z	 version r!   )r   r   r2   prefixlabels        r#   _prompt_referencer8   6   s;     $XFhba E	'++Lr"   datac                     t        | t              xrb t        | j                  d      t              xrA t        | j                  d      t              xr  t	        | j                  d            t
        u S )z5Check if the response is a valid prompt API response.r   r   r   )
isinstancedictgetr   typer    )r9   s    r#   _is_prompt_api_responser?   A   s`     	4 	-txx)3/	-txx'-	- )$%,	r"   c                   8   e Zd ZdZ	 d$dddddddee   dee   dee   dee   d	ee   d
efdZ	e
dddddeded   dee   dee   dee   defd       Ze
dddddeded   dee   dee   dee   defd       Ze
dddddedee   dee   dee   def
d       Zddddddedee   dee   dee   dee   deeef   fdZddddedee   dee   defdZdededefdZ	 d$dddee   dee   ddfd Zd!ededee   ddfd"Z	 d$dedee   deeef   fd#Zy)%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',
        )

        # With error tracking: prompt fetch failures are reported to PostHog
        prompts = Prompts(posthog, capture_errors=True)

        # 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',
        })
        ```
    NF)personal_api_keyproject_api_keyhostdefault_cache_ttl_secondscapture_errorsr   rB   rC   rD   rE   rF   c                Z   |xs t         | _        i | _        d| _        || _        || _        |Pt        |dd      xs d| _        t        |dd      xs d| _        t        t        |dd      xs t              | _        y|xs d| _        |xs d| _        t        |xs t              | _        y)ab  
        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)
            capture_errors: If True and a PostHog client is provided, prompt fetch
                failures are reported to PostHog error tracking via capture_exception().
        FNrB    api_keyraw_host)DEFAULT_CACHE_TTL_SECONDS_default_cache_ttl_seconds_cache_has_warned_deprecation_client_capture_errorsgetattr_personal_api_key_project_api_keyr   APP_ENDPOINT_host)r*   r   rB   rC   rD   rE   rF   s          r#   r+   zPrompts.__init__r   s    . &B)B 	' ;=',$-%,W6H$%O%USUD"$+GY$E$KD!.T2BlDJ &6%;D"$3$9rD!.t/C|DDJr"   .)cache_ttl_secondsfallbackr   r   with_metadataTrV   rW   r   r-   c                     y r(   r!   r*   r   rX   rV   rW   r   s         r#   r=   zPrompts.get   s     r"   c                     y r(   r!   rZ   s         r#   r=   zPrompts.get   s     r"   c                     y r(   r!   )r*   r   rV   rW   r   s        r#   r=   zPrompts.get   s     r"   )rX   rV   rW   r   c                Z   |/| j                   s#d| _         t        j                  dt        d       	 | j	                  |||      }|du r|S |j
                  S # t        $ rH}t        ||      }|4t        j                  d||       |du rt        d|	      cY d}~S |cY d}~S  d}~ww xY w)
a  
        Fetch a prompt by name from the PostHog API.

        When ``with_metadata`` is ``True``, returns a :class:`PromptResult`
        with ``source``, ``name``, and ``version`` metadata.  When omitted or
        ``False``, returns a plain string (deprecated -- will be removed in a
        future major version).

        Args:
            name: The name of the prompt to fetch
            with_metadata: If True, returns a PromptResult with source info.
                Omitting this parameter is deprecated.
            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:
            str if with_metadata is False/omitted, PromptResult if True

        Raises:
            Exception: If the prompt cannot be fetched and no fallback is available
        NTa`  [PostHog Prompts] Calling get() without with_metadata=True is deprecated and will be removed in a future major version. Pass with_metadata=True to receive a PromptResult object with source, name, and version metadata. You can pass with_metadata=False to silence this warning, but the plain-string return will still be removed in the next major version.   )
stacklevelrV   r   z8[PostHog Prompts] Failed to fetch %s, using fallback: %sr   )r   r   )rN   warningswarnDeprecationWarning_get_internalr   	Exceptionr8   logwarningr   )	r*   r   rX   rV   rW   r   resulterrorprompt_references	            r#   r=   zPrompts.get   s    @  )E)E+/D(MM #
	''(97 ( F $==  	0w?#N$
 !D('xPP	s5   A A 	B*"5B%B*B%B*$B%%B*r`   c                   ||n| j                   }t        ||      }| j                  j                  |      }t	        j                         }|A||j
                  z
  |k  }|r-t        d|j                  |j                  |j                        S 	 | j                  ||      }	t        |	d   t	        j                         |	d   |	d         | j                  |<   t        d|	d   |	d   |	d         S # t        $ rq}
| j                  |
||	       t        ||      }|It        j!                  d
||
       t        d|j                  |j                  |j                        cY d}
~
S  d}
~
ww xY w)z
        Internal method that handles cache + fetch logic, returning full metadata.

        Does NOT handle the string ``fallback`` option -- the caller handles that.
        Nr   )r   r   r   r   r   r   r   r)   r   r/   z;[PostHog Prompts] Failed to fetch %s, using stale cache: %sr   )rL   r0   rM   r=   timer&   r   r   r   r   _fetch_prompt_from_apir%   re   _maybe_capture_errorr8   rf   rg   )r*   r   rV   r   ttl	cache_keycachednowis_freshr9   ri   rj   s               r#   rd   zPrompts._get_internal   sy    !, 00 	
 tW-	 +iikf///36H#"!=="NN	 $	..tW=D &2H~99;&\Y	&DKK	"  H~&\Y	   	%%e$%H0w?!Q$
 $(!=="NN	  %	s&   A C1 1	E+:A%E&E+%E&&E+r   	variablesc                 j    dt         j                  dt        ffd}t        j                  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                 l    | j                  d      }|v rt        |         S | j                  d      S )N   r   )groupr   )rv   variable_namert   s     r#   replace_variablez)Prompts.compile.<locals>.replace_variableU  s6    !KKNM	)9]344;;q>!r"   z\{\{([\w.-]+)\}\})reMatchr   sub)r*   r   rt   r{   s     ` r#   compilezPrompts.compileF  s1    	"BHH 	" 	" vv*,<fEEr"   )r   c                B   ||t        d      || j                  j                          y|'| j                  j                  t	        ||      d       y| j                  D cg c]  }|d   |k(  s| }}|D ]  }| j                  j                  |d         yc c}w )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 providedr   )
ValueErrorrM   clearpopr0   )r*   r   r   keykeys_to_clears        r#   clear_cachezPrompts.clear_cache_  s     4<GHH<KKKKOOJtW5t<(,Fs1v~F CKKOOC& ! Gs   $B2Bri   c                   | j                   r| j                  yt        | j                  d      sy	 | j                  j                  |d||| j                  d       y# t
        $ r t        j                  d       Y yw xY w)zAReport a prompt fetch error to PostHog error tracking if enabled.Ncapture_exceptionz
ai.prompts)z$lib_featureprompt_nameprompt_versionposthog_host)
propertiesz?[PostHog Prompts] Failed to capture exception to error tracking)rP   rO   hasattrr   rU   re   rf   debug)r*   ri   r   r   s       r#   rn   zPrompts._maybe_capture_errorx  s     ##t||';t||%89	YLL**$0#'&-$(JJ	 +   	YIIWX	Ys   ,A B ?B c                    | j                   st        d      | j                  st        d      t        j                  j                  |d      }d| j                  i}|||d<   t        j                  j                  |      }| j                   d| d| }t        ||      }t        ||d	
      }d| j                    t        d}	t               j                  ||	d      }
|
j                  sW|
j                  dk(  rt        d| d      |
j                  dk(  rt        d| d      t        d| d|
j                         	 |
j                         }t        |      st        d|       |S # t        $ r t        d|       w xY w)a9  
        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 validated API response dict containing prompt, name, and version

        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.rH   )safetokenr   z,/api/environments/@current/llm_prompts/name/z/?Tr1   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 )rR   re   rS   urllibparsequote	urlencoderU   r8   r
   r   r=   okstatus_codejsonr?   )r*   r   r   encoded_namequery_paramsencoded_queryurlrj   prompt_labelr   responser9   s               r#   rm   zPrompts._fetch_prompt_from_api  s   * %%L  $$L 
 ||))$R)84;T=R=R3S&-L#..|<HVXYfXgh,T7;(w4H  't'='=&>?$

  >%%c7B%G{{##s*"4\N* MNN##s*:;K:L M{ { 
 4\N'(J^J^I_` 	==?D 't,@O    	@O 	s   E3 3Fr(   )r   r   r   r   r   r   r   r    boolr+   r	   r   r   r=   r   rd   PromptVariablesr   r   re   rn   r   rm   r!   r"   r#   rA   rA   K   s   $P "&'E +/)-"37$'E#'E #3-	'E
 "#'E sm'E $,C='E 'ER  ,/"%!$ t}	
 $C= 3- # 
   ,/"%!$ u~	
 $C= 3- # 
  
 ,/"%!$ $C=	
 3- # 
  )-+/"&!%@@  ~	@
 $C=@ 3-@ #@ 
sL 	!@L ,0!%GG $C=	G
 #G 
GRFc Fo F# F4 %)'FJ'SM'6>sm'	'2YY),Y7?}Y	Y, 37JJ"*3-J	c3hJr"   rA   )'r   loggingr|   rl   urllib.parser   ra   dataclassesr   typingr   r   r   r   r   r	   posthog.requestr
   r   posthog.utilsr   	getLoggerrf   rT   rK   r   r    r,   r   r   tuplePromptCacheKeyr   r   r%   r0   r8   r?   rA   r!   r"   r#   <module>r      s    	    ! @ @ 4 /g	"' sE#sE4"7889sHSM)*EF $" " " S 8C= ^  >C
 6:# $ L Lr"   