o
    h                     @  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 d dl	m
Z
 ddl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 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 m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/ ddlm0Z0 ddl1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9 ddl:m;Z;m<Z<m=Z= ddl>m?Z?m@Z@mAZA ddlBmCZCmDZDmEZEmFZFmGZG G dd de=ZHdS )    )annotationsN)AsyncIterator)Anycast)assert_never   )Agent)ModelBehaviorError	UserError)Handoff)logger)RunContextWrapperTContext)FunctionTool)ToolContext   )RealtimeAgent)RealtimeRunConfigRealtimeSessionModelSettingsRealtimeUserInput)RealtimeAgentEndEventRealtimeAgentStartEventRealtimeAudioRealtimeAudioEndRealtimeAudioInterruptedRealtimeErrorRealtimeEventInfoRealtimeGuardrailTrippedRealtimeHandoffEventRealtimeHistoryAddedRealtimeHistoryUpdated"RealtimeInputAudioTimeoutTriggeredRealtimeRawModelEventRealtimeSessionEventRealtimeToolEndRealtimeToolStart)realtime_handoff)AssistantAudioAssistantMessageItemAssistantText
InputAudio
InputImage	InputTextRealtimeItemUserMessageItem)RealtimeModelRealtimeModelConfigRealtimeModelListener)RealtimeModelEvent2RealtimeModelInputAudioTranscriptionCompletedEventRealtimeModelToolCallEvent)RealtimeModelSendAudioRealtimeModelSendInterruptRealtimeModelSendSessionUpdateRealtimeModelSendToolOutputRealtimeModelSendUserInputc                   @  s  e Zd ZdZ		d[d\ddZed]ddZd^ddZd^ddZd_ddZ	d`ddZ
dad d!Zdbd$d%Zd&d'dcd,d-Zdad.d/Zddd0d1Zded4d5Zdfd7d8Zdgd:d;Zedhd?d@ZdidDdEZdjdFdGZdkdJdKZdadLdMZdadNdOZdldSdTZedmdYdZZdS )nRealtimeSessiona?  A connection to a realtime model. It streams events from the model to you, and allows you to
    send messages and audio to the model.

    Example:
        ```python
        runner = RealtimeRunner(agent)
        async with await runner.run() as session:
            # Send messages
            await session.send_message("Hello")
            await session.send_audio(audio_bytes)

            # Stream events
            async for event in session:
                if event.type == "audio":
                    # Handle audio event
                    pass
        ```
    Nmodelr/   agentr   contextTContext | Nonemodel_configRealtimeModelConfig | None
run_configRealtimeRunConfig | NonereturnNonec                 C  s   || _ || _t|| _t| jd| _g | _|pi | _|pi | _| j	d}| j	d}i |p/i |p3i | _
t | _d| _d| _t | _i | _i | _| j	di 	dd| _t | _dS )	a  Initialize the session.

        Args:
            model: The model to use.
            agent: The current agent.
            context: The context object.
            model_config: Model configuration.
            run_config: Runtime configuration including guardrails.
        )r=   initial_model_settingsmodel_settingsFNguardrails_settingsdebounce_text_lengthd   )_model_current_agentr   _context_wrapperr   _event_info_history_model_config_run_configget_base_model_settingsasyncioQueue_event_queue_closed_stored_exceptionset_interrupted_response_ids_item_transcripts_item_guardrail_run_counts_debounce_text_length_guardrail_tasks)selfr;   r<   r=   r?   rA   rE   run_config_settings r`   X/var/www/html/openai_agents/venv/lib/python3.10/site-packages/agents/realtime/session.py__init__S   s0   



zRealtimeSession.__init__c                 C  s   | j S )zMAccess the underlying model for adding listeners or other direct interaction.)rJ   r^   r`   r`   ra   r;      s   zRealtimeSession.modelc                   sn   | j |  | j }| j| jdd| jdI dH |d< | j |I dH  | t	| j
| jdI dH  | S )zStart the session by connecting to the model. After this, you will be able to stream
        events from the model and send messages and audio to the model.
        rE   Nstarting_settingsr<   )historyinfo)rJ   add_listenerrO   copy&_get_updated_model_settings_from_agentrQ   rK   connect
_put_eventr    rN   rM   )r^   r?   r`   r`   ra   
__aenter__   s   

zRealtimeSession.__aenter__c                   s   |   I dH S )zEnter the async context manager. We strongly recommend using the async context manager
        pattern instead of this method. If you use this, you need to manually call `close()` when
        you are done.
        N)rm   rc   r`   r`   ra   enter   s   zRealtimeSession.enter	_exc_typer   _exc_val_exc_tbc                      |   I dH  dS )zEnd the session.N)close)r^   ro   rp   rq   r`   r`   ra   	__aexit__      zRealtimeSession.__aexit__#AsyncIterator[RealtimeSessionEvent]c                 C sf   | j s1z| jdur|  I dH  | j| j I dH }|V  W n tjy+   Y dS w | j rdS dS )z%Iterate over events from the session.N)rV   rW   _cleanuprU   rQ   rS   CancelledErrorr^   eventr`   r`   ra   	__aiter__   s   

zRealtimeSession.__aiter__c                   rr   )zClose the session.N)rw   rc   r`   r`   ra   rs      ru   zRealtimeSession.closemessager   c                   s   | j t|dI dH  dS )zSend a message to the model.
user_inputN)rJ   
send_eventr9   )r^   r|   r`   r`   ra   send_message   s   zRealtimeSession.send_messageF)commitaudiobytesr   boolc                  s    | j t||dI dH  dS )z$Send a raw audio chunk to the model.)r   r   N)rJ   r   r5   )r^   r   r   r`   r`   ra   
send_audio   s   zRealtimeSession.send_audioc                   s   | j t I dH  dS )zInterrupt the model.N)rJ   r   r6   rc   r`   r`   ra   	interrupt   s   zRealtimeSession.interruptc                   s:   || _ | jd| j dI dH }| jt|dI dH  dS )zMUpdate the active agent for this session and apply its settings to the model.Nrd   session_settings)rK   rj   rJ   r   r7   )r^   r<   updated_settingsr`   r`   ra   update_agent   s   zRealtimeSession.update_agentrz   r2   c                   s>  |  t| jdI d H  jdkr#|  t| jjdI d H  d S jdkr2| I d H  d S jdkrJ|  t| jjj	dI d H  d S jdkra|  t
| jjj	dI d H  d S jd	krx|  t| jjj	dI d H  d S jd
krt| j}t| j| _t| j|krt| jdkr| jd }|  t| j|dI d H  d S |  t| j| jdI d H  d S jdkr|  t| jdI d H  d S jdkr3j}|| jvrd| j|< d| j|< | j|  j7  < | | jt|t| j| dgd| _t| j| }| j}| j| d | }||kr1| j|  d7  < | | j| j d S d S jdkrtfdd| jD  }jtfdd| jD d }	|	d ur|	jdkrjdkrzl|	j}
g }tjD ]T\}}|jdv rt |t!tfsJ |j"}|sd }|t|
k r|
| }t |tst |t!r|j"}j#dkr| j$j}|r|j%d|id}|&| qr|r҈j%d|idW n t'y   t(jd d!d" Y nw | | j| _|rtfd#d| jD }|  t| j|dI d H  d S |  t| j| jdI d H  d S jd$kr?j  fd%d&| jD | _|  t| j| jdI d H  d S jd'krGd S jd(kr]|  t)| j*| jd)I d H  d S jd*kr}| j+  | j+  |  t,| j*| jd)I d H  d S jd+krj-| _.d S jd,krd S jd-krd S t/ d S ).N)datarg   errorrg   r   function_callr   )rg   r   item_idcontent_indexaudio_interrupted)rg   r   r   
audio_done#input_audio_transcription_completedr   )rg   item)rg   rf   input_audio_timeout_triggered)rg   transcript_delta )
transcriptr   contentr   item_updatedc                 3  s    | ]
}|j  jj kV  qd S Nr   r   .0r   rz   r`   ra   	<genexpr>  s    z+RealtimeSession.on_event.<locals>.<genexpr>c                 3  s     | ]}|j  j kr|V  qd S r   r   )r   i)incoming_itemr`   ra   r   $  s    r|   )r   input_audio	assistantr   updater   zError merging transcriptsT)exc_infoc                 3  s"    | ]}|j  jj kr|V  qd S r   r   r   r   r`   ra   r   S  s    item_deletedc                   s   g | ]	}|j  kr|qS r`   r   r   )
deleted_idr`   ra   
<listcomp>]  s    z,RealtimeSession.on_event.<locals>.<listcomp>connection_statusturn_started)r<   rg   
turn_ended	exceptionotherraw_server_event)0rl   r"   rM   typer   r   _handle_tool_callr   r   r   r   r   lenrN   r:   _get_new_historyr   r    r!   rZ   r[   deltar(   r'   r\   _enqueue_guardrail_taskresponse_idanyr   nextr   	enumerate
isinstancer*   r   rolerQ   
model_copyappend	Exceptionr   r   rK   clearr   r   rW   r   )r^   rz   prev_lennew_itemr   current_length	thresholdnext_run_thresholdis_newexisting_itemexisting_contentnew_contentidxentryentry_transcript	preservedthis_contentr`   )r   rz   r   ra   on_event   s  
 










	



zRealtimeSession.on_eventr#   c                   s   | j |I dH  dS )zPut an event into the queue.N)rU   putry   r`   r`   ra   rl     s   zRealtimeSession._put_eventr4   c                   s  t | j| j| | j| jI dH \}}dd |D }dd |D }|j|v r}| t| j	||j | jdI dH  ||j }t
| jj| jj|j|j|jd}|||jI dH }| jt|t|ddI dH  | t| j	||| jd	I dH  dS |j|v r||j }	t
| jj| jj|j|j|jd}|	| j|jI dH }t|tstd
|	j dt| | j}
|| _| jd| jdI dH }| t|
| j| j	dI dH  | jt|dI dH  |	|}| jt||ddI dH  dS td|j d)zHandle a tool call event.Nc                 S  s   i | ]}t |tr|j|qS r`   )r   r   name)r   toolr`   r`   ra   
<dictcomp>  s    z5RealtimeSession._handle_tool_call.<locals>.<dictcomp>c                 S  s   i | ]}|j |qS r`   )	tool_name)r   handoffr`   r`   ra   r     s    )rg   r   r<   )r=   usager   tool_call_idtool_argumentsT)	tool_calloutputstart_response)rg   r   r   r<   zHandoff z returned invalid result: rd   )
from_agentto_agentrg   r   zTool z
 not found) rS   gatherrK   get_all_toolsrL   _get_handoffsr   rl   r%   rM   r   r=   r   call_id	argumentson_invoke_toolrJ   r   r8   strr$   on_invoke_handoffr   r   r
   r   r   rj   r   r7   get_transfer_messager	   )r^   rz   toolshandoffsfunction_maphandoff_map	func_tooltool_contextresultr   previous_agentr   transfer_messager`   r`   ra   r     s   






	

	

z!RealtimeSession._handle_tool_callold_historylist[RealtimeItem]ARealtimeModelInputAudioTranscriptionCompletedEvent | RealtimeItemc           (        s  t  trhg }d}|D ]G}|j jkrM|jdkrM|jdkrMg }|jD ]}|jdkr8|jd jid}|| q"|| q"||j|ddd d	}q|| q|du rf|t	 jt
 jd
gd |S t fddt|D d }	|	d ur^| } jdkr\ jd ur\t jdkr\||	 }
|
jdkrX jdkr|
jdkr|
j} j}g }t|D ]H\}}|t|kr|| q|| }|jdkr|jd u r|| q|| qt |tr|jnd }|d ur|jd u r|| q|| q jd|id}|||	< |S  jdkr|
jdkr|
j} j}t|}ddd}t }|D ]}t |tr@||}|r@|| q,g }|D ]}t |tr_||}|r_||vr_|| qF|rh|| }g }t|D ]}\}}|jdkrt|dd }|d u r|t|k r|| }t |tr|jd ur|jd|jid}|| qn|jdkrt|dd }|d u s|dkr|t|k r|| }t |t
r|jr|jd|jid}|| qn|| qn jd|id} | ||	< |S  jdkrR|
jdkrR|
j}! j}"g }#t|"D ]1\}}$|t|!kr$|#|$ q|!| }%|%j}|d ur=|$jd u r=|#|% q|#|$ q jd|#id}&|&||	< |S  ||	< |S  ||	< |S  jrt fddt|D d }'|'d ur| }||'d   |S | g S )NFr|   userr   r   r   	completed)r   statusT)textr   c                 3  s$    | ]\}}|j  j kr|V  qd S r   r   r   r   r   r   r`   ra   r   	     " z3RealtimeSession._get_new_history.<locals>.<genexpr>r   r   r   r   valobjectrC   
str | Nonec                 S  s   t | tr
| jp	d S d S r   )r   r+   	image_url)r   r`   r`   ra   _image_url_str7  s   

z8RealtimeSession._get_new_history.<locals>._image_url_str
input_textr   r   systemc                 3  s$    | ]\}}|j  jkr|V  qd S r   )r   previous_item_idr   r   r`   ra   r     r   r   )r   r   rC   r   )r   r3   r   r   r   r   r   r   r   r.   r,   r   r   ri   r   r)   r   listrX   r+   addgetattrr*   r  insert)(clsr   rz   new_historyexisting_item_foundr   r   r   copied_entryexisting_indexr   assistant_existing_contentassistant_incomingassistant_new_contentr   acassistant_currentcur_textupdated_assistantuser_existing_contentuser_incominguser_new_contentr   incoming_image_urlspartumissing_imagesmergeducr   prevr   updated_usersystem_existing_contentsystem_incomingsystem_new_contentscsystem_currentupdated_systemprevious_indexr`   r   ra   r     s  
 


(


S





z RealtimeSession._get_new_historyr   r   r   c              	     sB  | j j| jdg  }t }g }|D ]}t|}||vr'|| || q|r/|| jv r1dS g }|D ]'}z|	| j
ttt | j |I dH }	|	jjrR||	 W q5 ty\   Y q5w |r|| jv rfdS | j| | t||| jdI dH  | jt I dH  dd |D }
| jtdd|
 d	I dH  d
S dS )zURun output guardrails on the given text. Returns True if any guardrail was triggered.output_guardrailsFN)guardrail_resultsr|   rg   c                 S  s   g | ]}|j  qS r`   )	guardrailget_name)r   r   r`   r`   ra   r     s    z:RealtimeSession._run_output_guardrails.<locals>.<listcomp>zguardrail triggered: z, r}   T)rK   r&  rP   rQ   rX   idr   r  rY   runrL   r   r   r   r   tripwire_triggeredr   rl   r   rM   rJ   r   r6   r9   join)r^   r   r   combined_guardrailsseen_idsr&  r(  guardrail_idtriggered_resultsr   guardrail_namesr`   r`   ra   _run_output_guardrails  s`   





	
z&RealtimeSession._run_output_guardrailsc                 C  s.   t | ||}| j| || j d S r   )rS   create_taskr3  r]   r  add_done_callback_on_guardrail_task_done)r^   r   r   taskr`   r`   ra   r     s   z'RealtimeSession._enqueue_guardrail_taskr7  asyncio.Task[Any]c              
   C  sT   | j | | s&| }|r(t| t| jddt	| id dS dS dS )z&Handle completion of a guardrail task.r|   zGuardrail task failed: r   N)
r]   discard	cancelledr   rS   r4  rl   r   rM   r   )r^   r7  r   r`   r`   ra   r6    s   z'RealtimeSession._on_guardrail_task_donec                 C  s*   | j D ]
}| s|  q| j   d S r   )r]   donecancelr   )r^   r7  r`   r`   ra   _cleanup_guardrail_tasks  s
   
z(RealtimeSession._cleanup_guardrail_tasksc                   s0   |    | j|  | j I dH  d| _dS )z2Clean up all resources and mark session as closed.NT)r=  rJ   remove_listenerrs   rV   rc   r`   r`   ra   rw     s
   
zRealtimeSession._cleanupre   #RealtimeSessionModelSettings | Noner   c                   s   | j  }|jd ur|j|d< t|| j|| j| || jI d H \}}}|p-d|d< |p3g |d< |p9g |d< |rC|	| | j
dd}|rPd |d< |S )	Npromptr   instructionsr   r   tracing_disabledFtracing)rR   ri   r@  rS   r   get_system_promptrL   r   r   r   rP   rQ   )r^   re   r<   r   rA  r   r   disable_tracingr`   r`   ra   rj     s$   





z6RealtimeSession._get_updated_model_settings_from_agentRealtimeAgent[Any]context_wrapperRunContextWrapper[Any]&list[Handoff[Any, RealtimeAgent[Any]]]c                   s   g }j D ]}t|tr|| qt|tr|t| qdfdd tj fdd|D  I d H }d	d
 t||D }|S )Nhandoff_obj Handoff[Any, RealtimeAgent[Any]]rC   r   c                   s8   | j }t|tr|S | }t|r|I d H S |S r   )
is_enabledr   r   inspectisawaitable)rJ  attrres)r<   rG  r`   ra   _check_handoff_enabled*  s   



z=RealtimeSession._get_handoffs.<locals>._check_handoff_enabledc                 3  s    | ]} |V  qd S r   r`   )r   h)rQ  r`   ra   r   3  s    z0RealtimeSession._get_handoffs.<locals>.<genexpr>c                 S  s   g | ]\}}|r|qS r`   r`   )r   rR  okr`   r`   ra   r   4  s    z1RealtimeSession._get_handoffs.<locals>.<listcomp>)rJ  rK  rC   r   )	r   r   r   r   r   r&   rS   r   zip)r  r<   rG  r   handoff_itemresultsenabledr`   )rQ  r<   rG  ra   r     s   


	zRealtimeSession._get_handoffs)NN)r;   r/   r<   r   r=   r>   r?   r@   rA   rB   rC   rD   )rC   r/   )rC   r:   )ro   r   rp   r   rq   r   rC   rD   )rC   rv   )rC   rD   )r|   r   rC   rD   )r   r   r   r   rC   rD   )r<   r   rC   rD   )rz   r2   rC   rD   )rz   r#   rC   rD   )rz   r4   rC   rD   )r   r   rz   r   rC   r   )r   r   r   r   rC   r   )r   r   r   r   rC   rD   )r7  r8  rC   rD   )re   r?  r<   r   rC   r   )r<   rF  rG  rH  rC   rI  )__name__
__module____qualname____doc__rb   propertyr;   rm   rn   rt   r{   rs   r   r   r   r   r   rl   r   classmethodr   r3  r   r6  r=  rw   rj   r   r`   r`   r`   ra   r:   ?   s>    ,








 
+
a 
,
A
	


r:   )I
__future__r   rS   rM  collections.abcr   typingr   r   typing_extensionsr   r<   r   
exceptionsr	   r
   r   r   r   run_contextr   r   r   r   r   r   r   configr   r   r   eventsr   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   itemsr'   r(   r)   r*   r+   r,   r-   r.   r;   r/   r0   r1   model_eventsr2   r3   r4   model_inputsr5   r6   r7   r8   r9   r:   r`   r`   r`   ra   <module>   s,    H(
	