Ë
    ³ŒjæU  ã            
      ó”  — d Z ddlmZ ddlZddlZddlmZ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 erdd
lmZ ddlmZmZ ddlmZ  ej:                  e«      ZdZ  e!h d£«      Z"dd„Z#dd„Z$dd„Z%dd„Z&d d„Z' G d„ d«      Z( G d„ d«      Z) G d„ d«      Z*de ddddedddœ		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d!d„Z+y)"uÜ  LangSmith tracing for the OpenAI Realtime API (raw WebSocket).

OpenAI Realtime has no native telemetry â€” it's a raw WebSocket event stream of
``input_audio_buffer.*`` / ``response.*`` events. :func:`wrap_realtime` wraps the
``AsyncRealtimeConnection`` so the trace is built directly from that stream while
the caller's ``async for event in connection`` loop is left untouched: each
received event is observed, spanned where warranted, and grouped into turns; the
running transcript and a stereo conversation WAV land on the root span.

Tool nesting is preserved without wrapping the caller's loop body: an event's
span is opened when the event is received and kept as the active LangSmith
context until the *next* event arrives â€” so any ``@traceable`` work the caller
does while handling the event (tool execution) nests under it.

Trace shape â€” one conversation = one trace::

    realtime_session                                   (root; transcript + WAV)
    â”œâ”€â”€ session.created / session.updated              (setup)
    â”œâ”€â”€ turn                                           (latency_ms, was_interrupted)
    â”‚   â”œâ”€â”€ conversation.item.input_audio_transcription.completed   (user message)
    â”‚   â””â”€â”€ response.done                              (chain wrapper)
    â”‚       â”œâ”€â”€ model                                  (llm â€” message + tokens)
    â”‚       â””â”€â”€ <your @traceable tools>                (nested under response.done)
    â””â”€â”€ turn â€¦
é    )ÚannotationsN)ÚTYPE_CHECKINGÚAnyÚCallableÚOptional)Úget_package_version)Ú_create_usage_metadata)Úobserve_safely)ÚDEFAULT_MAX_AUDIO_SECONDSÚEventSessionÚstart_session)Útracing_context)ÚSequence)ÚClientÚRunTree)ÚWriteReplicaiÀ]  >
   úresponse.createdúconversation.item.doneúconversation.item.addedúresponse.output_item.doneúresponse.content_part.doneúresponse.output_audio.doneúresponse.output_item.addedúresponse.content_part.addedúinput_audio_buffer.committedú%response.function_call_arguments.donec                ó0   — | j                  d«      xs d| v S )u   Direction of an event relative to the model.

    Inbound = something the user sent toward the model (their speech buffer,
    their transcription) â†’ goes in span ``inputs``. Everything else is the
    model/server talking back â†’ span ``outputs``.
    Úinput_audio_bufferÚinput_audio_transcription)Ú
startswith)Ú
event_types    ú|/var/www/html/Fitness-lenito-AI-main/venv/lib/python3.12/site-packages/langsmith/integrations/openai_realtime/_connection.pyÚ
is_inboundr#   I   s%   € ð 	×ÑÐ2Ó3ò 	5Ø&¨*Ð4ðó    c                óÈ  — g }g }t        | dd«      xs g D ]   }t        |dd«      dk(  rH|j                  t        |dd«      dt        |«      t        |dd«      t        |dd«      xs d	d
œdœ«       Œ[t        |dd«      xs g D ]2  }t        |dd«      xs t        |dd«      }|sŒ"|j                  |«       Œ4 Œ¢ ddj                  |«      j	                  «       dœ}|r||d<   |S )u   Curated assistant message from a ``response.done`` payload.

    The readable, AIMessage-shaped view of what the model returned this
    response: the spoken text plus any tool calls it requested. Tool calls use
    the OpenAI ChatCompletion shape (``type: "function"`` with a nested
    ``function`` holding the name and the raw JSON ``arguments`` string) â€” that's
    the format the LangSmith UI recognizes and renders inline on the model span;
    a flatter ``{name, args, id}`` shape would instead spill into "Additional
    Fields".
    ÚoutputNÚtypeÚfunction_callÚcall_idÚfunctionÚnameÚ	argumentsz{})r+   r,   )Úidr'   Úindexr*   ÚcontentÚ
transcriptÚtextÚ	assistantÚ ©Úroler/   Ú
tool_calls)ÚgetattrÚappendÚlenÚjoinÚstrip)ÚresponseÚtextsr6   ÚitemÚpartr1   Úouts          r"   Úresponse_assistant_outputrA   V   s  € ð €EØ')€JÜ˜ (¨DÓ1Ò7°RÒ7ˆÜ�4˜ Ó&¨/Ò9Ø×Ñä! $¨	°4Ó8Ø&Ü  ›_ä '¨¨f°dÓ ;ô &-¨T°;ÀÓ%EÒ%MÈñ	!ñ	
ôð Ü˜D )¨TÓ2Ò8°bÒ8ˆDÜ˜4 ¨tÓ4ÒS¼ÀÀfÈdÓ8SˆDÚØ—‘˜TÕ"ñ 9ð! 8ð( $/¸3¿8¹8ÀE»?×;PÑ;PÓ;RÑS€CÙØ&ˆˆLÑØ€Jr$   c                ó^  — t        | t        «      rt        | «      }nIt        | dd«      }	 t        |«      rt         |«       «      ni }|sdD ]  }t        | |d«      }|€Œ|||<   Œ dD ]1  \  }}|j                  |«      }t        |t        «      sŒ(||vsŒ-|||<   Œ3 |S # t        $ r i }Y Œcw xY w)uG  Normalize a Realtime ``usage`` object into the dict the shared mapper reads.

    Realtime spells its per-modality breakdowns ``input_token_details`` /
    ``output_token_details`` (singular "token"), whereas
    :func:`_create_usage_metadata` looks for the Chat-Completions
    ``*_tokens_details`` spelling â€” so we alias them here to let it pick up audio
    and cached-token detail (which dominate voice cost). Falls back to the
    top-level token counts if the object can't be dumped, omitting the detail
    blocks rather than risk passing non-dict values to the mapper.
    Ú
model_dumpN©Úinput_tokensÚoutput_tokensÚtotal_tokens))Úinput_token_detailsÚinput_tokens_details)Úoutput_token_detailsÚoutput_tokens_details)Ú
isinstanceÚdictr7   ÚcallableÚ	ExceptionÚget)ÚusageÚbaserC   ÚkeyÚvalÚrealtime_keyÚ
mapper_keyÚblocks           r"   Ú_usage_to_dictrX   }   sÄ   € ô �%œÔÜ�E‹{‰ä˜U L°$Ó7ˆ
ð	Ü)1°*Ô)=”4™
›Ô%À2ˆDñ ÛH�Ü˜e S¨$Ó/�Ø‘?Ø #�D˜’Ið Ió%Ñ ˆ�jð —‘˜Ó&ˆÜ�eœTÕ" z¸Ò'=Ø$ˆD�Òð%ð €Køô ò 	ØŠDð	ús   «B ÂB,Â+B,c                ór   ‡— | €yt        | «      Št        ˆfd„dD «       «      syt        t        ‰«      «      S )a€  Map a Realtime ``usage`` (object or dict) onto LangSmith ``usage_metadata``.

    Delegates to the shared OpenAI usage mapper so the Realtime integration and
    the Chat/Agents wrappers agree on the canonical shape (and so audio/cached
    token detail is captured, not dropped). Returns ``None`` when there is no
    usage or it carries no token counts (e.g. a cancelled turn).
    Nc              3  óD   •K  — | ]  }‰j                  |«      d u–— Œ y ­w©N)rP   )Ú.0rS   Ú
usage_dicts     €r"   Ú	<genexpr>z,usage_metadata_from_usage.<locals>.<genexpr>ª   s'   øè ø€ ð áDˆCð 	�‰�sÓ 4Ô'ÙDùs   ƒ rD   )rX   ÚanyrM   r	   )rQ   r]   s    @r"   Úusage_metadata_from_usager`   Ÿ   sB   ø€ ð €}ØÜ Ó&€JÜó áDóô ð ÜÔ& zÓ2Ó3Ð3r$   c                ó.   — t        t        | dd«      «      S )zJMap a ``response.done`` payload's token ``usage`` onto ``usage_metadata``.rQ   N)r`   r7   )r<   s    r"   Úresponse_usage_metadatarb   ²   s   € ä$¤W¨X°wÀÓ%EÓFÐFr$   c                  ó`   — e Zd ZdZddœ	 	 	 	 	 dd„Zdd„Zdd„Zdd„Zdd„Zdd	„Z	dd
„Z
dd„Zy)Ú_RealtimeTraceru&  Turns the Realtime event stream into a LangSmith trace, one event at a time.

    Decides â€” privately â€” whether to open a span, open/close a turn, append to
    the transcript rollup, set the trace title, time first-audio latency, flag a
    barge-in, and record the ``llm`` span. All trace writes go through the
    injected :class:`EventSession`.

    An event's span is held open (as the active LangSmith parent context) from
    the moment the event is received until the next event arrives, so the
    caller's tool calls nest under it.
    N©Úis_agent_speakingc               óJ   — || _         || _        d | _        d | _        d | _        y r[   )Ú_sessionÚ_is_agent_speakingÚ_await_audio_sinceÚ_openÚ_model)ÚselfÚsessionrf   s      r"   Ú__init__z_RealtimeTracer.__init__Ä   s/   € ð  ˆŒð #4ˆÔð 15ˆÔð .2ˆŒ
Ø"&ˆ�r$   c                ó  — | j                  «        | j                  j                  «       }t        |dd«      }|€y|dv r*t        t        |dd«      dd«      }|rt	        |«      | _        |dk(  r| j                  |«       y|j                  d«      s|t        v ry|dk(  r,| j                  j                  d	t        |d
d«      xs d«       y| j                  ||«        | j                  j                  ||fd|i| j                  |«      ¤Ž}|j                  «       }|dk(  rdt        |dd«      › �|_        n&|dk(  r!t        |dd«      }|�| j                  ||«       t!        |¬«      }|j                  «        ||f| _        y)a"  Observe one received event; span it where warranted.

        Closes the previous event's span first (the caller has finished handling
        it), then applies turn/transcript/latency side-state and, for meaningful
        events, opens a new span kept active until the next call.
        r'   N)zsession.createdzsession.updatedrn   Úmodelzresponse.output_audio.deltaz.deltaz%response.output_audio_transcript.doner2   r0   Ú r+   ú2conversation.item.input_audio_transcription.failedztranscription_failed: Úerrorúresponse.doner<   )Úparent)Ú_close_openrh   Únowr7   Ústrrl   Ú_record_first_audioÚendswithÚNOISE_EVENTSÚadd_messageÚ_before_spanÚ
event_spanÚ_span_kwargsÚ	__enter__rt   Ú_record_response_llmr   rk   )	rm   ÚeventÚreceived_atÚetyperq   Úcm_spanÚrunr<   Úcm_ctxs	            r"   Úobservez_RealtimeTracer.observe×   s’  € ð 	×ÑÔØ—m‘m×'Ñ'Ó)ˆÜ˜˜v tÓ,ˆØˆ=Øð Ð:Ñ:ÜœG E¨9°dÓ;¸WÀdÓKˆEÙÜ! %›j�”ð Ð1Ò1Ø×$Ñ$ [Ô1ØØ�>‰>˜(Ô# u´Ñ'<ØØÐ;Ò;à�M‰M×%Ñ%ØœW U¨L¸"Ó=ÒCÀôð à×Ñ˜% Ô-à*�$—-‘-×*Ñ*Ø�;ñ
Ø%*ð
Ø.2×.?Ñ.?ÀÓ.Fñ
ˆð ×ÑÓ!ˆØÐHÒHØ0´¸ÀÈÓ1NÐ0OÐPˆC�IØ�oÒ%Ü˜u j°$Ó7ˆHØÐ#Ø×)Ñ)¨#¨xÔ8Ü ¨Ô,ˆØ×ÑÔØ˜vÐ&ˆ�
r$   c                ó$   — | j                  «        y)z5Close any still-open event span (called at teardown).N)rw   ©rm   s    r"   Úfinalize_openz_RealtimeTracer.finalize_open  s   € à×ÑÕr$   c                ó–   — | j                   €y | j                   \  }}d | _         |j                  d d d «       |j                  d d d «       y r[   )rk   Ú__exit__)rm   r†   rˆ   s      r"   rw   z_RealtimeTracer._close_open  sE   € Ø�:‰:ÐØØŸ*™*‰ˆ�ØˆŒ
Ø�‰˜˜d DÔ)Ø×Ñ˜˜t TÕ*r$   c                óÚ  — |j                   }|dk(  rZ| j                  �,| j                  «       r| j                  j                  d¬«       | j                  j	                  «        d| _        y|dk(  r|| _        y|dk(  rat        |dd«      xs dj                  «       }|r8| j                  j                  d	|«       | j                  j                  |«       yd| _        y|d
k(  rd| _        yy)zDTurn/transcript/title side-state applied as a span is about to open.z!input_audio_buffer.speech_startedNT)Úwas_interruptedz!input_audio_buffer.speech_stoppedú5conversation.item.input_audio_transcription.completedr0   rr   Úuserrs   )
r'   ri   rh   Úadd_turn_metadataÚ
start_turnrj   r7   r;   r}   Ú	set_title)rm   rƒ   r„   r…   r1   s        r"   r~   z_RealtimeTracer._before_span  sØ   € à—
‘
ˆØÐ7Ò7ð ×&Ñ&Ð2°t×7NÑ7NÔ7PØ—‘×/Ñ/ÀÐ/ÔEØ�M‰M×$Ñ$Ô&Ø&*ˆDÕ#ØÐ9Ò9Ø&1ˆDÕ#ØÐMÒMÜ˜E <°Ó4Ò:¸×AÑAÓCˆDÙØ—‘×)Ñ)¨&°$Ô7Ø—‘×'Ñ'¨Õ-à*.�Õ'ØÐJÒJØ&*ˆDÕ#ð Kr$   c                ó¬   — |j                   }dt        |«      i}|dk(  r+t        |dd«      xs dj                  «       }|rd|dœ|d<   |S |dk(  ri |d	<   |S )
z9Curated, conversation-shaped I/O for the readable events.Úinboundr‘   r0   rr   r’   r4   Úinputsru   Úoutputs)r'   r#   r7   r;   )rm   rƒ   r…   Úkwargsr1   s        r"   r€   z_RealtimeTracer._span_kwargs+  ss   € à—
‘
ˆØ"+¬Z¸Ó->Ð!?ˆØÐKÒKÜ˜E <°Ó4Ò:¸×AÑAÓCˆDÙØ,2¸tÑ#D��xÑ ð
 ˆð	 �oÒ%ð !#ˆF�9ÑØˆr$   c                ó–   — | j                   �=| j                  j                  t        || j                   z
  dz  «      ¬«       d | _         y y )Niè  )Úlatency_to_first_audio_ms)rj   rh   r“   Úround)rm   r„   s     r"   rz   z#_RealtimeTracer._record_first_audio9  sO   € Ø×"Ñ"Ð.Ø�M‰M×+Ñ+Ü*/Ø  4×#:Ñ#:Ñ:¸dÑBó+ð ,ô ð
 '+ˆDÕ#ð /r$   c                óœ   — t        |dd «      d| j                  dœ}| j                  j                  |t	        |«      t        |«      |¬«       y )NÚstatusÚopenai)rŸ   Úls_providerÚls_model_name)r™   Úusage_metadataÚmetadata)r7   rl   rh   Ú
record_llmrA   rb   )rm   r‡   r<   r¤   s       r"   r‚   z$_RealtimeTracer._record_response_llmB  sN   € ä˜h¨°$Ó7Ø#Ø!Ÿ[™[ñ$
ˆð
 	�‰× Ñ ØÜ-¨hÓ7Ü2°8Ó<Øð	 	!õ 	
r$   )rn   r   rf   úOptional[Callable[[], bool]]ÚreturnÚNone)rƒ   r   r§   r¨   )r§   r¨   )rƒ   r   r„   Úfloatr§   r¨   )rƒ   r   r§   údict[str, Any])r„   r©   r§   r¨   )r‡   r   r<   r   r§   r¨   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__ro   r‰   rŒ   rw   r~   r€   rz   r‚   © r$   r"   rd   rd   ·   sQ   „ ñ
ð  ;?ñ	'àð'ð 8ð	'ð
 
ó'ó&/'óbó+ó+ó.ó+ô
r$   rd   c                  óX   — e Zd ZdZ	 	 	 	 	 	 	 	 d
d„Zdd„Zdd„Zdd„Zdd„Zdd„Z	dd„Z
y	)Ú_TracedRealtimeConnectionaî  Transparent proxy over an ``AsyncRealtimeConnection`` that traces events.

    Delegates every attribute to the wrapped connection, so the caller uses it
    exactly like the original (``connection.session.update(...)``,
    ``connection.response.create()``, ``async for event in connection``). Each
    received event is passed to the tracer. Also exposes
    :meth:`record_user_audio` / :meth:`record_agent_audio` so the app can
    (optionally) feed PCM for the stereo conversation WAV.
    c                ó<   — || _         || _        || _        d | _        y r[   )Ú_connectionÚ_tracerrh   Ú_aiter)rm   Ú
connectionÚtracerrn   s       r"   ro   z"_TracedRealtimeConnection.__init__[  s!   € ð
 &ˆÔØˆŒØˆŒØˆ�r$   c                óB   — t        t        j                  | d«      |«      S )Nr³   )r7   ÚobjectÚ__getattribute__)rm   r+   s     r"   Ú__getattr__z%_TracedRealtimeConnection.__getattr__e  s   € Ü”v×.Ñ.¨t°]ÓCÀTÓJÐJr$   c                óD   — | j                   j                  «       | _        | S r[   )r³   Ú	__aiter__rµ   r‹   s    r"   r½   z#_TracedRealtimeConnection.__aiter__h  s   € Ø×&Ñ&×0Ñ0Ó2ˆŒØˆr$   c              ƒ  óà   K  — | j                   }|€!| j                  j                  «       }|| _         |j                  «       ƒ d {  –—† }t	        | j
                  j                  |«       |S 7 Œ&­wr[   )rµ   r³   r½   Ú	__anext__r
   r´   r‰   )rm   Úaiterrƒ   s      r"   r¿   z#_TracedRealtimeConnection.__anext__l  s\   è ø€ Ø—‘ˆØˆ=Ø×$Ñ$×.Ñ.Ó0ˆEØˆDŒKØ—o‘oÓ'×'ˆÜ�t—|‘|×+Ñ+¨UÔ3Øˆð (ús   ‚AA.ÁA,Á'A.c              ƒ  ó–   K  — | j                   j                  «       ƒ d {  –—† }t        | j                  j                  |«       |S 7 Œ&­wr[   )r³   Úrecvr
   r´   r‰   )rm   rƒ   s     r"   rÂ   z_TracedRealtimeConnection.recvu  s;   è ø€ Ø×&Ñ&×+Ñ+Ó-×-ˆÜ�t—|‘|×+Ñ+¨UÔ3Øˆð .ús   ‚A	 A¡'A	c                ól   — | j                   j                  | j                   j                  «       |«       y)zCRecord a chunk of user (mic) PCM16 for the stereo conversation WAV.N)rh   Úrecord_userrx   ©rm   Úpcms     r"   Úrecord_user_audioz+_TracedRealtimeConnection.record_user_audioz  s#   € à�‰×!Ñ! $§-¡-×"3Ñ"3Ó"5°sÕ;r$   c                ól   — | j                   j                  | j                   j                  «       |«       y)zGRecord a chunk of agent (played) PCM16 for the stereo conversation WAV.N)rh   Úrecord_agentrx   rÅ   s     r"   Úrecord_agent_audioz,_TracedRealtimeConnection.record_agent_audio~  s#   € à�‰×"Ñ" 4§=¡=×#4Ñ#4Ó#6¸Õ<r$   N)r¶   r   r·   rd   rn   r   r§   r¨   )r+   ry   r§   r   ©r§   r±   )r§   r   )rÆ   Úbytesr§   r¨   )r«   r¬   r­   r®   ro   r»   r½   r¿   rÂ   rÇ   rÊ   r¯   r$   r"   r±   r±   P  sK   „ ñðØðØ'6ðØAMðà	óóKóóóó
<ô=r$   r±   c                  óT   — e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd„Zdd„Zdd„Zy)	Ú_RealtimeTracingSessionac  Async context manager returned by :func:`wrap_realtime`.

    On enter: starts the conversation root span and session-level LangSmith
    context, returning a traced connection proxy. On exit: closes any open span,
    records an error on the root if the body raised, and finalizes the root
    (rolling up the transcript + attaching the stereo WAV).
    c       	        óø   — || _         |xs t        t        j                  «       «      | _        || _        || _        || _        || _        || _	        || _
        |	| _        |
| _        d | _        d | _        d | _        y r[   )r³   ry   ÚuuidÚuuid4Ú
_thread_idÚ_sample_rateÚ_project_nameÚ_tagsÚ	_metadatari   Ú_max_audio_secondsÚ_clientÚ	_replicasrh   r´   Ú_ctx)rm   r¶   Ú	thread_idÚsample_rateÚproject_nameÚtagsr¤   rf   Úmax_audio_secondsÚclientÚreplicass              r"   ro   z _RealtimeTracingSession.__init__Œ  st   € ð &ˆÔØ#Ò8¤s¬4¯:©:«<Ó'8ˆŒØ'ˆÔØ)ˆÔØˆŒ
Ø!ˆŒØ"3ˆÔØ"3ˆÔØˆŒØ!ˆŒØ-1ˆŒØ/3ˆŒØˆ�	r$   c              ƒ  óB  K  — t        | j                  | j                  | j                  | j                  | j
                  | j                  | j                  | j                  dt        d«      ¬«
      | _
        t        d| j                  i| j                  | j                  | j                  ¬«      | _        | j                  j                  «        t        | j                  | j                  ¬«      | _        t#        | j$                  | j                   | j                  «      S ­w)Nzopenai-realtimer    )
rÛ   rÜ   rÝ   rÞ   r¤   rß   rà   rá   ÚintegrationÚintegration_versionrÛ   )r¤   rÞ   rÝ   rá   re   )r   rÒ   rÓ   rÔ   rÕ   rÖ   r×   rØ   rÙ   r   rh   r   rÚ   r�   rd   ri   r´   r±   r³   r‹   s    r"   Ú
__aenter__z"_RealtimeTracingSession.__aenter__¨  sØ   è ø€ Ü%Ø—o‘oØ×)Ñ)Ø×+Ñ+Ø—‘Ø—^‘^Ø"×5Ñ5Ø—<‘<Ø—^‘^Ø)Ü 3°HÓ =ô
ˆŒô $Ø! 4§?¡?Ð3Ø—‘Ø×+Ñ+Ø—^‘^ô	
ˆŒ	ð 	�	‰	×ÑÔÜ&Ø�M‰M¨T×-DÑ-Dô
ˆŒô )¨×)9Ñ)9¸4¿<¹<ÈÏÉÓWÐWùs   ‚DDc              ƒ  óú  K  — 	 | j                   �| j                   j                  «        | j                  �F|�*|j                  › d|› �| j                  j                  _        | j                  j                  «        | j                  �| j                  j                  d d d «       y# t        $ r t        j                  dd¬«       Y ŒLw xY w# | j                  �| j                  j                  d d d «       w w xY w­w)Nz: z)voice tracing: failed to finalize sessionT)Úexc_infoF)r´   rŒ   rh   r«   r‡   rt   ÚfinalizerO   ÚloggerÚwarningrÚ   rŽ   )rm   Úexc_typeÚexcÚtbs       r"   Ú	__aexit__z!_RealtimeTracingSession.__aexit__Á  sÙ   è ø€ ð	5Ø�|‰|Ð'Ø—‘×*Ñ*Ô,Ø�}‰}Ð(Ø�?Ø19×1BÑ1BÐ0CÀ2ÀcÀUÐ.K�D—M‘M×%Ñ%Ô+Ø—‘×&Ñ&Ô(ð �y‰yÐ$Ø—	‘	×"Ñ" 4¨¨tÔ4Øøô ò 	WÜ�N‰NÐFÐQUˆNÖVð	Wûð �y‰yÐ$Ø—	‘	×"Ñ" 4¨¨tÕ4ð %üs5   ‚C;„A8B& Á<*C;Â& C	ÃC ÃC	Ã	C Ã,C8Ã8C;N)r¶   r   rÛ   úOptional[str]rÜ   ÚintrÝ   rï   rÞ   úOptional[list[str]]r¤   úOptional[dict[str, Any]]rf   r¦   rß   úOptional[float]rà   úOptional[Client]rá   ú Optional[Sequence[WriteReplica]]r§   r¨   rË   )rë   r   rì   r   rí   r   r§   Úbool)r«   r¬   r­   r®   ro   rå   rî   r¯   r$   r"   rÎ   rÎ   ƒ  sƒ   „ ñðàðð !ð	ð
 ðð $ðð "ðð +ðð 8ðð +ðð !ðð 3ðð 
óó8Xô2r$   rÎ   ©	rÛ   rÜ   rÝ   rÞ   r¤   rf   rß   rà   rá   c       	        ó,   — t        | |||||||||	¬«
      S )a5  Trace an OpenAI Realtime connection into LangSmith.

    Returns an async context manager that yields a transparent proxy of
    ``connection``; iterate and call it exactly as you would the original::

        async with client.realtime.connect(model=...) as raw, \\
                   wrap_realtime(raw, thread_id=tid) as connection:
            async for event in connection:
                ...

    To capture the stereo conversation WAV, feed PCM via the proxy's
    ``record_user_audio`` / ``record_agent_audio`` and (optionally) supply
    ``is_agent_speaking`` so barge-ins are flagged.

    Args:
        connection: the ``AsyncRealtimeConnection`` from ``client.realtime.connect``.
        thread_id: LangSmith thread id; a random UUID if omitted.
        sample_rate: PCM sample rate of the audio (for the WAV).
        project_name: LangSmith project; defaults to standard ``LANGSMITH_*`` config.
        tags / metadata: attached to the conversation root span.
        is_agent_speaking: zero-arg callable returning whether the agent is still
            audible, used to flag a barge-in; ``None`` disables that flag.
        max_audio_seconds: per-channel cap on audio retained for the WAV, to
            bound memory on long sessions; pass ``None`` to keep all audio.
        client: LangSmith ``Client`` for tracing writes; ``None`` (default) uses
            the SDK's standard env-based resolution (``LANGSMITH_*``).
        replicas: tracing replicas to mirror the conversation trace to additional
            destinations; ``None`` (default) disables replication.
    r÷   )rÎ   )
r¶   rÛ   rÜ   rÝ   rÞ   r¤   rf   rß   rà   rá   s
             r"   Úwrap_realtimerù   Ô  s0   € ôT #ØØØØ!ØØØ+Ø+ØØôð r$   )r!   ry   r§   rö   )r<   r   r§   rª   )rQ   r   r§   rª   )rQ   r   r§   údict[str, Any] | None)r<   r   r§   rú   )r¶   r   rÛ   rï   rÜ   rð   rÝ   rï   rÞ   rñ   r¤   rò   rf   r¦   rß   ró   rà   rô   rá   rõ   r§   rÎ   ),r®   Ú
__future__r   ÚloggingrÐ   Útypingr   r   r   r   Ú$langsmith._internal._package_versionr   Úlangsmith._internal._usager	   Ú!langsmith._internal.voice.helpersr
   Ú!langsmith._internal.voice.sessionr   r   r   Úlangsmith.run_helpersr   Úcollections.abcr   Ú	langsmithr   r   Úlangsmith.run_treesr   Ú	getLoggerr«   ré   ÚDEFAULT_SAMPLE_RATEÚ	frozensetr|   r#   rA   rX   r`   rb   rd   r±   rÎ   rù   r¯   r$   r"   Ú<module>r	     s9  ðñõ4 #ã Û ß 9Ó 9å DÝ =Ý <÷ñ õ
 2áÝ(ç)Ý0à	ˆ×	Ñ	˜8Ó	$€ð Ð ñ òó€ó"
ó$óNóD4ó&G÷
V
ñ V
÷r0=ñ 0=÷fNñ Nðh  $Ø*Ø"&Ø $Ø)-Ø6:Ø)BØ#Ø15ñ5Øð5ð ð5ð ð	5ð
  ð5ð ð5ð 'ð5ð 4ð5ð 'ð5ð ð5ð /ð5ð ô5r$   