ó
    üÞ jæU  ã            
      ó¬  • S r SSKJr  SSKrSSKrSSKJrJrJrJ	r	  SSK
Jr  SSKJr  SSKJr  SSKJrJrJr  SS	KJr  \(       a  SS
KJr  SSKJrJr  SSKJr  \R:                  " \5      rSr \!" 1 Sk5      r"SS jr#SS jr$SS jr%SS jr&S S jr' " S S5      r( " S S5      r) " S S5      r*S\ SSSS\SSS.	                     S!S jjr+g)"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                ó<   • U R                  S5      =(       d    SU ;   $ )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    Úl/var/www/html/gaurav/venv/lib/python3.13/site-packages/langsmith/integrations/openai_realtime/_connection.pyÚ
is_inboundr#   I   s%   € ð 	×ÑÐ2Ó3÷ 	5Ø&¨*Ñ4ðó    c                ó  • / n/ n[        U SS5      =(       d    /  Hº  n[        USS5      S:X  aN  UR                  [        USS5      S[        U5      [        USS5      [        USS5      =(       d    S	S
.S.5        Mb  [        USS5      =(       d    /  H>  n[        USS5      =(       d    [        USS5      nU(       d  M-  UR                  U5        M@     M¼     SSR                  U5      R	                  5       S.nU(       a  X&S'   U$ )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Ø—‘˜TÖ"ó 9ñ! 8ð( $/¸3¿8¹8ÀE»?×;PÑ;PÓ;RÑS€CÞØ&ˆLÑØ€Jr$   c                ó’  • [        U [        5      (       a  [        U 5      nOU[        U SS5      n [        U5      (       a  [        U" 5       5      O0 nU(       d  S H  n[        XS5      nUc  M  XAU'   M     S H8  u  pVUR                  U5      n[        U[        5      (       d  M-  Xa;  d  M4  XqU'   M:     U$ ! [         a    0 n Nsf = f)u'  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¨$Ó/�Ø“?Ø #˜“Iñ Ió%Ñ ˆð —‘˜Ó&ˆÜ�eœT×"Ó" zÕ'=Ø$�Óñ%ð €Køô ó 	ØŠDð	ús   °"B7 Â7CÃCc                ó€   ^• U c  g[        U 5      m[        U4S jS 5       5      (       d  g[        [        T5      5      $ )al  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  óH   >#   • U H  nTR                  U5      S Lv •  M     g 7f©N)rP   )Ú.0rS   Ú
usage_dicts     €r"   Ú	<genexpr>Ú,usage_metadata_from_usage.<locals>.<genexpr>ª   s&   øé € ð áDˆCð 	�‰�sÓ 4Õ'ÚDùs   ƒ"rD   )rX   ÚanyrM   r	   )rQ   r]   s    @r"   Úusage_metadata_from_usagera   Ÿ   sG   ø€ ð �}ØÜ Ó&€JÜô áDó÷ ñ ð ÜÔ& zÓ2Ó3Ð3r$   c                ó.   • [        [        U SS5      5      $ )zJMap a ``response.done`` payload's token ``usage`` onto ``usage_metadata``.rQ   N)ra   r7   )r<   s    r"   Úresponse_usage_metadatarc   ²   s   € ä$¤W¨X°wÀÓ%EÓFÐFr$   c                  óz   • \ rS rSrSrSS.     SS jjrSS jrSS jrSS jrSS	 jr	SS
 jr
SS jrSS jrSrg)Ú_RealtimeTraceré·   u  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               óF   • Xl         X l        S U l        S U l        S U l        g r[   )Ú_sessionÚ_is_agent_speakingÚ_await_audio_sinceÚ_openÚ_model)ÚselfÚsessionrh   s      r"   Ú__init__Ú_RealtimeTracer.__init__Ä   s+   € ð  Œð #4Ôð 15ˆÔð .2ˆŒ
Ø"&ˆ�r$   c                ó*  • U R                  5         U R                  R                  5       n[        USS5      nUc  gUS;   a/  [        [        USS5      SS5      nU(       a  [	        U5      U l        US:X  a  U R                  U5        gUR                  S5      (       d
  U[        ;   a  gUS:X  a1  U R                  R                  S	[        US
S5      =(       d    S5        gU R                  X5        U R                  R                  " X4SU0U R                  U5      D6nUR                  5       nUS:X  a  S[        USS5       3Ul        O'US:X  a!  [        USS5      nUb  U R                  Xg5        [!        US9nUR                  5         XX4U l        g)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.updatedrp   Ú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_openrj   Únowr7   Ústrrn   Ú_record_first_audioÚendswithÚNOISE_EVENTSÚadd_messageÚ_before_spanÚ
event_spanÚ_span_kwargsÚ	__enter__rw   Ú_record_response_llmr   rm   )	ro   ÚeventÚreceived_atÚetypert   Úcm_spanÚrunr<   Úcm_ctxs	            r"   ÚobserveÚ_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ØÑ#Ø×)Ñ)¨#Ô8Ü ¨Ñ,ˆØ×ÑÔØÐ&ˆ�
r$   c                ó$   • U R                  5         g)z5Close any still-open event span (called at teardown).N)rz   ©ro   s    r"   Úfinalize_openÚ_RealtimeTracer.finalize_open  s   € à×ÑÕr$   c                ó–   • U R                   c  g U R                   u  pS U l         UR                  S S S 5        UR                  S S S 5        g r[   )rm   Ú__exit__)ro   r‰   r‹   s      r"   rz   Ú_RealtimeTracer._close_open  sC   € Ø�:‰:ÑØØŸ*™*‰ˆØˆŒ
Ø�‰˜˜d DÔ)Ø×Ñ˜˜t TÕ*r$   c                óú  • UR                   nUS:X  a]  U R                  b.  U R                  5       (       a  U R                  R                  SS9  U R                  R	                  5         SU l        gUS:X  a  X l        gUS:X  ak  [        USS5      =(       d    SR                  5       nU(       a8  U R                  R                  S	U5        U R                  R                  U5        gSU l        gUS
:X  a  SU l        gg)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   ru   Úuserrv   )
r'   rk   rj   Úadd_turn_metadataÚ
start_turnrl   r7   r;   r€   Ú	set_title)ro   r†   r‡   rˆ   r1   s        r"   r�   Ú_RealtimeTracer._before_span  sÙ   € à—
‘
ˆØÐ7Ó7ð ×&Ñ&Ñ2°t×7NÑ7N×7PÑ7PØ—‘×/Ñ/ÀÐ/ÑEØ�M‰M×$Ñ$Ô&Ø&*ˆDÕ#ØÐ9Ó9Ø&1Õ#ØÐMÓMÜ˜E <°Ó4×:¸×AÑAÓCˆDÞØ—‘×)Ñ)¨&°$Ô7Ø—‘×'Ñ'¨Õ-à*.�Õ'ØÐJÓJØ&*ˆDÕ#ð Kr$   c                óÄ   • UR                   nS[        U5      0nUS:X  a5  [        USS5      =(       d    SR                  5       nU(       a  SUS.US'   U$ US:X  a  0 US	'   U$ )
z9Curated, conversation-shaped I/O for the readable events.Úinboundr—   r0   ru   r˜   r4   Úinputsrx   Úoutputs)r'   r#   r7   r;   )ro   r†   rˆ   Úkwargsr1   s        r"   rƒ   Ú_RealtimeTracer._span_kwargs+  ss   € à—
‘
ˆØ"+¬Z¸Ó->Ð!?ˆØÐKÓKÜ˜E <°Ó4×:¸×AÑAÓCˆDÞØ,2¸tÑ#D��xÑ ð
 ˆð	 �oÓ%ð !#ˆF�9ÑØˆr$   c                ó�   • U R                   b9  U R                  R                  [        XR                   -
  S-  5      S9  S U l         g g )Niè  )Úlatency_to_first_audio_ms)rl   rj   r™   Úround)ro   r‡   s     r"   r}   Ú#_RealtimeTracer._record_first_audio9  sM   € Ø×"Ñ"Ñ.Ø�M‰M×+Ñ+Ü*/Ø ×#:Ñ#:Ñ:¸dÑBó+ð ,ñ ð
 '+ˆDÕ#ð /r$   c                ó–   • [        USS 5      SU R                  S.nU R                  R                  U[	        U5      [        U5      US9  g )NÚstatusÚopenai)r¨   Úls_providerÚls_model_name)r    Úusage_metadataÚmetadata)r7   rn   rj   Ú
record_llmrA   rc   )ro   rŠ   r<   r­   s       r"   r…   Ú$_RealtimeTracer._record_response_llmB  sN   € ä˜h¨°$Ó7Ø#Ø!Ÿ[™[ñ$
ˆð
 	�‰× Ñ ØÜ-¨hÓ7Ü2°8Ó<Øð	 	!ò 	
r$   )rl   rk   rn   rm   rj   )rp   r   rh   ú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__Ú__firstlineno__Ú__doc__rq   rŒ   r�   rz   r�   rƒ   r}   r…   Ú__static_attributes__© r$   r"   re   re   ·   sQ   † ñ
ð  ;?ñ	'àð'ð 8ð	'ð
 
õ'ô&/'ôbô+ô+ô.ô+÷
r$   re   c                  ón   • \ rS rSrSr        SS jrSS jrSS jrSS jrSS jr	SS jr
SS	 jrS
rg)Ú_TracedRealtimeConnectioniP  aÒ  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                ó6   • Xl         X l        X0l        S U l        g r[   )Ú_connectionÚ_tracerrj   Ú_aiter)ro   Ú
connectionÚtracerrp   s       r"   rq   Ú"_TracedRealtimeConnection.__init__[  s   € ð
 &ÔØŒØŒØˆ�r$   c                óB   • [        [        R                  U S5      U5      $ )Nr¿   )r7   ÚobjectÚ__getattribute__)ro   r+   s     r"   Ú__getattr__Ú%_TracedRealtimeConnection.__getattr__e  s   € Ü”v×.Ñ.¨t°]ÓCÀTÓJÐJr$   c                óD   • U R                   R                  5       U l        U $ r[   )r¿   Ú	__aiter__rÁ   r�   s    r"   rË   Ú#_TracedRealtimeConnection.__aiter__h  s   € Ø×&Ñ&×0Ñ0Ó2ˆŒØˆr$   c              ƒ  óà   #   • U R                   nUc   U R                  R                  5       nXl         UR                  5       I S h  v•N n[	        U R
                  R                  U5        U$  N&7fr[   )rÁ   r¿   rË   Ú	__anext__r
   rÀ   rŒ   )ro   Úaiterr†   s      r"   rÎ   Ú#_TracedRealtimeConnection.__anext__l  sY   é € Ø—‘ˆØ‰=Ø×$Ñ$×.Ñ.Ó0ˆEØŒKØ—o‘oÓ'×'ˆÜ�t—|‘|×+Ñ+¨UÔ3Øˆñ (ùs   ‚AA.ÁA,Á'A.c              ƒ  ó–   #   • U R                   R                  5       I S h  v•N n[        U R                  R                  U5        U$  N&7fr[   )r¿   Úrecvr
   rÀ   rŒ   )ro   r†   s     r"   rÒ   Ú_TracedRealtimeConnection.recvu  s:   é € Ø×&Ñ&×+Ñ+Ó-×-ˆÜ�t—|‘|×+Ñ+¨UÔ3Øˆñ .ùs   ‚A	 A¡'A	c                ól   • U R                   R                  U R                   R                  5       U5        g)zCRecord a chunk of user (mic) PCM16 for the stereo conversation WAV.N)rj   Úrecord_userr{   ©ro   Úpcms     r"   Úrecord_user_audioÚ+_TracedRealtimeConnection.record_user_audioz  s#   € à�‰×!Ñ! $§-¡-×"3Ñ"3Ó"5°sÕ;r$   c                ól   • U R                   R                  U R                   R                  5       U5        g)zGRecord a chunk of agent (played) PCM16 for the stereo conversation WAV.N)rj   Úrecord_agentr{   rÖ   s     r"   Úrecord_agent_audioÚ,_TracedRealtimeConnection.record_agent_audio~  s#   € à�‰×"Ñ" 4§=¡=×#4Ñ#4Ó#6¸Õ<r$   )rÁ   r¿   rj   rÀ   N)rÂ   r   rÃ   re   rp   r   r±   r²   )r+   r|   r±   r   ©r±   r½   )r±   r   )r×   Úbytesr±   r²   )rµ   r¶   r·   r¸   r¹   rq   rÈ   rË   rÎ   rÒ   rØ   rÜ   rº   r»   r$   r"   r½   r½   P  sK   † ñðØðØ'6ðØAMðà	ôôKôôôô
<÷=r$   r½   c                  ób   • \ rS rSrSr                      SS jrS	S jrS
S jrSrg)Ú_RealtimeTracingSessioniƒ  aO  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l         U=(       d    [        [        R                  " 5       5      U l        X0l        X@l        XPl        X`l        Xpl	        X€l
        X�l        X l        S U l        S U l        S U l        g r[   )r¿   r|   ÚuuidÚuuid4Ú
_thread_idÚ_sample_rateÚ_project_nameÚ_tagsÚ	_metadatark   Ú_max_audio_secondsÚ_clientÚ	_replicasrj   rÀ   Ú_ctx)ro   rÂ   Ú	thread_idÚsample_rateÚproject_nameÚtagsr­   rh   Úmax_audio_secondsÚclientÚreplicass              r"   rq   Ú _RealtimeTracingSession.__init__Œ  sb   € ð &ÔØ#×8¤s¬4¯:ª:«<Ó'8ˆŒØ'ÔØ)ÔØŒ
Ø!ŒØ"3ÔØ"3ÔØŒØ!ŒØ-1ˆŒØ/3ˆŒØˆ�	r$   c              ƒ  ó0  #   • [        U R                  U R                  U R                  U R                  U R
                  U R                  U R                  U R                  S[        S5      S9
U l
        [        SU R                  0U R                  U R                  U R                  S9U l        U R                  R                  5         [        U R                  U R                  S9U l        [#        U R$                  U R                   U R                  5      $ 7f)Nzopenai-realtimer©   )
rî   rï   rð   rñ   r­   rò   ró   rô   ÚintegrationÚintegration_versionrî   )r­   rñ   rð   rô   rg   )r   rå   ræ   rç   rè   ré   rê   rë   rì   r   rj   r   rí   r„   re   rk   rÀ   r½   r¿   r�   s    r"   Ú
__aenter__Ú"_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              ƒ  ó   #   •  U R                   b  U R                   R                  5         U R                  bG  Ub*  UR                   SU 3U R                  R                  l        U R                  R                  5         U R                  b  U R                  R                  S S S 5        g! [         a    [        R                  SSS9   NKf = f! U R                  b  U R                  R                  S S S 5        f f = f7f)Nz: z)voice tracing: failed to finalize sessionT)Úexc_infoF)rÀ   r�   rj   rµ   rŠ   rw   ÚfinalizerO   ÚloggerÚwarningrí   r“   )ro   Úexc_typeÚexcÚtbs       r"   Ú	__aexit__Ú!_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>„A;B* Á?+C>Â*CÃC Ã
CÃC Ã-C;Ã;C>)rë   r¿   rí   rk   rê   ré   rç   rì   ræ   rj   rè   rå   rÀ   N)rÂ   r   rî   úOptional[str]rï   Úintrð   r  rñ   úOptional[list[str]]r­   úOptional[dict[str, Any]]rh   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¸   r¹   rq   rù   r  rº   r»   r$   r"   rá   rá   ƒ  sƒ   † ñðàðð !ð	ð
 ðð $ðð "ðð +ðð 8ðð +ðð !ðð 3ðð 
ôô8X÷2r$   rá   ©	rî   rï   rð   rñ   r­   rh   rò   ró   rô   c       	        ó&   • [        U UUUUUUUUU	S9
$ )aÕ  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­   rh   rò   ró   rô   s
             r"   Úwrap_realtimer  Ô  s0   € ôT #ØØØØ!ØØØ+Ø+ØØñð r$   )r!   r|   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  rh   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   ra   rc   re   r½   rá   r  r»   r$   r"   Ú<module>r     s7  ðñõ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$   