
    sgLB                        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	m
Z
mZmZmZmZmZmZmZmZ d dlmZ ddlmZmZmZ  e       rd dlZd d	lmZ d d
lmZ ndZ e       rd dlmZ  e       rd dl m!Z! e"e#e$e%e	 e&d      dfZ' ejP                  dejR                        Z* ejP                  dejR                        Z+ ejP                  dejR                  ejX                  z        Z- ejP                  dejR                        Z. G d de/      Z0 G d de/      Z1de$dee$e$f   fdZ2de$defdZ3de
defdZ4de$deee$   ee   ee$   f   fdZ5de
defdZ6d  Z7ed!        Z8y)"    N)contextmanager)datetime)	lru_cache)
AnyCallableDictListOptionalTupleUnionget_args
get_originget_type_hints)version   )is_jinja_availableis_torch_availableis_vision_available)	Extension)ImmutableSandboxedEnvironment)Image)Tensor.z(^(.*?)[\n\s]*(Args:|Returns:|Raises:|\Z)z0\n\s*Args:\n\s*(.*?)[\n\s]*(Returns:|Raises:|\Z)a1  
(?:^|\n)  # Match the start of the args block, or a newline
\s*(\w+):\s*  # Capture the argument name and strip spacing
(.*?)\s*  # Capture the argument description, which can span multiple lines, and strip trailing spacing
(?=\n\s*\w+:|\Z)  # Stop when you hit the next argument or the end of the block
z*\n\s*Returns:\n\s*(.*?)[\n\s]*(Raises:|\Z)c                       e Zd ZdZy)TypeHintParsingExceptionzJException raised for errors in parsing type hints to generate JSON schemasN__name__
__module____qualname____doc__     Y/var/www/html/venv/lib/python3.12/site-packages/transformers/utils/chat_template_utils.pyr   r   =       Tr!   r   c                       e Zd ZdZy)DocstringParsingExceptionzJException raised for errors in parsing docstrings to generate JSON schemasNr   r    r!   r"   r%   r%   C   r#   r!   r%   
param_typereturnc           
          t         ddit        ddit        ddit        ddit        i i}t               rddi|t        <   t               rddi|t        <   |j                  | ddi      S )	Ntypeintegernumberstringbooleanimageaudioobject)
intfloatstrboolr   r   r   r   r   get)r&   type_mappings     r"   _get_json_schema_typer7   I   sz    fi !fhvy!RL %w/U &0VJ(:;;r!   hintc                 >   t        |       }t        |       }|	 t        |       S |t
        u r|D cg c]  }|t        d       ust        |       }}t        |      dk(  r|d   }n5t        d |D              rdt        |D cg c]  }|d   	 c}      i}nd|i}t        d       |v rd|d<   |S |t        u r|sdd	iS d	t        |d         d
S |t        u rg|sdd	iS t        |      dk(  r(t	        dt        |       j                  dd       d      d|v rt	        d      d	|D cg c]  }t        |       c}dS |t        u r%ddi}t        |      dk(  rt        |d         |d<   |S t	        d|       # t        $ r t	        d|       w xY wc c}w c c}w c c}w )NzGCouldn't parse this type hint, likely due to a custom class or object: r   r   c              3   B   K   | ]  }t        |d    t                yw)r)   N)
isinstancer3   ).0subtypes     r"   	<genexpr>z#_parse_type_hint.<locals>.<genexpr>j   s     JgGFOS1Js   r)   anyOfTnullablearray)r)   itemszThe type hint ztyping. a1   is a Tuple with a single element, which we do not automatically convert to JSON schema as it is rarely necessary. If this input can contain more than one element, we recommend using a List[] type instead, or if it really is a single element, remove the Tuple[] wrapper and just pass the element directly..znConversion of '...' is not supported in Tuple type hints. Use List[] types for variable-length inputs instead.)r)   prefixItemsr0      additionalProperties)r   r   r7   KeyErrorr   r   r)   _parse_type_hintlenallsortedlisttupler3   replacedict)r8   originargstsubtypesreturn_dictr=   outs           r"   rH   rH   X   s   FD>D~	(.. 
515MA$t*9L$Q'MMx=A"1+KJJJ!6(*Sw76?*S#TUK #H-K:&*K
#	4G$$ $.>tAw.GHH	5G$$t9>* T!2!29b!A B C- -  $;*# 
  d0S1A!1D0STT	4 x t9>*:47*CC&'

"#lnr
sso  	*Y[_ 	 N +T@ 1Ts"   
E7 FFF
'F7Ffuncc                     t        |       }t        j                  |       }g }|j                  j	                         D ]  \  }}|j
                  t        j                  j                  k(  r%t        d|j                   d| j                         |j                  t        j                  j                  k(  sz|j                  |        i }|j	                         D ]  \  }}t        |      ||<    d|d}|r||d<   |S )Nz	Argument z$ is missing a type hint in function r0   )r)   
propertiesrequired)r   inspect	signature
parametersrB   
annotation	Parameteremptyr   namer   defaultappendrH   )	rV   
type_hintsr[   rY   
param_nameparamrX   r&   schemas	            r"   "_convert_type_hints_to_json_schemarg      s    %J!!$'IH&11779 (
Ew00666*YuzzlBfgkgtgtfu+vww==G--333OOJ'	( J","2"2"4 >
J!1*!=
:> j9F%zMr!   	docstringc           
         t         j                  |       }t        j                  |       }t        j                  |       }|r|j	                  d      j                         nd}|r|j	                  d      j                         nd}|r|j	                  d      j                         nd}|dj                  |j                  d      D cg c]  }|j                         s| c}      }t        j                  |      }|D 	ci c].  }	|	d   t        j                  dd|	d   j                               0 }
}	ni }
||
|fS c c}w c c}	w )a  
    Parses a Google-style docstring to extract the function description,
    argument descriptions, and return description.

    Args:
        docstring (str): The docstring to parse.

    Returns:
        The function description, arguments, and return description.
    r   N
r   z	\s*\n+\s* )description_researchargs_re
returns_regroupstripjoinsplitargs_split_refindallresub)rh   description_match
args_matchreturns_matchdescriptiondocstring_argsreturnslinematchesmatch	args_dicts              r"   parse_google_format_docstringr      s%    '--i8	*J%%i0M 9J#))!,224tK4>Z%%a(..0DN0=m!!!$**,4G !^5I5I$5O#`TSWS]S]S_D#`a''7X_`uU1XrvvlCq9IJJ`	`		7** $a`s   	E E 3Ec                    t        j                  |       }|st        d| j                   d      |j	                         }t        |      \  }}}t        |       }|d   j                  dd      x}|||d<   |d   j                         D ]  \  }}||vrt        d| j                   d| d      ||   }	t        j                  d	|	t        j                  
      }
|
rnt        j                  |
j                  d            D cg c]  }|j	                          c}|d<   |
j                  d|
j!                          j	                         }	|	|d<    | j                  ||d}|||d<   d|dS c c}w )a  
    This function generates a JSON schema for a given function, based on its docstring and type hints. This is
    mostly used for passing lists of tools to a chat template. The JSON schema contains the name and description of
    the function, as well as the names, types and descriptions for each of its arguments. `get_json_schema()` requires
    that the function has a docstring, and that each argument has a description in the docstring, in the standard
    Google docstring format shown below. It also requires that all the function arguments have a valid Python type hint.

    Although it is not required, a `Returns` block can also be added, which will be included in the schema. This is
    optional because most chat templates ignore the return value of the function.

    Args:
        func: The function to generate a JSON schema for.

    Returns:
        A dictionary containing the JSON schema for the function.

    Examples:
    ```python
    >>> def multiply(x: float, y: float):
    >>>    '''
    >>>    A function that multiplies two numbers
    >>>
    >>>    Args:
    >>>        x: The first number to multiply
    >>>        y: The second number to multiply
    >>>    '''
    >>>    return x * y
    >>>
    >>> print(get_json_schema(multiply))
    {
        "name": "multiply",
        "description": "A function that multiplies two numbers",
        "parameters": {
            "type": "object",
            "properties": {
                "x": {"type": "number", "description": "The first number to multiply"},
                "y": {"type": "number", "description": "The second number to multiply"}
            },
            "required": ["x", "y"]
        }
    }
    ```

    The general use for these schemas is that they are used to generate tool descriptions for chat templates that
    support them, like so:

    ```python
    >>> from transformers import AutoTokenizer
    >>> from transformers.utils import get_json_schema
    >>>
    >>> def multiply(x: float, y: float):
    >>>    '''
    >>>    A function that multiplies two numbers
    >>>
    >>>    Args:
    >>>        x: The first number to multiply
    >>>        y: The second number to multiply
    >>>    return x * y
    >>>    '''
    >>>
    >>> multiply_schema = get_json_schema(multiply)
    >>> tokenizer = AutoTokenizer.from_pretrained("CohereForAI/c4ai-command-r-v01")
    >>> messages = [{"role": "user", "content": "What is 179 x 4571?"}]
    >>> formatted_chat = tokenizer.apply_chat_template(
    >>>     messages,
    >>>     tools=[multiply_schema],
    >>>     chat_template="tool_use",
    >>>     return_dict=True,
    >>>     return_tensors="pt",
    >>>     add_generation_prompt=True
    >>> )
    >>> # The formatted chat can now be passed to model.generate()
    ```

    Each argument description can also have an optional `(choices: ...)` block at the end, such as
    `(choices: ["tea", "coffee"])`, which will be parsed into an `enum` field in the schema. Note that this will
    only be parsed correctly if it is at the end of the line:

    ```python
    >>> def drink_beverage(beverage: str):
    >>>    '''
    >>>    A function that drinks a beverage
    >>>
    >>>    Args:
    >>>        beverage: The beverage to drink (choices: ["tea", "coffee"])
    >>>    '''
    >>>    pass
    >>>
    >>> print(get_json_schema(drink_beverage))
    ```
    {
        'name': 'drink_beverage',
        'description': 'A function that drinks a beverage',
        'parameters': {
            'type': 'object',
            'properties': {
                'beverage': {
                    'type': 'string',
                    'enum': ['tea', 'coffee'],
                    'description': 'The beverage to drink'
                    }
                },
            'required': ['beverage']
        }
    }
    z Cannot generate JSON schema for z because it has no docstring!rX   r'   Nr{   z< because the docstring has no description for the argument ''z\(choices:\s*(.*?)\)\s*$)flagsr   enum)r`   r{   r\   function)r)   r   )rZ   getdocr%   r   rq   r   rg   poprB   rv   rm   
IGNORECASEjsonloadsrp   r,   start)rV   docmain_docparam_descriptions
return_docjson_schemarT   argrf   descenum_choicescoutputs                r"   get_json_schemar      s   V ..
C'.t}}o=Z[
 	
 ))+C/LS/Q,H *4T:K"<044XtDDQ!)3K&"<0668 
%V((+24==/A}  B  ~C  CD  E  "#&yy!<d"--X15L<N<Nq<Q1RSAaggiSF6N&&'=););)=>DDFD $}
% mmHKXF&xF33 Ts   E0c           	          g }g }| j                   j                  ||      5   | j                  d||||d|D ]  }|j                  |        dj	                  |      }	d d d        |	|fS # 1 sw Y   	|fS xY w)N)messagestools	documentsadd_generation_promptrC   r    )environmentactivate_trackergeneraterb   rr   )
compiled_templater   r   r   r   template_kwargsrendered_blocksgeneration_indicesblockrendered_chats
             r"   _render_with_assistant_indicesr   X  s     O		&	&	7	7I[	\ 	1/&// 
"7	

 
 	*E ""5)	* 0	1 ,,,	1 ,,,s   ?A,,A8c                     G d dt               }t        j                  t        j                        t        j                  d      k  rt        dt        j                   d      d }dd}d }t        d	d	|t        j                  j                  g
      }||j                  d<   ||j                  d<   ||j                  d<   |j                  |       S )Nc                   >    e Zd ZdhZdef fdZdej                  j                  dej                  j                  fdZej                  dej                  j                  dej                  j                  defd	       Zdefd
Zedee   dee   fd       Z xZS )1_compile_jinja_template.<locals>.AssistantTracker
generationr   c                 x    t         |   |       |j                  | j                         d | _        d | _        y )N)r   )super__init__extendr   _rendered_blocks_generation_indices)selfr   	__class__s     r"   r   z:_compile_jinja_template.<locals>.AssistantTracker.__init__p  s7    G[)0E0EF$(D!'+D$r!   parserr'   c                     t        |j                        j                  }|j                  dgd      }t        j
                  j                  | j                  d      g g |      j                  |      S )Nzname:endgenerationT)drop_needle_generation_support)	nextstreamlinenoparse_statementsjinja2nodes	CallBlockcall_method
set_lineno)r   r   r   bodys       r"   parsez7_compile_jinja_template.<locals>.AssistantTracker.parsew  se    &--(//F**,@+At*TD<<))$*:*:;P*QSUWY[_`kklrssr!   contextcallerc                      |       }| j                         rOt        dj                  | j                              }|t        |      z   }| j                  j                  ||f       |S )NrC   )	is_activerI   rr   r   r   rb   )r   r   r   rvstart_index	end_indexs         r"   r   zE_compile_jinja_template.<locals>.AssistantTracker._generation_support|  sX    B~~!"''$*?*?"@A'#b'1	((//i0HIIr!   c                 6    | j                   xs | j                  S N)r   r   )r   s    r"   r   z;_compile_jinja_template.<locals>.AssistantTracker.is_active  s    ((DD,D,DDr!   r   r   c              3      K   	 | j                         rt        d      || _        || _        d  d | _        d | _        y # d | _        d | _        w xY ww)Nz3AssistantTracker should not be reused before closed)r   
ValueErrorr   r   )r   r   r   s      r"   r   zB_compile_jinja_template.<locals>.AssistantTracker.activate_tracker  sW     	0>>#$%Z[[(7%+=((,%+/( )-%+/(s   A-A  A AA)r   r   r   tagsr   r   r   r   Parserr   r   r   pass_eval_contextEvalContextruntimeMacror3   r   r4   r   r   r	   r1   r   __classcell__)r   s   @r"   AssistantTrackerr   l  s    ~	,(E 	,	t 4 4 	t9O9O 	t
 
	!	!	v||/G/G 	QWQ_Q_QeQe 	jm 	 
"		Et 	E 

	0DI 
	0SWX[S\ 
	0 

	0r!   r   z3.1.0zLapply_chat_template requires jinja2>=3.1.0 to be installed. Your version is .c                 @    t         j                  j                  |       r   )r   
exceptionsTemplateError)messages    r"   raise_exceptionz0_compile_jinja_template.<locals>.raise_exception  s    --g66r!   c                 6    t        j                  | ||||      S )N)ensure_asciiindent
separators	sort_keys)r   dumps)xr   r   r   r   s        r"   tojsonz'_compile_jinja_template.<locals>.tojson  s     zz!,vR\hqrrr!   c                 H    t        j                         j                  |       S r   )r   nowstrftime)formats    r"   strftime_nowz-_compile_jinja_template.<locals>.strftime_now  s    ||~&&v..r!   T)trim_blockslstrip_blocks
extensionsr   r   r   )FNNF)r   r   r   r   __version__ImportErrorr   extloopcontrolsfiltersglobalsfrom_string)chat_templater   r   r   r   	jinja_envs         r"   _compile_jinja_templater   j  s    (09 (0T }}V''(7==+AAZ^d^p^p]qqrs
 	
7s
/ .:JFJJLcLc9dI #)Ih+:I'((4In%  //r!   )9rZ   r   rv   
contextlibr   r   	functoolsr   typingr   r   r   r	   r
   r   r   r   r   r   	packagingr   import_utilsr   r   r   r   
jinja2.extr   jinja2.sandboxr   	PIL.Imager   torchr   r1   r2   r3   r4   r)   BASIC_TYPEScompileDOTALLrl   rn   VERBOSErt   ro   	Exceptionr   r%   r7   rH   rg   r   r   r   r   r    r!   r"   <module>r     s     	 %   j j j  U U $<F E3c4:s;GS
"**H"))
T

 II

 RZZEryyQ
	y 			 	<c <d38n <>t3 >t4 >tBX $ *+S +U8C=(SW.ZbcfZg;g5h +BF4( F4t F4R-$ A0 A0r!   