o
    ưi2                     @   st   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 dZG dd	 d	ZdS )
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                   @   sD   e Zd ZdZ		d
dedeeeef  dee fddZdd	 Z	dS )PromptTemplatez>Represents a single prompt template with metadata and content.Ncontentmetadatatemplate_idc                 C   s   || _ |pi | _|| _g d}| jd| _| jdi di | _| jdi d| _| jdi di | _i | _| j	 D ]}||vrO| j| | j|< qAd S )N)modelinputoutputr   r   schemar   format)
r   r   r   getr   input_schemaZoutput_formatZoutput_schemaZoptional_paramskeys)selfr   r   r   Zrestricted_keyskey r   d/home/app/Keep/.python/lib/python3.10/site-packages/litellm/integrations/dotprompt/prompt_manager.py__init__   s   
zPromptTemplate.__init__c                 C   s   d| j  d| j dS )NzPromptTemplate(id='z
', model='z'))r   r   r   r   r   r   __repr__%   s   zPromptTemplate.__repr__NN)
__name__
__module____qualname____doc__strr   r   r   r   r   r   r   r   r   r      s    
r   c                   @   s>  e Zd ZdZ				d2dee dee deeeeeef f  dee fddZd3d
dZ		d4deeeeef f dee d	dfddZ
deeef ded	efddZded	eeeef ef fddZ		d5dedeeeef  dee d	efddZdeeef deeef d	dfddZded	eeef fddZ	d4dedee d	ee fdd Zd	ee fd!d"Zded	eeeef  fd#d$Zd3d%d&Z	d4deded'eeeef  d	dfd(d)Zdeeef d	eeef fd*d+Zdeeef d	efd,d-Zd	eeeeef f fd.d/Zdeeeeef f d	dfd0d1Z dS )6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              
   C   s   |rt |nd | _i | _|| _tti tddgddddddd	| _| jr)|   | jr>|s2t	d
| 
| j|}|| j|< |rH| || d S d S )Nhtmlxmlz{{z}}z{%z%}z{#z#})loaderZ
autoescapeZvariable_start_stringZvariable_end_stringZblock_start_stringZblock_end_stringZcomment_start_stringZcomment_end_stringz2prompt_id is required when prompt_file is provided)r   r'   promptsr)   r
   r	   r   	jinja_env_load_prompts
ValueError_load_prompt_file_load_prompts_from_json)r   r&   r'   r(   r)   templater   r   r   r   4   s.   

zPromptManager.__init__returnc              	   C   sp   | j r| j  std| j  t| j d}|D ]}z|j}| ||}|| j|< W q ty5   Y qw dS )z1Load all .prompt files from the prompt directory.z!Prompt directory does not exist: z*.promptN)	r'   existsr0   listglobstemr1   r-   	Exception)r   Zprompt_filesr)   r&   r3   r   r   r   r/   Y   s   
zPromptManager._load_promptsc              	   C   sh   |r||i}|  D ]'\}}z|dd}|di }t|||d}|| j|< W q
 ty1   Y q
w dS )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-   r9   )r   r(   r&   Zprompt_infor   r   r3   r   r   r   r2   l   s    z%PromptManager._load_prompts_from_json	file_pathc                 C   s>   t |tr	t|}|jdd}| |\}}t| ||dS )z%Load and parse a single .prompt file.utf-8encodingr;   )
isinstancer$   r   	read_text_parse_frontmatterr   strip)r   r=   r&   r   frontmattertemplate_contentr   r   r   r1      s   
zPromptManager._load_prompt_filer   c              
   C   s~   d}t ||t j}|r7|d}|d}zt|pi }W ||fS  tjy6 } ztd| d}~ww i }|}||fS )z+Parse YAML frontmatter from prompt content.z^---\s*\n(.*?)\n---\s*\n(.*)$      zInvalid YAML frontmatter: N)rematchDOTALLgroupyamlZ	safe_loadZ	YAMLErrorr0   )r   r   Zfrontmatter_patternrJ   frontmatter_yamlrF   rE   er   r   r   rC      s   

z PromptManager._parse_frontmatterprompt_variablesversionc              
   C   s   | j ||d}|du r)t| j }|rd| dnd}td| d| d| |p,i }|jr7| ||j z| j|j	}|j
di |}	|	W S  ty_ }
 z
td	| d
|
 d}
~
w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
        )r&   rQ   Nz
 (version )r:   zPrompt ''z not found. Available prompts: zError rendering template 'z': r   )
get_promptr6   r-   r   KeyErrorr   _validate_inputr.   Zfrom_stringr   renderr9   r0   )r   r&   rP   rQ   r3   Zavailable_promptsversion_str	variablesZjinja_templaterenderedrO   r   r   r   rW      s$   zPromptManager.renderrY   r   c              
   C   sf   |  D ],\}}||v r0|| }| |}t||s0td| dt|dt| dt|j qdS )z3Basic validation of input variables against schema.zInvalid type for field 'z': expected r    z, got N)r<   _get_python_typerA   r0   getattrr$   typer    )r   rY   r   
field_nameZ
field_typevalueexpected_typer   r   r   rV      s   

zPromptManager._validate_inputschema_typec                 C   s2   t t ttftttttttttd}|| t S )z*Convert schema type string to Python type.)stringr$   numberintegerintfloatbooleanboolarrayr6   objectdict)r$   re   rf   rh   r6   rk   r   lower)r   ra   Ztype_mappingr   r   r   r[      s   zPromptManager._get_python_typec                 C   s6   |dur| d| }|| j v r| j | S | j |S )a3  
        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
        Nz.v)r-   r   )r   r&   rQ   Zversioned_idr   r   r   rT     s
   

zPromptManager.get_promptc                 C   s   t | j S )z'Get a list of all available prompt IDs.)r6   r-   r   r   r   r   r   list_prompts  s   zPromptManager.list_promptsc                 C   s   | j |}|r|jS dS )z#Get metadata for a specific prompt.N)r-   r   r   )r   r&   r3   r   r   r   get_prompt_metadata"  s   z!PromptManager.get_prompt_metadatac                 C   s    | j   | jr|   dS dS )zBReload all prompts from the directory (if directory was provided).N)r-   clearr'   r/   r   r   r   r   reload_prompts'  s   
zPromptManager.reload_promptsr   c                 C   s    t ||pi |d}|| j|< dS )z'Add a prompt template programmatically.r;   N)r   r-   )r   r&   r   r   r3   r   r   r   
add_prompt-  s   
zPromptManager.add_promptc                 C   s0   t |}|jdd}| |\}}| |dS )zConvert a .prompt file to JSON format.

        Args:
            file_path: Path to the .prompt file

        Returns:
            Dictionary with 'content' and 'metadata' keys
        r>   r?   r   r   )r   rB   rC   rD   )r   r=   r   rE   rF   r   r   r   prompt_file_to_json6  s   	z!PromptManager.prompt_file_to_jsonc                 C   sF   | dd}| di }|s|S ddl}|j|d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   r:   r   r   NF)Zdefault_flow_stylez---
)r   rM   dump)r   r(   r   r   rM   rN   r   r   r   json_to_prompt_fileG  s   	z!PromptManager.json_to_prompt_filec                 C   s.   i }| j  D ]\}}|j|jd||< q|S )zyGet all loaded prompts in JSON format.

        Returns:
            Dictionary mapping prompt_id to prompt data
        rr   )r-   r<   r   r   )r   resultr&   r3   r   r   r   get_all_prompts_as_json^  s   z%PromptManager.get_all_prompts_as_jsonc                 C   s   |  | dS )zFLoad additional prompts from JSON data (merges with existing prompts).N)r2   )r   r(   r   r   r   load_prompts_from_json_datal  s   z)PromptManager.load_prompts_from_json_data)NNNN)r4   N)Nr   )!r    r!   r"   r#   r   r$   r   r   r   r/   r2   r   r   r   r1   r   rC   re   rW   rV   r]   tupler[   rT   r   rm   rn   rp   rq   rs   ru   rw   rx   r   r   r   r   r%   )   s    

%
&

"
-





"	r%   )r#   rI   pathlibr   typingr   r   r   r   r   r   rM   Zjinja2r	   r
   r   r   r%   r   r   r   r   <module>   s     