o
    i+i                     @  s  d dl mZ d dlZd dlZd dlmZ d dlmZmZ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mZ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!m"Z"m#Z#m$Z$m%Z%m&Z& ddl'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0 erddl1m2Z2 ddl3m4Z4 ddl5m6Z6 G dd deZ7G dd deZ8G dd deZ9G dd deZ:G dd deZ;G dd deZ<G dd deZ=ee7e8B e9B e:B e;B e<B e=B ed d!f Z>G d"d# d#eZ?G d$d% d%eZ@G d&d' d'eZAG d(d) d)eZBG d*d+ d+eZCG d,d- d-eZDG d.d/ d/eZEG d0d1 d1eZFG d2d3 d3eZGG d4d5 d5eZHdAd:d;ZIG d<d= d=ZJe
d> ZKG d?d@ d@ejLeK ZMdS )B    )annotationsN)asdict)TYPE_CHECKING	AnnotatedAnyLiteral)	BaseModelField)rtc   )utils)ChatItemChatMessageFunctionCallFunctionCallOutputFunctionToolRawFunctionToolToolsetlogger)AgentMetrics)RPC_GET_AGENT_INFORPC_GET_CHAT_HISTORYRPC_GET_SESSION_STATERPC_SEND_MESSAGETOPIC_AGENT_REQUESTTOPIC_AGENT_RESPONSE
TOPIC_CHATTOPIC_CLIENT_EVENTS   )	
AgentStateAgentStateChangedEventConversationItemAddedEvent
ErrorEventFunctionToolsExecutedEventMetricsCollectedEventUserInputTranscribedEvent	UserStateUserStateChangedEvent)AgentSession)RoomIO)TextInputCallbackc                   @  2   e Zd ZU dZded< ded< ded< ded< d	S )
ClientAgentStateChangedEventagent_state_changedzLiteral['agent_state_changed']typer    	old_state	new_statefloat
created_atN__name__
__module____qualname__r/   __annotations__ r9   r9   d/var/www/html/livekit_bhavya/venv/lib/python3.10/site-packages/livekit/agents/voice/client_events.pyr-   4   
   
 r-   c                   @  r,   )
ClientUserStateChangedEventuser_state_changedzLiteral['user_state_changed']r/   r'   r0   r1   r2   r3   Nr4   r9   r9   r9   r:   r<   ;   r;   r<   c                   @  *   e Zd ZU dZded< ded< ded< dS )	 ClientConversationItemAddedEventconversation_item_addedz"Literal['conversation_item_added']r/   r   itemr2   r3   Nr4   r9   r9   r9   r:   r?   B      
 r?   c                   @  s:   e Zd ZU dZded< ded< ded< ded	< d
ed< dS )ClientUserInputTranscribedEventuser_input_transcribedz!Literal['user_input_transcribed']r/   str
transcriptboolis_final
str | Nonelanguager2   r3   Nr4   r9   r9   r9   r:   rC   H   s   
 rC   c                   @  s2   e Zd ZU dZded< ded< ded< ded	< d
S ) ClientFunctionToolsExecutedEventfunction_tools_executedz"Literal['function_tools_executed']r/   zlist[FunctionCall]function_callszlist[FunctionCallOutput | None]function_call_outputsr2   r3   Nr4   r9   r9   r9   r:   rK   P   r;   rK   c                   @  r>   )	ClientMetricsCollectedEventmetrics_collectedzLiteral['metrics_collected']r/   r   metricsr2   r3   Nr4   r9   r9   r9   r:   rO   W   rB   rO   c                   @  r>   )	ClientErrorEventerrorzLiteral['error']r/   rE   messager2   r3   Nr4   r9   r9   r9   r:   rR   ]   rB   rR   r/   )discriminatorc                   @     e Zd ZdS )GetSessionStateRequestNr5   r6   r7   r9   r9   r9   r:   rW   o       rW   c                   @  s6   e Zd ZU ded< ded< ded< ded< d	ed
< dS )GetSessionStateResponser    agent_stater'   
user_staterE   agent_idzdict[str, Any]optionsr2   r3   Nr5   r6   r7   r8   r9   r9   r9   r:   rZ   s   s   
 rZ   c                   @  rV   )GetChatHistoryRequestNrX   r9   r9   r9   r:   r`   {   rY   r`   c                   @     e Zd ZU ded< dS )GetChatHistoryResponselist[ChatItem]itemsNr_   r9   r9   r9   r:   rb         
 rb   c                   @  rV   )GetAgentInfoRequestNrX   r9   r9   r9   r:   rf      rY   rf   c                   @  s.   e Zd ZU ded< ded< ded< ded< d	S )
GetAgentInfoResponserE   idrI   instructions	list[str]toolsrc   chat_ctxNr_   r9   r9   r9   r:   rg      s
   
 rg   c                   @  ra   )SendMessageRequestrE   textNr_   r9   r9   r9   r:   rm      re   rm   c                   @  ra   )SendMessageResponserc   rd   Nr_   r9   r9   r9   r:   ro      re   ro   c                   @  s*   e Zd ZU dZded< ded< ded< dS )StreamRequestzRequest sent via text stream.rE   
request_idmethodpayloadN)r5   r6   r7   __doc__r8   r9   r9   r9   r:   rp      s
   
 rp   c                   @  s.   e Zd ZU dZded< ded< dZded< dS )StreamResponsezResponse sent via text stream.rE   rq   rs   NrI   rS   )r5   r6   r7   rt   r8   rS   r9   r9   r9   r:   ru      s
   
 ru   rk   	list[Any]returnrj   c                 C  sJ   g }| D ]}t |ttfr||jj qt |tr"|t|j	 q|S N)

isinstancer   r   appendinfonamer   extend_tool_namesrk   )rk   resulttoolr9   r9   r:   r~      s   
r~   c                   @  sN  e Zd ZdZdXdd	ZedYddZdZddZdZddZd[ddZ	dZddZ
dZddZd\ddZejedd\d d!Zd]d#d$Zd]d%d&Zd]d'd(Zd]d)d*ZdZd+d,Zd^d/d0Zd_d2d3Zd`d5d6Zdad8d9Zdbd;d<Zdcd>d?ZdddAdBZdedDdEZdfdGdHZejeddfdIdJZdgdMdNZ dgdOdPZ!dgdQdRZ"dgdSdTZ#d\dUdVZ$dWS )hClientEventsHandlera  
    Handles exposing AgentSession state to room participants and allows interaction.

    This class provides:
    - Event streaming: Automatically streams AgentSession events to clients via a text stream
    - RPC handlers: Allows clients to request state, chat history, and agent info on demand
    - Text input handling: Receives text messages from clients and generates agent replies
    sessionr)   room_ior*   rw   Nonec                 C  s<   || _ || _d | _d| _d| _d| _d| _t | _d| _	d S NF)
_session_room_io_text_input_cb_text_stream_handler_registered_rpc_handlers_registered_request_handler_registered_event_handlers_registeredset_tasks_started)selfr   r   r9   r9   r:   __init__   s   
zClientEventsHandler.__init__rtc.Roomc                 C  s   | j jS rx   )r   roomr   r9   r9   r:   _room   s   zClientEventsHandler._roomc                   s.   | j rd S d| _ |   |   |   d S NT)r   _register_rpc_handlers_register_request_handler_register_event_handlersr   r9   r9   r:   start   s   zClientEventsHandler.startc                   sl  | j sdS d| _ | jr!z| jt W n	 ty   Y nw d| _| jrOz| jjt	 | jjt
 | jjt | jjt W n	 tyK   Y nw d| _| jrgz| jt W n	 tyc   Y nw d| _| jr| jd| j | jd| j | jd| j | jd| j | jd| j | jd| j | jd	| j d| _tjj| j I dH  | j  dS )
z Cleanup and unregister handlers.NFr.   r=   r@   rL   rP   rD   rS   )r   r   r   unregister_text_stream_handlerr   
ValueErrorr   local_participantunregister_rpc_methodr   r   r   r   	Exceptionr   r   r   r   off_on_agent_state_changed_on_user_state_changed_on_conversation_item_added_on_function_tools_executed_on_metrics_collected_on_user_input_transcribed	_on_errorr   aiocancel_and_waitr   clearr   r9   r9   r:   aclose   sN   zClientEventsHandler.aclosetext_input_cbr+   c                 C  sT   || _ | js(z| jt| j d| _W dS  ty'   tdt d Y dS w dS )z
        Register a text input handler to receive messages from clients.

        Args:
            text_input_cb: Callback function to handle incoming text messages.
        Ttext stream handler for topic 'z' already set, ignoringN)	r   r   r   register_text_stream_handlerr   _on_user_text_inputr   r   warning)r   r   r9   r9   r:   register_text_input  s   

z'ClientEventsHandler.register_text_inputc                 C  s\   | j rd S | jjt| j | jjt| j | jjt| j	 | jjt
| j d| _ d S r   )r   r   r   register_rpc_methodr   _rpc_get_session_stater   _rpc_get_chat_historyr   _rpc_get_agent_infor   _rpc_send_messager   r9   r9   r:   r     s   
z*ClientEventsHandler._register_rpc_handlersc                 C  sN   | j rdS z| jt| j d| _ W dS  ty&   tdt d Y dS w )zERegister text stream handler for requests (no size limit unlike RPC).NTr   z' already set)r   r   r   r   _on_stream_requestr   r   r   r   r9   r9   r:   r   (  s   z-ClientEventsHandler._register_request_handlerreaderrtc.TextStreamReaderparticipant_identityrE   c                 C  s0   t | ||}| j| || jj dS )z%Handle incoming text stream requests.N)asynciocreate_task_handle_stream_requestr   addadd_done_callbackdiscardr   r   r   taskr9   r9   r:   r   3  s   z&ClientEventsHandler._on_stream_requestr   c           	   
     sH  z|  I dH }t|}d}zF|jdkr | |jI dH }n5|jdkr/| |jI dH }n&|jdkr>| |jI dH }n|jdkrM| |jI dH }nd}d|j }W n t	yn } zd}t
|}W Y d}~nd}~ww t|j||d}| jjj| t|gd	I dH  W dS  t	y } ztjd
|d W Y d}~dS d}~ww )z0Process a text stream request and send response.Nget_session_stateget_chat_historyget_agent_infosend_message zUnknown method: )rq   rs   rS   topicdestination_identitieszfailed to handle stream requestexc_info)read_allrp   model_validate_jsonrr   _stream_get_session_staters   _stream_get_chat_history_stream_get_agent_info_stream_send_messager   rE   ru   rq   r   r   	send_textmodel_dump_jsonr   r   r   )	r   r   r   datarequestrS   response_payloaderesponser9   r9   r:   r   9  sH   




z*ClientEventsHandler._handle_stream_requestrs   c                   B   | j j}t| j j| j j|jt| j j| j jpt		 d}|
 S )z)Handle get_session_state via text stream.r[   r\   r]   r^   r3   r   current_agentrZ   r[   r\   rh   r   r^   _started_attimer   r   rs   agentr   r9   r9   r:   r   e  s   
z-ClientEventsHandler._stream_get_session_statec                      t t| jjjd}| S )z(Handle get_chat_history via text stream.rd   rb   listr   historyrd   r   )r   rs   r   r9   r9   r:   r   q  s   z,ClientEventsHandler._stream_get_chat_historyc                   4   | j j}t|j|jt|jt|jj	d}|
 S )z6Handle get_agent_info via text stream (no size limit).rh   ri   rk   rl   r   r   rg   rh   ri   r~   rk   r   rl   rd   r   r   r9   r9   r:   r   v  s   
z*ClientEventsHandler._stream_get_agent_infoc                   s\   ddl m} t|}| jj|jdI dH }g }|jD ]}||j	 qt
|d}| S )z$Handle send_message via text stream.r   	RunResult
user_inputNr   )
run_resultr   rm   r   r   runrn   eventsrz   rA   ro   r   )r   rs   r   r   r   rd   eventr   r9   r9   r:   r     s   


z(ClientEventsHandler._stream_send_messagec                 C  s   | j rd S | jd| j | jd| j | jd| j | jd| j | jd| j | jd| j | jd| j	 d| _ d S )	Nr.   r=   r@   rL   rP   rD   rS   T)
r   r   onr   r   r   r   r   r   r   r   r9   r9   r:   r     s   
z,ClientEventsHandler._register_event_handlersr   r!   c                 C  "   t |j|j|jd}| | d S N)r0   r1   r3   )r-   r0   r1   r3   _stream_client_eventr   r   client_eventr9   r9   r:   r        z+ClientEventsHandler._on_agent_state_changedr(   c                 C  r   r   )r<   r0   r1   r3   r   r   r9   r9   r:   r     r   z*ClientEventsHandler._on_user_state_changedr"   c                 C  s.   t |jtsd S t|j|jd}| | d S )N)rA   r3   )ry   rA   r   r?   r3   r   r   r9   r9   r:   r     s   z/ClientEventsHandler._on_conversation_item_addedr&   c                 C  s&   t |j|j|j|jd}| | d S )N)rF   rH   rJ   r3   )rC   rF   rH   rJ   r3   r   r   r9   r9   r:   r     s   z.ClientEventsHandler._on_user_input_transcribedr$   c                 C  r   )N)rM   rN   r3   )rK   rM   rN   r3   r   r   r9   r9   r:   r     r   z/ClientEventsHandler._on_function_tools_executedr%   c                 C  s,   |j d u rd S t|j |jd}| | d S )N)rQ   r3   )rQ   rO   r3   r   r   r9   r9   r:   r     s   
z)ClientEventsHandler._on_metrics_collectedr#   c                 C  s,   t |jr	t|jnd|jd}| | d S )NzUnknown error)rT   r3   )rR   rS   rE   r3   r   r   r9   r9   r:   r     s
   zClientEventsHandler._on_errorlist[str] | Nonec                 C  s(   | j j}|du r
dS d}|sdS |jgS )zGet the identities of participants that should receive client events.

        Returns the linked RoomIO participant if it has the required permissions,
        or None if no valid target is available.
        NT)r   linked_participantidentity)r   linkedhas_permissionr9   r9   r:   _get_target_identities  s   z*ClientEventsHandler._get_target_identitiesClientEventc                 C  s.   t | |}| j| || jj d S rx   )r   r   _send_client_eventr   r   r   r   )r   r   r   r9   r9   r:   r     s   z(ClientEventsHandler._stream_client_eventc              
     s   | j  sd S |  }|d u rd S z"| }| j jjt|dI d H }||I d H  | I d H  W d S  t	yN } zt
jd|d W Y d }~d S d }~ww )Nr   z!failed to stream event to clientsr   )r   isconnectedr   r   r   stream_textr   writer   r   r   r   )r   r   r   
event_datawriterr   r9   r9   r:   r     s$   
z&ClientEventsHandler._send_client_eventr   rtc.RpcInvocationDatac                   r   )Nr   r   r   r   r   r   r9   r9   r:   r     s   
z*ClientEventsHandler._rpc_get_session_statec                   r   )Nr   r   )r   r   r   r9   r9   r:   r     s   z)ClientEventsHandler._rpc_get_chat_historyc                   r   )Nr   r   r  r9   r9   r:   r     s   
z'ClientEventsHandler._rpc_get_agent_infoc                   s^   ddl m} t|j}| jj|jdI d H }g }|jD ]}|	|j
 qt|d}| S )Nr   r   r   r   )r   r   rm   r   rs   r   r   rn   r   rz   rA   ro   r   )r   r   r   r   r   rd   r   r   r9   r9   r:   r      s   

z%ClientEventsHandler._rpc_send_messagec                   s   j j}|r||jkrd S jj|  std d S d	 fdd}jd u r2t	d d S t
|j}j| |jj d S )
Nz*participant not found, ignoring text inputr   r+   rw   r   c                   sP   ddl m}  I d H }| j||j d}t|r&|I d H  d S d S )Nr   )TextInputEvent)rn   r{   participant)room_io.typesr  r   r   r{   r   iscoroutine)r   r  rn   text_input_resultr	  r   r   r9   r:   
_read_text7  s   
z;ClientEventsHandler._on_user_text_input.<locals>._read_textz3text input callback is not set, ignoring text inputr   r+   rw   r   )r   r   r   r   remote_participantsgetr   r   r   rS   r   r   r   r   r   r   )r   r   r   r   r  r   r9   r  r:   r   -  s   


z'ClientEventsHandler._on_user_text_inputN)r   r)   r   r*   rw   r   )rw   r   rw   r   r  r   r   r   rE   rw   r   )rs   rE   rw   rE   )r   r!   rw   r   )r   r(   rw   r   )r   r"   rw   r   )r   r&   rw   r   )r   r$   rw   r   )r   r%   rw   r   )r   r#   rw   r   )rw   r   )r   r   rw   r   )r   r  rw   rE   )%r5   r6   r7   rt   r   propertyr   r   r   r   r   r   r   r   log_exceptionsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r9   r9   r9   r:   r      sD    
	

	
,




+









	










r   )r.   r=   r@   rD   rL   rP   rS   c                      s   e Zd ZdZd2 fdd	Zd3d
dZd3ddZd4ddZd4ddZd5ddZ	d5ddZ
d6ddZd7d8d"d#Zd9d%d&Zd:d(d)Zd;d+d,Zd7d<d0d1Z  ZS )=RemoteSessiona  
    Client-side interface to interact with a remote AgentSession.

    This class allows frontends/clients to:
    - Subscribe to real-time events from the agent session
    - Query session state, chat history, and agent info via RPC
    - Send messages to the agent

    Example:
        ```python
        session = RemoteSession(room, agent_identity="agent")
        session.on("agent_state_changed", lambda ev: print(f"Agent state: {ev.new_state}"))
        session.on("user_state_changed", lambda ev: print(f"User state: {ev.new_state}"))
        session.on("conversation_item_added", lambda ev: print(f"Message: {ev.item}"))
        await session.start()

        # Query current state
        state = await session.fetch_session_state()
        history = await session.fetch_chat_history()

        # Send a message and get all generated items
        response = await session.send_message("Hello!")
        for item in response.items:
            print(f"Item: {item}")
        ```
    r   r   agent_identityrE   rw   r   c                   s.   t    || _|| _d| _t | _i | _d S r   )superr   r   _agent_identityr   r   r   _pending_requests)r   r   r  	__class__r9   r:   r   s  s   

zRemoteSession.__init__c                   s6   | j rd S d| _ | jt| j | jt| j d S r   )r   r   r   r   _on_event_streamr   _on_response_streamr   r9   r9   r:   r     s   zRemoteSession.startc                   s   | j sd S d| _ z| jt W n	 ty   Y nw z| jt W n	 ty,   Y nw | j D ]}|  q2| j	  t
jj| j I d H  | j	  d S r   )r   r   r   r   r   r   r  valuescancelr   r   r   r   r   )r   futurer9   r9   r:   r     s&   

zRemoteSession.acloser   r   r   c                 C  <   || j krd S t| |}| j| || jj d S rx   )r  r   r   _read_eventr   r   r   r   r   r9   r9   r:   r    
   
zRemoteSession._on_event_streamc                 C  r"  rx   )r  r   r   _read_responser   r   r   r   r   r9   r9   r:   r    r$  z!RemoteSession._on_response_streamc              
     s   z(|  I dH }t|}| j|jd}|r$| s'|| W dS W dS W dS  tyC } zt	j
d|d W Y d}~dS d}~ww )z4Read and dispatch a response to the waiting request.Nzfailed to read stream responser   )r   ru   r   r  poprq   done
set_resultr   r   r   )r   r   r   r   r!  r   r9   r9   r:   r%    s   
zRemoteSession._read_responsec              
     sn   z|  I d H }| |}|r| |j| W d S W d S  ty6 } ztjd|d W Y d }~d S d }~ww )Nzfailed to parse client eventr   )r   _parse_eventemitr/   r   r   r   )r   r   r   r   r   r9   r9   r:   r#    s   
zRemoteSession._read_eventr   ClientEvent | Nonec              
   C  sT   ddl m} z|t|W S  ty) } ztd|  W Y d }~d S d }~ww )Nr   )TypeAdapterzfailed to parse event: )pydanticr,  r   validate_jsonr   r   r   )r   r   r,  r   r9   r9   r:   r)    s   zRemoteSession._parse_event      N@rr   rs   timeoutr2   c                   s   t d}t|||d}t }|| j|< z'| jjj|	 t
| jgdI dH  tj||dI dH }|jr:t|j|jW S  tjyM   | j|d   ty[   | j|d  w )z5Send a request via text stream and wait for response.req_)rq   rr   rs   r   N)r0  )r   	shortuuidrp   r   Futurer  r   r   r   r   r   r  wait_forrS   r   rs   TimeoutErrorr&  )r   rr   rs   r0  rq   r   r!  r   r9   r9   r:   _send_request  s4   


zRemoteSession._send_requestrZ   c                   *   t  }| jd| dI d H }t|S )Nr   rr   rs   )rW   r6  r   rZ   r   r   r   r   r9   r9   r:   fetch_session_state     
z!RemoteSession.fetch_session_staterb   c                   r7  )Nr   r8  )r`   r6  r   rb   r   r9  r9   r9   r:   fetch_chat_history  r;  z RemoteSession.fetch_chat_historyrg   c                   r7  )Nr   r8  )rf   r6  r   rg   r   r9  r9   r9   r:   fetch_agent_info  r;  zRemoteSession.fetch_agent_inforn   response_timeoutro   c                   s0   t |d}| jd| |dI d H }t|S )N)rn   r   )rr   rs   r0  )rm   r6  r   ro   r   )r   rn   r>  r   r   r9   r9   r:   r     s   

zRemoteSession.send_message)r   r   r  rE   rw   r   r  r  )r   r   rw   r   )r   rE   rw   r+  )r/  )rr   rE   rs   rE   r0  r2   rw   rE   )rw   rZ   )rw   rb   )rw   rg   )rn   rE   r>  r2   rw   ro   )r5   r6   r7   rt   r   r   r   r  r  r%  r#  r)  r6  r:  r<  r=  r   __classcell__r9   r9   r  r:   r  W  s    






		
!

r  )rk   rv   rw   rj   )N
__future__r   r   r   dataclassesr   typingr   r   r   r   r-  r   r	   livekitr
   r   r   llmr   r   r   r   r   r   r   logr   rQ   r   typesr   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   agent_sessionr)   r   r*   r
  r+   r-   r<   r?   rC   rK   rO   rR   r   rW   rZ   r`   rb   rf   rg   rm   ro   rp   ru   r~   r   RemoteSessionEventTypesEventEmitterr  r9   r9   r9   r:   <module>   sx    $	(,


   