
    i|2                         d 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ZddlmZmZmZ  G d d      Z G d d	      Zy)
zq
Based on Google's GenAI Kit dotprompt implementation: https://google.github.io/dotprompt/reference/frontmatter/
    N)Path)AnyDictListOptionalTupleUnion)
DictLoaderEnvironmentselect_autoescapec                   F    e Zd ZdZ	 	 ddedeeeef      dee   fdZd Z	y)	PromptTemplatez>Represents a single prompt template with metadata and content.Ncontentmetadatatemplate_idc                 0   || _         |xs i | _        || _        g d}| j                  j                  d      | _        | j                  j                  di       j                  di       | _        | j                  j                  di       j                  d      | _        | j                  j                  di       j                  di       | _        i | _        | j                  j                         D ]#  }||vs| j                  |   | j                  |<   % y )N)modelinputoutputr   r   schemar   format)
r   r   r   getr   input_schemaoutput_formatoutput_schemaoptional_paramskeys)selfr   r   r   restricted_keyskeys         ~/Users/manta/Documents/Projects/TheRoad-I1/.venv/lib/python3.12/site-packages/litellm/integrations/dotprompt/prompt_manager.py__init__zPromptTemplate.__init__   s      B& 7]]&&w/
 MM--gr:>>xL!]]..x<@@J!]]..x<@@2N!==%%'C/),0MM#,>$$S) (    c                 <    d| j                    d| j                   dS )NzPromptTemplate(id='z
', model='z'))r   r   r   s    r!   __repr__zPromptTemplate.__repr__%   s"    $T%5%5$6jBOOr#   NN)
__name__
__module____qualname____doc__strr   r   r   r"   r&    r#   r!   r   r      sE    H
 .2%)	?? 4S>*? c]	?*Pr#   r   c                   \   e Zd ZdZ	 	 	 	 d!dee   dee   deeeeeef   f      dee   fdZd"d	Z		 d#deeeeef   f   dee   ddfd
Z
deeef   dedefdZdedeeeef   ef   fdZ	 	 d$dedeeeef      dee   defdZdeeef   deeef   ddfdZdedeeef   fdZ	 d#dedee   dee   fdZdee   fdZdedeeeef      fdZd"dZ	 d#dededeeeef      ddfdZdeeef   deeef   fdZdeeef   defdZdeeeeef   f   fdZdeeeeef   f   ddfd Z y)%PromptManagera  
    Manager for loading and rendering .prompt files following the Dotprompt specification.

    Supports:
    - YAML frontmatter for metadata
    - Handlebars-style templating (using Jinja2)
    - Input/output schema validation
    - Model configuration
    N	prompt_idprompt_directoryprompt_dataprompt_filec           
         |rt        |      nd | _        i | _        || _        t	        t        i       t        ddg      dddddd	      | _        | j                  r| j                          | j                  r8|st        d
      | j                  | j                  |      }|| j                  |<   |r| j                  ||       y y )Nhtmlxmlz{{z}}z{%z%}z{#z#})loader
autoescapevariable_start_stringvariable_end_stringblock_start_stringblock_end_stringcomment_start_stringcomment_end_stringz2prompt_id is required when prompt_file is provided)r   r1   promptsr3   r   r
   r   	jinja_env_load_prompts
ValueError_load_prompt_file_load_prompts_from_json)r   r0   r1   r2   r3   templates         r!   r"   zPromptManager.__init__4   s     ;K%5 6PT24&$b>(&%9"& $#!!%#

     !UVV--d.>.>	JH&.DLL# ((i@ r#   returnc                 P   | j                   r| j                   j                         st        d| j                          t        | j                   j	                  d            }|D ]0  }	 |j
                  }| j                  ||      }|| j                  |<   2 y# t        $ r Y ?w xY w)z1Load all .prompt files from the prompt directory.z!Prompt directory does not exist: z*.promptN)	r1   existsrB   listglobstemrC   r?   	Exception)r   prompt_filesr3   r0   rE   s        r!   rA   zPromptManager._load_promptsY   s    $$D,A,A,H,H,J3D4I4I3JK  D1166zBC'K',,	11+yI*2Y'	 (  s   )-B	B%$B%c                     |r||i}|j                         D ]G  \  }}	 |j                  dd      }|j                  di       }t        |||      }|| j                  |<   I y# t        $ r Y Vw xY w)a  Load prompts from JSON data structure.

        Expected format:
        {
            "prompt_id": {
                "content": "template content",
                "metadata": {"model": "gpt-4", "temperature": 0.7, ...}
            }
        }

        or

        {
            "content": "template content",
            "metadata": {"model": "gpt-4", "temperature": 0.7, ...}
        } + prompt_id
        r    r   r   r   r   N)itemsr   r   r?   rL   )r   r2   r0   prompt_infor   r   rE   s          r!   rD   z%PromptManager._load_prompts_from_jsonl   s    ( $k2K&1&7&7&9"I{%//)R8&??:r:)#% )
 +3Y' ':  s   AA""	A.-A.	file_pathc                     t        |t              rt        |      }|j                  d      }| j	                  |      \  }}t        |j                         ||      S )z%Load and parse a single .prompt file.utf-8encodingrP   )
isinstancer,   r   	read_text_parse_frontmatterr   strip)r   rS   r0   r   frontmattertemplate_contents         r!   rC   zPromptManager._load_prompt_file   sa     i%YI%%w%7 )-(?(?(H%%$**, !
 	
r#   r   c                 6   d}t        j                  ||t         j                        }|r@|j                  d      }|j                  d      }	 t	        j
                  |      xs i }||fS i }|}||fS # t        j                  $ r}t        d|       d}~ww xY w)z+Parse YAML frontmatter from prompt content.z^---\s*\n(.*?)\n---\s*\n(.*)$      zInvalid YAML frontmatter: N)rematchDOTALLgroupyaml	safe_load	YAMLErrorrB   )r   r   frontmatter_patternrb   frontmatter_yamlr]   r\   es           r!   rZ   z PromptManager._parse_frontmatter   s     ?,gryyA${{1~${{1~C"nn-=>D" ,,, K&,,, >> C #=aS!ABBCs   A2 2BBBprompt_variablesversionc                    | j                  ||      }|At        | j                  j                               }|rd| dnd}t	        d| d| d|       |xs i }|j
                  r| j                  ||j
                         	 | j                  j                  |j                        } |j                  di |}	|	S # t        $ r}
t        d	| d
|
       d}
~
ww xY w)a  
        Render a prompt template with the given variables.

        Args:
            prompt_id: The ID of the prompt template to render
            prompt_variables: Variables to substitute in the template
            version: Optional version number. If provided, looks for {prompt_id}.v{version}

        Returns:
            The rendered prompt string

        Raises:
            KeyError: If prompt_id is not found
            ValueError: If template rendering fails
        )r0   rl   Nz
 (version )rO   zPrompt ''z not found. Available prompts: zError rendering template 'z': r-   )
get_promptrI   r?   r   KeyErrorr   _validate_inputr@   from_stringr   renderrL   rB   )r   r0   rk   rl   rE   available_promptsversion_str	variablesjinja_templaterenderedrj   s              r!   rt   zPromptManager.render   s    , ??Y?H $T\\%6%6%8 95<Jwiq1"K9+Q{m3RSdRef  %*	     H,A,AB	M!^^778H8HIN,~,,9y9HO 	M9)CsKLL	Ms   8B? ?	CCCrw   r   c                     |j                         D ]g  \  }}||v s||   }| j                  |      }t        ||      r.t        d| dt	        |dt        |             dt        |      j                          y)z3Basic validation of input variables against schema.zInvalid type for field 'z': expected r(   z, got N)rQ   _get_python_typerX   rB   getattrr,   typer(   )r   rw   r   
field_name
field_typevalueexpected_types          r!   rr   zPromptManager._validate_input   s     '-lln"J
Y&!*- $ 5 5j A!%7$2:, ?$$+M:s=GY$Z#[[abfglbmbvbvawy  '5r#   schema_typec                     t         t         t        t        ft        t        t        t        t        t        t        t
        t
        d}|j                  |j                         t               S )z*Convert schema type string to Python type.)stringr,   numberintegerintfloatbooleanboolarrayrI   objectdict)r,   r   r   r   rI   r   r   lower)r   r   type_mappings      r!   r{   zPromptManager._get_python_type   sQ     El7
  1 1 3S99r#   c                     |$| d| }|| j                   v r| j                   |   S | j                   j                  |      S )a#  
        Get a prompt template by ID and optional version.

        Args:
            prompt_id: The base prompt ID
            version: Optional version number. If provided, looks for {prompt_id}.v{version}

        Returns:
            The prompt template if found, None otherwise
        z.v)r?   r   )r   r0   rl   versioned_ids       r!   rp   zPromptManager.get_prompt  sL     '[7)4Lt||+||L11 ||	**r#   c                 H    t        | j                  j                               S )z'Get a list of all available prompt IDs.)rI   r?   r   r%   s    r!   list_promptszPromptManager.list_prompts  s    DLL%%'((r#   c                 X    | j                   j                  |      }|r|j                  S dS )z#Get metadata for a specific prompt.N)r?   r   r   )r   r0   rE   s      r!   get_prompt_metadataz!PromptManager.get_prompt_metadata"  s)    <<##I.$,x  6$6r#   c                 r    | j                   j                          | j                  r| j                          yy)zBReload all prompts from the directory (if directory was provided).N)r?   clearr1   rA   r%   s    r!   reload_promptszPromptManager.reload_prompts'  s,        !r#   r   c                 F    t        ||xs i |      }|| j                  |<   y)z'Add a prompt template programmatically.rP   N)r   r?   )r   r0   r   r   rE   s        r!   
add_promptzPromptManager.add_prompt-  s)     "hn")
 #+Yr#   c                     t        |      }|j                  d      }| j                  |      \  }}|j                         |dS )zConvert a .prompt file to JSON format.

        Args:
            file_path: Path to the .prompt file

        Returns:
            Dictionary with 'content' and 'metadata' keys
        rU   rV   r   r   )r   rY   rZ   r[   )r   rS   r   r\   r]   s        r!   prompt_file_to_jsonz!PromptManager.prompt_file_to_json6  sL     O	%%w%7 )-(?(?(H%%+113MMr#   c                     |j                  dd      }|j                  di       }|s|S ddl} |j                  |d      }d| d| S )	zConvert JSON prompt data to .prompt file format.

        Args:
            prompt_data: Dictionary with 'content' and 'metadata' keys

        Returns:
            String content in .prompt file format
        r   rO   r   r   NF)default_flow_stylez---
)r   re   dump)r   r2   r   r   re   ri   s         r!   json_to_prompt_filez!PromptManager.json_to_prompt_fileG  sY     //)R0??:r2N 	$499X%H'(gY77r#   c                     i }| j                   j                         D ]!  \  }}|j                  |j                  d||<   # |S )zyGet all loaded prompts in JSON format.

        Returns:
            Dictionary mapping prompt_id to prompt data
        r   )r?   rQ   r   r   )r   resultr0   rE   s       r!   get_all_prompts_as_jsonz%PromptManager.get_all_prompts_as_json^  sJ     #'<<#5#5#7Ix#++$--!F9 $8
 r#   c                 &    | j                  |       y)zFLoad additional prompts from JSON data (merges with existing prompts).N)rD   )r   r2   s     r!   load_prompts_from_json_dataz)PromptManager.load_prompts_from_json_datal  s     	$$[1r#   )NNNN)rF   N)Nr'   )!r(   r)   r*   r+   r   r,   r   r   r"   rA   rD   r	   r   r   rC   r   rZ   r   rt   rr   r}   tupler{   rp   r   r   r   r   r   r   r   r   r   r-   r#   r!   r/   r/   )   s    $(*.;?%)#AC=#A #3-#A d3S#X#678	#A
 c]#AJ( RV$T#s(^ 34$AI#$	$L
sDy)
69
	
$-# -%S#X8K2L -0 6:!%	+M+M #4S>2+M #	+M
 
+MZc3h15c3h	:C :E$+4F :( 8<++'/}+	.	!+,)d3i )7S 7Xd38n5M 7
! RV++'*+6>tCH~6N+	+NU39-= N$sCx. N"8tCH~ 8# 8.c4S>.A)B 2T#s(^ 342	2r#   r/   )r+   ra   pathlibr   typingr   r   r   r   r   r	   re   jinja2r
   r   r   r   r/   r-   r#   r!   <module>r      s9    
  : :  = =P P8G2 G2r#   