o
    i9                     @  s  d dl mZ d dlZd dlZd dlZd dl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mZmZmZmZ d dlmZ d d	lmZ d d
lmZmZm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& ddl'm(Z( ddl)m*Z* ddl+m,Z,m-Z-m.Z.m"Z/ ddlm0Z0m1Z1m2Z2m3Z3 ddl"m4Z4 ddl5m6Z6m7Z7 ddl8m9Z9m:Z: G dd deZ;G dd deZ<G dd deZ=G dd deZ>G d d! d!eZ?G d"d# d#eZ@ed$ZAG d%d& d&eejBed' eAB  eeA ZCG d(d) d)eZDdS )*    )annotationsN)ABCabstractmethod)AsyncIterableAsyncIterator)datetimetimezone)TracebackType)AnyClassVarGenericLiteralTypeVar)trace)AttributeValue)	BaseModel
ConfigDictField)rtc)Metadata   )utils)APIConnectionErrorAPIErrorAPIStatusErrorlogger)
LLMMetrics)_chat_ctx_to_otel_eventstrace_typestracerr   )DEFAULT_API_CONNECT_OPTIONS	NOT_GIVENAPIConnectOptions
NotGivenOr)aio   )ChatContextChatRole)Tool
ToolChoicec                   @  sT   e Zd ZU ded< 	 ded< 	 dZded< 	 dZded< 	 dZded< 	 ded< d	S )
CompletionUsageintcompletion_tokensprompt_tokensr   prompt_cached_tokenscache_creation_tokenscache_read_tokenstotal_tokensN)__name__
__module____qualname____annotations__r/   r0   r1    r7   r7   X/var/www/html/livekit_bhavya/venv/lib/python3.10/site-packages/livekit/agents/llm/llm.pyr+   #   s   
 r+   c                   @  s>   e Zd ZU dZded< ded< ded< ded< dZd	ed
< dS )FunctionToolCallfunctionzLiteral['function']typestrname	argumentscall_idNdict[str, Any] | Noneextra)r3   r4   r5   r;   r6   rA   r7   r7   r7   r8   r9   2   s   
 r9   c                   @  s8   e Zd ZU dZded< eedZded< dZded	< dS )
CollectedResponse r<   textdefault_factorylist[FunctionToolCall]
tool_callsNCompletionUsage | Noneusage)	r3   r4   r5   rD   r6   r   listrH   rJ   r7   r7   r7   r8   rB   ;   s   
 rB   c                   @  sD   e Zd ZU dZded< dZded< eedZded< dZ	d	ed
< dS )ChoiceDeltaNzChatRole | Nonerolez
str | NonecontentrE   rG   rH   r@   rA   )
r3   r4   r5   rM   r6   rN   r   rK   rH   rA   r7   r7   r7   r8   rL   A   s   
 rL   c                   @  s.   e Zd ZU ded< dZded< dZded< dS )	ChatChunkr<   idNzChoiceDelta | NonedeltarI   rJ   )r3   r4   r5   r6   rQ   rJ   r7   r7   r7   r8   rO   I   s   
 rO   c                   @  sP   e Zd ZU eddZdZded< ded< ded	< ed
ddZded< ded< dS )LLMErrorT)arbitrary_types_allowed	llm_errorzLiteral['llm_error']r;   float	timestampr<   label.)exclude	ExceptionerrorboolrecoverableN)	r3   r4   r5   r   model_configr;   r6   r   rZ   r7   r7   r7   r8   rR   O   s   
 
rR   TEventc                      s   e Zd Zd+ fddZed,ddZed,dd	Zed,d
dZede	e
e
e
dd-ddZd+ddZd+dd Zd.d!d"Zd/d)d*Z  ZS )0LLMreturnNonec                   s*   t    t| j dt| j | _d S )N.)super__init__r;   r4   r3   _labelself	__class__r7   r8   rd   `   s   
 zLLM.__init__r<   c                 C     | j S N)re   rf   r7   r7   r8   rW   d      z	LLM.labelc                 C     dS )zGet the model name/identifier for this LLM instance.

        Returns:
            The model name if available, "unknown" otherwise.

        Note:
            Plugins should override this property to provide their model information.
        unknownr7   rf   r7   r7   r8   modelh      
z	LLM.modelc                 C  rm   )zGet the provider name/identifier for this LLM instance.

        Returns:
            The provider name if available, "unknown" otherwise.

        Note:
            Plugins should override this property to provide their provider information.
        rn   r7   rf   r7   r7   r8   providert   rp   zLLM.providerN)toolsconn_optionsparallel_tool_callstool_choiceextra_kwargschat_ctxr'   rr   list[Tool] | Noners   r#   rt   NotGivenOr[bool]ru   NotGivenOr[ToolChoice]rv   NotGivenOr[dict[str, Any]]	LLMStreamc                C  s   d S rk   r7   )rg   rw   rr   rs   rt   ru   rv   r7   r7   r8   chat   rp   zLLM.chatc                 C  rm   )z&Pre-warm connection to the LLM serviceNr7   rf   r7   r7   r8   prewarm   s   zLLM.prewarmc                      d S rk   r7   rf   r7   r7   r8   aclose   s    z
LLM.aclosec                      | S rk   r7   rf   r7   r7   r8   
__aenter__      zLLM.__aenter__exc_typetype[BaseException] | NoneexcBaseException | Noneexc_tbTracebackType | Nonec                      |   I d H  d S rk   r   rg   r   r   r   r7   r7   r8   	__aexit__      zLLM.__aexit__r`   ra   )r`   r<   )rw   r'   rr   rx   rs   r#   rt   ry   ru   rz   rv   r{   r`   r|   )r`   r_   r   r   r   r   r   r   r`   ra   )r3   r4   r5   rd   propertyrW   ro   rq   r   r!   r"   r}   r~   r   r   r   __classcell__r7   r7   rh   r8   r_   [   s&    


r_   )metrics_collectedrZ   c                   @  s   e Zd ZU dZded< d<ddZed=ddZd=ddZd>ddZ	e
jedd?ddZed@dd ZedAd!d"Zd=d#d$ZdBd&d'ZdCd)d*ZdDd+d,ZdEd3d4ZdFd6d7ZdGd9d:Zd;S )Hr|   llm_requestzClassVar[str]_llm_request_span_namellmr_   rw   r'   rr   
list[Tool]rs   r#   r`   ra   c                  s   | _ | _| _| _tjt   _tj	 jd _
 j
\ _}d _tj |dd _d fdd}tj| d	d _ j fd
d d  _d S )Nr   FzLLM._metrics_task)r=   r`   ra   c                    sf   t j jdd } t jD ]
\}}| || q  I d H  W d    d S 1 s,w   Y  d S )NF)end_on_exit)r    start_as_current_spanr   r   	_chat_ctx	add_event
_main_task)spanr=   
attributesrf   r7   r8   _traceable_main_task   s   "z0LLMStream.__init__.<locals>._traceable_main_taskzLLM._main_taskc                   s
    j  S rk   )	_event_chclose)_rf   r7   r8   <lambda>   s   
 z$LLMStream.__init__.<locals>.<lambda>r   )_llmr   _tools_conn_optionsr%   ChanrO   r   	itertoolstee
_tee_aiter_event_aiter_current_attempt_has_errorasynciocreate_task_metrics_monitor_task_metrics_task_taskadd_done_callback_llm_request_span)rg   r   rw   rr   rs   monitor_aiterr   r7   rf   r8   rd      s   

zLLMStream.__init__c                   r   rk   r7   rf   r7   r7   r8   _run   r   zLLMStream._runc                   s  t  | _| jtjdtj| jjtj	| jj
i t| jjd D ]}z=td.}|tj| z|  I d H W W  d    W   S  tyV } zt||  d }~ww 1 sZw   Y  W q! ty } ztt|trz|jdkrzW Y d }~ d S | j|}| jjdks|js| j|dd  || jjkr| j|dd td| jjd  d	|| j|d
d tjd| d| d| jj |d dd |dkrt!"|I d H  d| _#W Y d }~q!d }~w ty } z| j|dd  d }~ww d S )Nr}   r&   llm_request_runi  r   F)r\   z(failed to generate LLM completion after z	 attemptsTz#failed to generate LLM completion: z, retrying in s)r   attempt)rA   )$r   get_current_spanr   set_attributesr   ATTR_GEN_AI_OPERATION_NAMEATTR_GEN_AI_PROVIDER_NAMEr   rq   ATTR_GEN_AI_REQUEST_MODELro   ranger   	max_retryr    r   set_attributeATTR_RETRY_COUNTr   rY   telemetry_utilsrecord_exceptionr   
isinstancer   status_code_interval_for_retry	retryable_emit_errorr   r   warningre   r   sleepr   )rg   iattempt_spaneretry_intervalr7   r7   r8   r      sh   


zLLMStream._main_task	api_errorrY   r\   r[   c              	   C  s,   d| _ | jdtt | jj||d d S )NTrZ   )rV   rW   rZ   r\   )r   r   emitrR   timere   )rg   r   r\   r7   r7   r8   r      s   zLLMStream._emit_errorr   event_aiterAsyncIterable[ChatChunk]c                   s  t  }d}d}d }d}g }d }|2 z;3 d H W }	|	j}|dkr.t  | }ttj }|	jrF|	jj	r;||	jj	7 }|	jj
rF||	jj
 |	jd urN|	j}q6 t  | }
| js]|dk r_d S tt   |||
| j | jj|rr|jnd|rx|jnd|r~|jnd|r|jnd|r|j|
 ndt| jj| jjdd}| jr| jtj|  | jtj |jtj!|ji |r| jtj"d| d dd	i}|r||d
< |rdd |D |d< | j#tj$| | j%d| d S )Ng      rC   r   g        )
model_namemodel_provider)rV   
request_idttftduration	cancelledrW   r-   r.   r/   r2   tokens_per_secondmetadata"rM   	assistantrN   c                 S  s*   g | ]}t |j|jd |jddqS ))r=   r>   r:   )r:   rP   r;   )jsondumpsr=   r>   r?   ).0	tool_callr7   r7   r8   
<listcomp>P  s    z3LLMStream._metrics_monitor_task.<locals>.<listcomp>rH   r   )&r   perf_counterrP   r   nowr   utc	isoformatrQ   rN   rH   extendrJ   r   r   r   r   r   re   r-   r.   r/   r2   r   ro   rq   r   r   r   ATTR_LLM_METRICSmodel_dump_jsonr   ATTR_GEN_AI_USAGE_INPUT_TOKENSATTR_GEN_AI_USAGE_OUTPUT_TOKENS#ATTR_LANGFUSE_COMPLETION_START_TIMEr   EVENT_GEN_AI_CHOICEr   )rg   r   
start_timer   r   rJ   response_contentrH   completion_start_timeevr   metricscompletion_event_bodyr7   r7   r8   r   	  s   



zLLMStream._metrics_monitor_taskc                 C  rj   rk   )r   rf   r7   r7   r8   rw   ^  rl   zLLMStream.chat_ctxc                 C  rj   rk   )r   rf   r7   r7   r8   rr   b  rl   zLLMStream.toolsc                   sJ   t | jI d H  | jI d H  | jr| j  d | _| j I d H  d S rk   )r%   cancel_and_waitr   r   r   endr   r   rf   r7   r7   r8   r   f  s   
zLLMStream.acloserO   c                   sJ   z| j  I d H }W |S  ty$   | j s!| j  }r!|td w rk   )r   	__anext__StopAsyncIterationr   r   	exception)rg   valr   r7   r7   r8   r   o  s   zLLMStream.__anext__AsyncIterator[ChatChunk]c                 C  s   | S rk   r7   rf   r7   r7   r8   	__aiter__z  s   zLLMStream.__aiter__c                   r   rk   r7   rf   r7   r7   r8   r   }  r   zLLMStream.__aenter__r   r   r   r   r   r   c                   r   rk   r   r   r7   r7   r8   r     r   zLLMStream.__aexit__AsyncIterable[str]c                   s   d fdd}| S )z
        Convert the LLMStream to an async iterable of strings.
        This assumes the stream will not call any tools.
        r`   r   c               	    sl    4 I d H "  2 z3 d H W } | j r| j jr| j jV  q
6 W d   I d H  d S 1 I d H s/w   Y  d S rk   )rQ   rN   )chunkrf   r7   r8   	_iterable  s   
.z,LLMStream.to_str_iterable.<locals>._iterableNr`   r   r7   )rg   r   r7   rf   r8   to_str_iterable  s   zLLMStream.to_str_iterablerB   c              	     s   g }g }d}| 4 I dH 6 | 2 z'3 dH W }|j r/|j jr$||j j |j jr/||j j |jdur7|j}q6 W d  I dH  n1 I dH sIw   Y  td| ||dS )a  Collect the entire stream into a single response.

        Example:
            ```python
            from livekit.agents import llm

            response = await my_llm.chat(chat_ctx=ctx, tools=tools).collect()

            for tc in response.tool_calls:
                result = await llm.execute_function_call(tc, tool_ctx)
                ctx.insert(result.fnc_call)
                if result.fnc_call_out:
                    ctx.insert(result.fnc_call_out)
            ```
        NrC   )rD   rH   rJ   )	rQ   rN   appendrH   r   rJ   rB   joinstrip)rg   
text_partsrH   rJ   r   r7   r7   r8   collect  s*   
(
zLLMStream.collectN)
r   r_   rw   r'   rr   r   rs   r#   r`   ra   r   )r   rY   r\   r[   r`   ra   )r   r   r`   ra   )r`   r'   )r`   r   )r`   rO   )r`   r   )r`   r|   r   r   )r`   rB   )r3   r4   r5   r   r6   rd   r   r   r   r   r   log_exceptionsr   r   r   rw   rr   r   r   r   r   r   r   r  r7   r7   r7   r8   r|      s(   
 
"

7
T

	



r|   )E
__future__r   r   r   r   abcr   r   collections.abcr   r   r   r   typesr	   typingr
   r   r   r   r   opentelemetryr   opentelemetry.util.typesr   pydanticr   r   r   livekitr   livekit.agents.metrics.baser   rC   r   _exceptionsr   r   r   logr   r   r   	telemetryr   r   r    r   r!   r"   r#   r$   r%   chat_contextr'   r(   tool_contextr)   r*   r+   r9   rB   rL   rO   rR   r^   EventEmitterr_   r|   r7   r7   r7   r8   <module>   sH    		
C