o
    iP                     @  sJ  d dl m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	 d dl
mZmZmZmZmZmZmZmZ d dlmZmZmZ d dlmZmZ d dlmZmZ d d	lmZ d d
lm Z  ddl!m"Z" ddl#m$Z$ ddl%m&Z& ddl'm(Z(m)Z) ddl*m+Z+m,Z, erddl-m.Z. ddl'm/Z/m0Z0 ddl1m2Z2 ddl*m3Z3 dZ4dZ5d{ddZ6e	G dd dZ7d|d#d$Z8d}d(d)Z9e	G d*d+ d+Z:d,d-d~d1d2Z;d3d4dd9d:Z<dd;d<Z=ed=dd>Z>ddAdBZ?ddFdGZ@ddHdIZAddMdNZBddOddWdXZCdd[d\ZDd3d]ddadbZEddgdhZFddjdkZGe	G dldm dmZHddsdtZIddOddydzZJdS )    )annotationsN)Callable)	dataclass)TYPE_CHECKING	AnnotatedAnyUnioncastget_args
get_originget_type_hints)	BaseModelTypeAdaptercreate_model)Field	FieldInfo)PydanticUndefined	from_json)TypeVar)rtc   )logger)images   )_strict)ChatContextImageContent)FunctionToolRawFunctionTool
RunContextFunctionCallFunctionCallOutput)FunctionToolCall)ToolContextz<think>z</think>old_ids	list[str]new_idsreturnc                   s`  t | t |}  fddt|d D }td|d D ]>}td d D ]4}| |d  ||d  krE||d  |d  d || |< q&t||d  | || |d  || |< q&qg }| }}|dkr|dkr| |d  ||d  kr|| |d   |d8 }|d8 }n||d  | || |d  kr|d8 }n|d8 }|dkr|dksktt|S )z
    Standard dynamic-programming LCS to get the common subsequence
    of IDs (in order) that appear in both old_ids and new_ids.
    c                   s   g | ]	}d g d  qS )r   r    ).0_mr*   Z/var/www/html/livekit_bhavya/venv/lib/python3.10/site-packages/livekit/agents/llm/utils.py
<listcomp>1       z _compute_lcs.<locals>.<listcomp>r   r   )lenrangemaxappendlistreversed)r&   r(   ndpijlcs_idsr*   r-   r/   _compute_lcs+   s(   ",

 

r=   c                   @  s&   e Zd ZU ded< ded< ded< dS )DiffOpsr'   	to_removezlist[tuple[str | None, str]]	to_create	to_updateN__name__
__module____qualname____annotations__r*   r*   r*   r/   r>   K   s   
 r>   old_ctxr   new_ctxc                   s   dd | j D }dd |j D }tt|| dd | j D } fdd| j D }g }g }d}|j D ]0}	|	j vrB|||	jf n||	j }
|	jdkr_|
jdkr_|	j|
jkr_|||	jf |	j}q2t|||d	S )
zXComputes the minimal list of create/remove operations to transform old_ctx into new_ctx.c                 S     g | ]}|j qS r*   idr+   r.   r*   r*   r/   r0   Z       z)compute_chat_ctx_diff.<locals>.<listcomp>c                 S  rI   r*   rJ   rL   r*   r*   r/   r0   [   rM   c                 S  s   i | ]}|j |qS r*   rJ   r+   itemr*   r*   r/   
<dictcomp>^   s    z)compute_chat_ctx_diff.<locals>.<dictcomp>c                   s   g | ]
}|j  vr|j qS r*   rJ   )r+   msgr<   r*   r/   r0   `   s    Nmessage)r?   r@   rA   )itemssetr=   rK   r5   typetext_contentr>   )rG   rH   r&   r(   old_ctx_by_idr?   r@   rA   prev_idnew_msgold_msgr*   rR   r/   compute_chat_ctx_diffV   s"   


r\   tyrV   boolc                 C  s(   ddl m} t| }| |u p||u }|S )Nr   r   )voice.eventsr    r   )r]   r    originis_call_contextr*   r*   r/   is_context_typeu   s   rb   c                   @  s6   e Zd ZU ded< ded< dZded< dZded< dS )	SerializedImagestrinference_detail
str | None	mime_typeNzbytes | None
data_bytesexternal_url)rC   rD   rE   rF   rh   ri   r*   r*   r*   r/   rc   ~   s
   
 rc   T)	use_cacheimager   rj   c                C  s^  d}|r|| j v rtt| j | S t| jtrv| jdrk| jdd\}}t	|}|dd dd }| j
rP| j
|krPtd| j
 d	| d
 | j
}n|}h d}||vrbtd| dt||| jd}	n;t| j
| j| jd}	n0t| jtjrt }
| jr| jrtj| j| jdd|
_t| j|
}t|d| jd}	ntd|r|	| j |< |	S )Nserialized_imagezdata:,r   ;r   :zProvided mime_type 'z9' does not match data URL mime type
                    'z'. Using provided mime_type.>   	image/gif	image/png
image/webp
image/jpegzUnsupported mime_type z!. Must be jpeg, png, webp, or gif)rh   rg   re   )rg   re   ri   scale_aspect_fit)widthheightstrategyrs   zUnsupported image type)_cacher	   rc   
isinstancerk   rd   
startswithsplitbase64	b64decoderg   r   warning
ValueErrorre   r   
VideoFramer   EncodeOptionsinference_widthinference_heightResizeOptionsresize_optionsencode)rk   rj   	cache_keyheaderb64_dataencoded_dataheader_mimerg   supported_typesrl   optsr*   r*   r/   serialize_image   sb   



r   F)internally_taggedfunction_toolr   r   dict[str, Any]c                C  sZ   t | }| j}| }d|vrg |d< |r |j|jpd|ddS d|j|jp'd|ddS )z|non-strict mode tool description
    see https://serde.rs/enum-representations.html for the internally tagged representationrequired function)namedescription
parametersrV   )r   r   r   rV   r   )$function_arguments_to_pydantic_modelinfomodel_json_schemar   r   )r   r   modelr   schemar*   r*   r/   build_legacy_openai_schema   s"   r   c                 C  sD   t | }| j}t|}d|vrg |d< d|jd|jpd|ddS )zstrict mode tool descriptionr   r   Tr   )r   strictr   r   r   )r   r   r   to_strict_json_schemar   r   )r   r   r   r   r*   r*   r/   build_strict_openai_schema   s   
r   ResponseFormatT)defaultcls
type | Anyc                 C  s   t | tot| tot| dS )NrF   )ry   rV   
issubclassdicthasattr)r   r*   r*   r/   is_typed_dict   s   r   response_formattype | dict[str, Any].tuple[str, type[BaseModel] | TypeAdapter[Any]]c                 C  s   t | tr| dddvrtdtdt| r*t| jfi dd | j D } d }t	
| r?t| tr?| j}| }||fS t	
| rTt| drT| j}t| }||fS td|  )	NrV   r   )textjson_schemajson_objectz Unsupported response_format typec                 S  s   i | ]	\}}||d fqS ).r*   )r+   kvr*   r*   r/   rP     r1   z,to_response_format_param.<locals>.<dictcomp>__pydantic_config__z#Unsupported response_format type - )ry   r   get	TypeErrorr   r   rC   rF   rT   inspectisclassr   r   r   r   )r   json_schema_typer   r*   r*   r/   to_response_format_param  s,   
	r   c                 C  s(   t | \}}t|}d||dddS )Nr   T)r   r   r   )rV   r   )r   r   r   )r   r   r   r   r*   r*   r/   to_openai_response_format$  s   
r   funcCallable[..., Any]type[BaseModel]c                 C  s  ddl m} | jd}ddd |D }|d }|| }dd	 |jD }t| }t| d
d}i }	|j	
 D ]\}
}||
 }t|rEq8|j|jurN|jnd}d}i }t|tu rt|}|d }tdd |dd D d}|r~t|dr~| d }n|r|j|d< |j|d< |}|dur|dttu r||d< |ddu r||
d|d< |stdi |}n|
 D ]
\}}t||| q||f|	|
< q8t|fi |	S )zNCreate a Pydantic model from a function's signature. (excluding context types)r   )parse_from_objectr,   r   c                 s  s    | ]}|  V  qd S N)
capitalizer+   xr*   r*   r/   	<genexpr>8      z7function_arguments_to_pydantic_model.<locals>.<genexpr>Argsc                 S  s   i | ]}|j |jqS r*   )arg_namer   )r+   pr*   r*   r/   rP   <  s    z8function_arguments_to_pydantic_model.<locals>.<dictcomp>Tinclude_extras.Nc                 s  s    | ]
}t |tr|V  qd S r   )ry   r   r   r*   r*   r/   r   S  s    r   asdict
attributesr   r   r*   )docstring_parserr   rC   r{   joinparamsr   	signaturer   r   rT   rb   r   emptyr   r   r
   nextr   r   r   r   r   r   setattrr   )r   r   	fnc_namesfnc_name
model_name	docstring
param_docsr   
type_hintsfields
param_nameparam	type_hintdefault_value
field_infofield_attrsannotated_argsannotated_fieldr   r   r*   r*   r/   r   2  sN   


r   )call_ctxfncFunctionTool | RawFunctionTooljson_argumentsrd   r   RunContext[Any] | None&tuple[tuple[Any, ...], dict[str, Any]]c                 C  s0  t | }t| dd}t|}t| trSt| }|j D ]+\}}|| }	||v rH|| du rHt	|	sH|j
t jjur@|j
||< qtd| dq||}
t|
}nt| tr]d|i}n	tdt|  i }|j D ]\}}|| }	t|	r|dur|||< qm|jdi i ||}|  |j|jfS )	z|
    Create the positional and keyword arguments to call a function tool from
    the raw function output from the LLM.
    Tr   Nz&Received None for required parameter 'z; ;this argument cannot be None and no default is available.raw_argumentsz Unsupported function tool type: r*   )r   r   r   r   ry   r   r   r   rT   _is_optional_typer   	Parameterr   r   model_validate_shallow_model_dumpr   rV   rb   bindapply_defaultsargskwargs)r   r   r   r   r   	args_dict
model_typer   r   r   r   
raw_fieldscontext_dictr,   boundr*   r*   r/   prepare_function_argumentsq  s<   





r   hintr   c                 C  sJ   t | tu rt| d } t | }|tu }|p|tju }|o$td t| v S Nr   )r   r   r
   r   types	UnionTyperV   )r   r`   is_unionr*   r*   r/   r     s   r   )by_aliasr   r   r   c                C  s@   i }| j j D ]\}}|r|jr|jn|}t| |||< q|S r   )	__class__model_fieldsrT   aliasgetattr)r   r   resultr   fieldkeyr*   r*   r/   r     s
   r   contentrf   thinkingasyncio.Eventc                 C  s   | d u rd S |  r'| t}|dkr#|  | |tt d  } | S d } | S | t}|dkr>|  | |tt d  } | S r   )is_setfindTHINK_TAG_ENDclearr2   THINK_TAG_STARTrU   )r  r  idxr*   r*   r/   strip_thinking_tokens  s   
	
r  valuec                   s   t tttttd f t|  rdS t| ts%t| ts%t| t	s%t| t
r.tdd | D S t| tr@t fdd|  D S dS )NTc                 s  s    | ]}t |V  qd S r   )_is_valid_function_outputrN   r*   r*   r/   r     r   z,_is_valid_function_output.<locals>.<genexpr>c                 3  s&    | ]\}}t | ot|V  qd S r   )ry   r  )r+   r  valVALID_TYPESr*   r/   r     s
    
F)rd   intfloatr^   complexrV   ry   r6   rU   	frozensettupleallr   rT   )r  r*   r  r/   r    s"   

r  c                   @  s.   e Zd ZU ded< ded< ded< ded< d	S )
FunctionCallResultr"   fnc_callzFunctionCallOutput | Nonefnc_call_outr   
raw_outputBaseException | Noneraw_exceptionNrB   r*   r*   r*   r/   r    s
   
 r  r  r"   output	exceptionr  c                 C  s   ddl m} ddlm}m} t|tr|}d}t||r-t| || j| j	|j
dd||dS t||r:t| d||dS |durNt| || j| j	ddd||dS t|sjtjd	| j d
| j	|dd t| d|ddS t| || j| j	t|puddd|ddS )zNCreate a FunctionCallResult, handling ToolError, StopResponse, and validation.r   )r#   )StopResponse	ToolErrorNTr   call_idr  is_errorr  r  r  r  zAn internal error occurredzAI function `z` returned an invalid output)r#  r  extrar   F)chat_contextr#   tool_contextr   r!  ry   BaseExceptionr  r   r#  rS   r  r   errorrd   )r  r  r  r#   r   r!  r*   r*   r/   make_function_call_output  st   




r,  	tool_callr$   tool_ctxr%   c             
     s0  ddl m}m} || j| j| jpd| jpi d}|j| j}|du rHt	
d| j d t||| j| jd| j d	d
dtd| j dS z%t|| jpOd|d\}}||i |}	t|	rf|	I dH }	t||	ddW S  ty }
 zt	jd| j d| j| jdd t|d|
dW  Y d}
~
S d}
~
ww )z3Execute a function tool call and return the result.r   r!   z{})r#  r   	argumentsr'  Nzunknown AI function ``zUnknown function: Tr"  r%  )r   r   r   )r  r  r  z!exception executing AI function `)r#  r/  r&  )r(  r"   r#   r#  r   r/  r'  function_toolsr   r   r~   r  r   r   asyncioiscoroutiner,  	Exceptionr  )r-  r.  r   r"   r#   r  r   fnc_args
fnc_kwargsr   er*   r*   r/   execute_function_call8  sP   



r8  )r&   r'   r(   r'   r)   r'   )rG   r   rH   r   r)   r>   )r]   rV   r)   r^   )rk   r   rj   r^   r)   rc   )r   r   r   r^   r)   r   )r   r   r)   r   )r   r   r)   r^   )r   r   r)   r   )r   r   r)   r   )r   r   r)   r   )r   r   r   rd   r   r   r)   r   )r   r   r)   r^   )r   r   r   r^   r)   r   )r  rf   r  r  r)   rf   )r  r   r)   r^   )r  r"   r  r   r  r  r)   r  )r-  r$   r.  r%   r   r   r)   r  )K
__future__r   r2  r|   r   r   collections.abcr   dataclassesr   typingr   r   r   r   r	   r
   r   r   pydanticr   r   r   pydantic.fieldsr   r   pydantic_corer   r   typing_extensionsr   livekitr   logr   utilsr   r   r   r(  r   r   r)  r   r   r_   r    r"   r#   llmr$   r%   r
  r  r=   r>   r\   rb   rc   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r,  r8  r*   r*   r*   r/   <module>   sh    (
 


	=



!
C
:


M