§
    ~ŠtjX  ã            	      ó0  — d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	 ddl
mZ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mZmZ dd
lmZmZ erddlmZ ddlmZ  ej        e ¦  «        Z!ed         Z"e G d„ d¦  «        ¦   «         Z#ddddeddddœd'd&„Z$dS )(u<  ``EventSession`` â€” Track B's LangSmith ``RunTree`` builder.

The integrations that observe a remote event stream (OpenAI Realtime, OpenAI
Agents realtime, ADK Live) all face the same problem: the service hands them an
event stream rather than emitting its own telemetry for the live loop, so the
trace has to be built by hand with the LangSmith SDK â€” one root span per
conversation, one child span per meaningful event.

``EventSession`` is everything that pattern needs and would otherwise be
duplicated across the adapters:

* a root ``realtime_session`` span carrying the running transcript (``outputs``)
  and the stereo conversation WAV (attachment);
* a child span per event (``event_span``), optionally grouped into ``turn``
  spans;
* point-in-time ``llm`` spans for terminal model responses (``record_llm``);
* timestamped audio recording and a ``finalize`` that rolls up stats + WAV.

Each adapter keeps only what is genuinely provider-specific: which events count
as ``inbound`` (userâ†’model, so the payload lands in span ``inputs``) and how to
label each event span.
é    )ÚannotationsN)ÚIteratorÚSequence)Úcontextmanager)Ú	dataclassÚfield)ÚTYPE_CHECKINGÚAnyÚLiteralÚOptionalÚcast)ÚRunTree)ÚDEFAULT_MAX_AUDIO_SECONDSÚbuild_stereo_session_wavÚ session_wav_exceeds_duration_cap)Ú
dump_eventÚscrub)ÚClient)ÚWriteReplica)ÚtoolÚchainÚllmÚ	retrieverÚ	embeddingÚpromptÚparserc                  ó¶  — e Zd ZU dZded<   ded<   ded<   ded	<   d
Zded<   eZded<    ee	j
        ¬¦  «        Zded<    ee¬¦  «        Zded<    ee¬¦  «        Zded<    edd¬¦  «        Zded<    edd¬¦  «        Zded<    edd¬¦  «        Zded<   dZded<    ee¬¦  «        Zded<    ed
d¬¦  «        Zded <    edd¬¦  «        Zded!<    edd¬¦  «        Zded"<    edd¬¦  «        Zded#<   dSd%„ZdTd'„ZdTd(„ZdUd+„ZdVd/„ZdVd0„ZdWd2„ZdTd3„ZdXd5„Z dYd8„Z!e"d9d
d
d
d
d:œdZdG„¦   «         Z#	 d[dHd
d
d
dIœd\dL„Z$d9d
d
dMœd]dN„Z%d
d
d
dOœd^dP„Z&d_dQ„Z'dTdR„Z(d
S )`ÚEventSessionu  Conversation-level tracing state. One per conversation.

    The root span carries roll-up stats in metadata, the running conversation
    transcript as its ``outputs`` (so the LangSmith preview pane shows the whole
    exchange at a glance â€” see ``add_message``), and the stereo conversation WAV
    as an attachment. Each received event becomes a child span via
    ``event_span`` â€” nested under the current ``turn`` span if the adapter opted
    into turn grouping (see ``start_turn``), otherwise directly under the root.
    r   ÚrunÚstrÚ	thread_idúOptional[str]Úproject_nameÚintÚsample_rateNzOptional[int]Úmax_audio_bytesúOptional[float]Úmax_audio_seconds)Údefault_factoryÚfloatÚt0zlist[tuple[float, bytes]]Úuser_chunksÚagent_chunksr   F)ÚdefaultÚinitÚ_user_bytesÚ_agent_bytesÚboolÚ_audio_truncatedÚevent_countzlist[dict[str, str]]ÚmessagesúRunTree | NoneÚ_current_turnÚ_turn_countÚ_turn_msg_startÚ
_title_setÚreturnc                ó8   — t          j        ¦   «         | j        z
  S )uD   Seconds since the session started â€” the timeline used for the WAV.)ÚtimeÚ	monotonicr+   ©Úselfs    ú_/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/langsmith/_internal/voice/session.pyÚnowzEventSession.nowa   s   € åŒ~ÑÔ $¤'Ñ)Ð)ó    ÚNonec           	     ó  — |                       ¦   «          | xj        dz  c_        t          | j        ¦  «        | _        | j                             ddi dgdd| j        ii¬¦  «        }|                     ¦   «          || _        dS )a‡  Open a new conversational-turn span, closing the previous one.

        Subsequent ``event_span`` calls nest under this turn until the next
        ``start_turn`` (or ``finalize``). The turn's ``outputs`` become the
        transcript lines added during it, so each turn previews its own
        exchange. Opt-in: an adapter that never calls this keeps the flat root
        layout.
        é   Úturnr   Úmetadata©ÚnameÚrun_typeÚinputsÚtagsÚextraN)	Ú_close_turnr8   Úlenr5   r9   r   Úcreate_childÚpostr7   )r@   rG   s     rA   Ú
start_turnzEventSession.start_turne   s“   € ð 	×ÒÑÔÐØÐÔ˜AÑÐÔÝ" 4¤=Ñ1Ô1ˆÔØŒx×$Ò$ØØØØ�Ø ¨Ô(8Ð9Ð:ð %ñ 
ô 
ˆð 	�	Š	‰ŒˆØ!ˆÔÐÐrC   c                óÂ   — | j         €dS | j        | j        d…         }| j                              |rd|ini ¬¦  «         | j                              ¦   «          d| _         dS )z>End the currently open turn span, if any, with its transcript.Nr5   ©Úoutputs)r7   r5   r9   ÚendÚpatch)r@   Úmsgss     rA   rO   zEventSession._close_turn{   sq   € àÔÐ%ØˆFØŒ}˜TÔ1Ð3Ð3Ô4ˆØÔ×Ò¸TÐ'I¨
°DÐ'9Ð'9ÀrÐÑJÔJÐJØÔ× Ò Ñ"Ô"Ð"Ø!ˆÔÐÐrC   ÚroleÚcontentc                óŽ   — |pd                      ¦   «         }|r,| j                             |t          |¦  «        dœ¦  «         dS dS )a  Append one transcript line to the conversation rollup.

        Empty/whitespace content is ignored (failed transcriptions, silent
        turns). Content is truncated like any other span payload (see ``scrub``)
        so an unexpectedly large blob never bloats the root span.
        Ú )rZ   r[   N)Ústripr5   Úappendr   )r@   rZ   r[   s      rA   Úadd_messagezEventSession.add_message„   sX   € ð �=˜b×'Ò'Ñ)Ô)ˆØð 	LØŒM× Ò ¨$½5À¹>¼>Ð!JÐ!JÑKÔKÐKÐKÐKð	Lð 	LrC   ÚtÚdataÚbytesc                ó¶   — |                       | j        |¦  «        }|sdS | xj        t          |¦  «        z  c_        | j                             ||f¦  «         dS )zÏRecord a timestamped chunk of user (mic) PCM16 for the stereo WAV.

        Dropped once the user channel reaches ``max_audio_bytes`` (see that
        field) so a long session can't exhaust memory.
        N)Ú_bounded_audio_chunkr0   rP   r,   r_   ©r@   ra   rb   Úchunks       rA   Úrecord_userzEventSession.record_user�   sd   € ð ×)Ò)¨$Ô*:¸DÑAÔAˆØð 	ØˆFØÐÔ�C ™JœJÑ&ÐÔØÔ×Ò  E 
Ñ+Ô+Ð+Ð+Ð+rC   c                ó¶   — |                       | j        |¦  «        }|sdS | xj        t          |¦  «        z  c_        | j                             ||f¦  «         dS )zÏRecord a timestamped chunk of agent (playback) PCM16 for the WAV.

        Dropped once the agent channel reaches ``max_audio_bytes`` (see that
        field) so a long session can't exhaust memory.
        N)re   r1   rP   r-   r_   rf   s       rA   Úrecord_agentzEventSession.record_agent›   sd   € ð ×)Ò)¨$Ô*;¸TÑBÔBˆØð 	ØˆFØÐÔ�S ™ZœZÑ'ÐÔØÔ× Ò  ! U Ñ,Ô,Ð,Ð,Ð,rC   Úcurrent_bytesc                óÖ   — | j         €|S | j         |z
  }||dz  z  }|dk    r|                      ¦   «          dS t          |¦  «        |k    r|S |                      ¦   «          |d |…         S )Né   r   rC   )r&   Ú_note_audio_truncatedrP   )r@   rk   rb   Ú	remainings       rA   re   z!EventSession._bounded_audio_chunk§   s‚   € ØÔÐ'ØˆKØÔ(¨=Ñ8ˆ	Ø�Y ‘]Ñ"ˆ	Ø˜Š>ˆ>Ø×&Ò&Ñ(Ô(Ð(Ø�3Ýˆt‰9Œ9˜	Ò!Ð!ØˆKØ×"Ò"Ñ$Ô$Ð$Ø�J�Y�JÔÐrC   c                óZ   — | j         rdS d| _         t                               d¦  «         dS )z)Flag once that recorded audio was capped.NTzpvoice tracing: audio capture hit the configured cap; further audio for this conversation is dropped from the WAV)r3   ÚloggerÚwarningr?   s    rA   rn   z"EventSession._note_audio_truncated´   s@   € àÔ ð 	ØˆFØ $ˆÔÝ�ŠðJñ	
ô 	
ð 	
ð 	
ð 	
rC   Útextc                ó¤   — |pd                      ¦   «         }|r| j        rdS t          dt          |¦  «        ¦  «        | j        _        d| _        dS )aÄ  Name the conversation root from its first user utterance (first wins).

        The root's ``name`` is what LangSmith shows in the trace / threads list,
        so naming it after the opening utterance makes conversations scannable
        instead of all reading ``realtime_session``. Only the first non-empty
        utterance applies; scrubbed like any other payload. The new name rides
        along on the root's ``patch`` at ``finalize``.
        r]   Nr    T)r^   r:   r   r   r   rJ   )r@   rs   s     rA   Ú	set_titlezEventSession.set_title¾   sS   € ð �
˜×!Ò!Ñ#Ô#ˆØð 	�t”ð 	ØˆFÝ˜U¥E¨$¡K¤KÑ0Ô0ˆŒŒØˆŒˆˆrC   Úkvr
   c                óÈ   — | j         €dS | j         j        pi }t          |                     d¦  «        pi ¦  «        }|                     |¦  «         ||d<   || j         _        dS )u>  Merge key/values into the open turn span's metadata (no-op if none).

        For per-turn metrics not known when the turn opens â€” e.g.
        ``latency_to_first_audio_ms``, ``was_interrupted``. Applied to the
        currently open turn, so call it before the next ``start_turn`` closes
        that turn.
        NrH   )r7   rN   ÚdictÚgetÚupdate)r@   rv   rN   rH   s       rA   Úadd_turn_metadatazEventSession.add_turn_metadataÍ   sm   € ð ÔÐ%ØˆFØÔ"Ô(Ð.¨BˆÝ˜Ÿ	š	 *Ñ-Ô-Ð3°Ñ4Ô4ˆØ�Š˜ÑÔÐØ$ˆˆjÑØ#(ˆÔÔ Ð Ð rC   r   )rK   rL   rV   Úusage_metadatarH   ÚeventÚt_nowrJ   ÚinboundrK   ÚRunKindrL   údict[str, Any] | NonerV   r|   rH   úIterator[RunTree]c             #  ó¢  K  — | xj         dz  c_         t          t          |¦  «        ¦  «        }
|dup	|dup|dk    }dt          |d¦  «        i}|r|
|d<   |	r|                     |	¦  «         |�t          |¦  «        }n|ri }n|r|
ni }| j        p| j        }|                     |||dgd|i¬	¦  «        }|                     ¦   «          	 |V — |�$| 	                    t          d
|¦  «        ¬¦  «         |r(|                     |�t          |¦  «        ni ¬¦  «         n|                     |ri n|
¬¦  «         |                     ¦   «          dS # |�$| 	                    t          d
|¦  «        ¬¦  «         |r(|                     |�t          |¦  «        ni ¬¦  «         n|                     |ri n|
¬¦  «         |                     ¦   «          w xY w)uB  Open a child span for one received event; close it on body exit.

        Wrapping the handler body means any real work done while handling the
        event (e.g. tool execution) nests inside this span â€” the same way a tool
        call nests under the step that triggered it in any traced app.

        By default the raw (scrubbed) event payload is the span's I/O â€” in
        ``inputs`` for userâ†’model (``inbound``) events, in ``outputs`` otherwise.
        Pass curated ``inputs``/``outputs`` (and optionally a ``run_type`` like
        "llm" plus ``usage_metadata``) to give the span readable,
        conversation-shaped I/O instead; the full wire payload is then preserved
        under ``metadata.raw_event``. Curated values pass through ``scrub`` too,
        so no un-scrubbed event data ever reaches a span.
        rF   Nr   Úreceived_at_sé   Ú	raw_eventr}   rH   rI   r
   ©r|   rU   )r4   r   r   Úroundrz   r7   r   rQ   rR   Úsetr   rW   rX   )r@   r}   r~   rJ   r   rK   rL   rV   r|   rH   ÚpayloadÚcuratedÚmdÚ
run_inputsÚparentr   s                   rA   Ú
event_spanzEventSession.event_spanÝ   s  è è € ð8 	ÐÔ˜AÑÐÔÝ�
 5Ñ)Ô)Ñ*Ô*ˆð  Ð$ÐR¨°tÐ(;ÐR¸xÈ7Ò?Rˆà-­u°U¸A©¬Ð?ˆØð 	&Ø%ˆBˆ{‰OØð 	 Ø�IŠI�hÑÔÐàÐÝ# F™mœmˆJˆJØð 	4ØˆJˆJà$+Ð3˜˜°ˆJàÔ#Ð/ t¤xˆØ×!Ò!ØØØØ�Ø˜rÐ"ð "ñ 
ô 
ˆð 	�Š‰
Œ
ˆ
ð		ØˆIˆIˆIàÐ)Ø—’¥t¨E°>Ñ'BÔ'B�ÑCÔCÐCØð <Ø—’°'Ð2E¥ g¡¤ È2�ÑNÔNÐNÐNà—’ gÐ :  °7�Ñ;Ô;Ð;Ø�IŠI‰KŒKˆKˆKˆKøð Ð)Ø—’¥t¨E°>Ñ'BÔ'B�ÑCÔCÐCØð <Ø—’°'Ð2E¥ g¡¤ È2�ÑNÔNÐNÐNà—’ gÐ :  °7�Ñ;Ô;Ð;Ø�IŠI‰KŒKˆKˆKøøøs   Ã
E ÅB GÚmodel)rJ   rL   r|   rH   rŽ   údict[str, Any]c               óê  — |p| j         p| j        }|€Ct          | j        ¦  «        }|r)|d                              d¦  «        dk    r
|dd…         }d|i}|                     |dt          |¦  «        dgd|pi i¬	¦  «        }|                     ¦   «          |�$|                     t          d
|¦  «        ¬¦  «         | 
                    t          |¦  «        ¬¦  «         |                     ¦   «          dS )u±  Record a point-in-time ``llm`` child span for a model response.

        Voice services deliver a response as a *terminal* event (e.g. Realtime's
        ``response.done``), so there's no model-inference duration to measure â€”
        but the token usage, assistant message, and finish status still belong
        on an ``llm``-kind run for cost rollup and readability. Kept
        point-in-time and separate from the surrounding handler span so local
        tool latency is never attributed to the model call. ``parent`` defaults
        to the current turn (or the root).

        When ``inputs`` is omitted, it defaults to the model's *effective
        prompt* â€” the conversation transcript so far minus the response being
        recorded (the trailing assistant message) â€” so the ``llm`` run reads like
        a normal model call instead of having empty inputs.

        ``usage_metadata`` must be passed here, not patched on afterwards: cost
        is derived when the run is finalized, so usage that lands on a later
        patch (after ``end``) is not reflected. Services that report tokens on a
        separate, later event should defer this call until the counts arrive.
        NéÿÿÿÿrZ   Ú	assistantr5   r   r�   rH   rI   r
   r‡   rU   )r7   r   Úlistr5   ry   rQ   r   rR   r‰   r   rW   rX   )	r@   rŽ   rJ   rV   rL   r|   rH   Úcontextr   s	            rA   Ú
record_llmzEventSession.record_llm   sý   € ð< Ð9˜4Ô-Ð9°´ˆØˆ>Ý˜4œ=Ñ)Ô)ˆGØð '˜7 2œ;Ÿ?š?¨6Ñ2Ô2°kÒAÐAØ! # 2 #œ,�Ø  'Ð*ˆFØ×!Ò!ØØÝ˜‘=”=Ø�Ø˜x˜~¨2Ð.ð "ñ 
ô 
ˆð 	�Š‰
Œ
ˆ
ØÐ%Ø�GŠG¥4¨¨~Ñ#>Ô#>ˆGÑ?Ô?Ð?Ø�Š�˜g™œˆÑ'Ô'Ð'Ø�	Š	‰ŒˆˆˆrC   )rK   rL   rH   c               óÊ   — | xj         dz  c_         | j        p| j        }|                     |||�t	          |¦  «        ni dgd|pi i¬¦  «        }|                     ¦   «          |S )u™  Open a child span and return it for the caller to ``close_span`` later.

        Unlike ``event_span`` (a context manager that fixes its ``outputs`` up
        front), this is for work whose result is only known at a *later* event â€”
        e.g. a tool call that spans a ``tool_start``/``tool_end`` pair, where the
        wall-clock gap between the two events is the real tool latency. Nests
        under the current turn (or the root) and counts toward ``event_count``,
        like any other event span. The caller must pair every ``open_span`` with
        a ``close_span`` (see the adapters' teardown, which closes any that were
        left open).
        rF   Nr}   rH   rI   )r4   r7   r   rQ   r   rR   )r@   rJ   rK   rL   rH   rŽ   r   s          rA   Ú	open_spanzEventSession.open_spanQ  s~   € ð& 	ÐÔ˜AÑÐÔØÔ#Ð/ t¤xˆØ×!Ò!ØØØ$*Ð$6•5˜‘=”=�=¸BØ�Ø˜x˜~¨2Ð.ð "ñ 
ô 
ˆð 	�Š‰
Œ
ˆ
Øˆ
rC   )rV   r|   rH   c               ó‚  — |�$|                      t          d|¦  «        ¬¦  «         |r[|j        pi }t          |                     d¦  «        pi ¦  «        }|                     t          |¦  «        ¦  «         ||d<   ||_        |                     |�t          |¦  «        ni ¬¦  «         |                     ¦   «          dS )u  End and patch a span previously opened with ``open_span``.

        Any error already set on ``run`` (``run.error``) is preserved. Outputs
        pass through ``scrub`` like every other span payload. ``metadata`` is
        merged into the run's existing metadata at close â€” for detail only known
        when the span ends (e.g. the raw wire payload of the event that closed
        it), so an ``open_span`` span can preserve it the way ``event_span``
        does. It passes through ``scrub`` like any other payload.
        Nr
   r‡   rH   rU   )	r‰   r   rN   rx   ry   rz   r   rW   rX   )r@   r   rV   r|   rH   rN   Úmergeds          rA   Ú
close_spanzEventSession.close_spanp  s¶   € ð" Ð%Ø�GŠG¥4¨¨~Ñ#>Ô#>ˆGÑ?Ô?Ð?Øð 	Ø”I�O ˆEÝ˜%Ÿ)š) JÑ/Ô/Ð5°2Ñ6Ô6ˆFØ�MŠM�% ™/œ/Ñ*Ô*Ð*Ø &ˆE�*ÑØˆCŒIØ�Š¨'Ð*=�˜g™œ˜À2ˆÑFÔFÐFØ�	Š	‰ŒˆˆˆrC   c                óN   — t          | j        | j        | j        | j        ¦  «        S ©N)r   r,   r-   r%   r(   r?   s    rA   Ú_audio_exceeds_duration_capz(EventSession._audio_exceeds_duration_capŒ  s,   € Ý/ØÔØÔØÔØÔ"ñ	
ô 
ð 	
rC   c                óâ  — |                       ¦   «          |                      ¦   «         r|                      ¦   «          | j        j        pi }t          |                     d¦  «        pi ¦  «        }| j        |d<   t          t          j
        ¦   «         | j        z
  d¦  «        |d<   | j        rd|d<   ||d<   || j        _        	 t          | j        | j        | j        | j        ¬¦  «        }n.# t$          $ r! t&                               dd¬	¦  «         d
}Y nw xY w|rdd|fi| j        _        | j                             | j        r	d| j        ini ¬¦  «         | j                             ¦   «          dS )a  Roll up stats, attach the stereo WAV, and close the root span.

        Best-effort: a failure building the WAV must not stop the root span from
        being closed, and finalize as a whole must not raise into the caller's
        teardown (see the adapters' ``__aexit__``).
        rH   r4   rm   Ú
duration_sTÚaudio_truncated)Úmax_duration_secondsz*voice tracing: failed to build session WAV)Úexc_inforC   Úconversationz	audio/wavr5   rU   N)rO   rŸ   rn   r   rN   rx   ry   r4   rˆ   r=   r>   r+   r3   r   r,   r-   r%   r(   Ú	Exceptionrq   rr   ÚattachmentsrW   r5   rX   )r@   rN   rH   Úwavs       rA   ÚfinalizezEventSession.finalize”  s™  € ð 	×ÒÑÔÐØ×+Ò+Ñ-Ô-ð 	)Ø×&Ò&Ñ(Ô(Ð(Ø $¤¤Ð 4°"ˆÝ#'¨¯	ª	°*Ñ(=Ô(=Ð(CÀÑ#DÔ#DˆØ"&Ô"2ˆ�ÑÝ!&¥t¤~Ñ'7Ô'7¸$¼'Ñ'AÀ1Ñ!EÔ!Eˆ�ÑØÔ ð 	/Ø*.ˆHÐ&Ñ'Ø$ˆˆjÑØˆŒŒð	Ý*ØÔ ØÔ!ØÔ Ø%)Ô%;ð	ñ ô ˆCˆCøõ ð 	ð 	ð 	õ �NŠNÐGÐRVˆNÑWÔWÐWØˆCˆCˆCð		øøøð
 ð 	ð  ¨cÐ 2ð$ˆDŒHÔ ð 	Œ�Š¸D¼MÐQ˜j¨$¬-Ð8Ð8ÈrˆÑRÔRÐRØŒ�ŠÑÔÐÐÐs   Ã'C+ Ã+(DÄD)r;   r*   )r;   rD   )rZ   r    r[   r    r;   rD   )ra   r*   rb   rc   r;   rD   )rk   r$   rb   rc   r;   rc   )rs   r    r;   rD   )rv   r
   r;   rD   )r}   r
   r~   r*   rJ   r    r   r2   rK   r€   rL   r�   rV   r�   r|   r�   rH   r�   r;   r‚   rž   )rŽ   r6   rJ   r    rV   r‘   rL   r�   r|   r�   rH   r�   r;   rD   )
rJ   r    rK   r€   rL   r�   rH   r�   r;   r   )
r   r   rV   r�   r|   r�   rH   r�   r;   rD   )r;   r2   ))Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__r&   r   r(   r   r=   r>   r+   r•   r,   r-   r0   r1   r3   r4   r5   r7   r8   r9   r:   rB   rS   rO   r`   rh   rj   re   rn   ru   r{   r   r�   r—   r™   rœ   rŸ   r©   © rC   rA   r   r   3   s£  € € € € € € ðð ð €L€L�LØ€N€N�NØÐÐÑØÐÐÑð &*€OÐ)Ð)Ð)Ñ)Ø)BÐÐBÐBÐBÑBà� d¤nÐ5Ñ5Ô5€BÐ5Ð5Ð5Ñ5ð .3¨UÀ4Ð-HÑ-HÔ-H€KÐHÐHÐHÑHØ.3¨eÀDÐ.IÑ.IÔ.I€LÐIÐIÐIÑIà�u Q¨UÐ3Ñ3Ô3€KÐ3Ð3Ð3Ñ3Ø˜ a¨eÐ4Ñ4Ô4€LÐ4Ð4Ð4Ñ4Ø"˜U¨5°uÐ=Ñ=Ô=ÐÐ=Ð=Ð=Ñ=Ø€KÐÐÐÑð &+ U¸4Ð%@Ñ%@Ô%@€HÐ@Ð@Ð@Ñ@ð %* E°$¸UÐ$CÑ$CÔ$C€MÐCÐCÐCÑCØ�u Q¨UÐ3Ñ3Ô3€KÐ3Ð3Ð3Ñ3Ø ˜5¨°Ð7Ñ7Ô7€OÐ7Ð7Ð7Ñ7à�u U°Ð7Ñ7Ô7€JÐ7Ð7Ð7Ñ7ð*ð *ð *ð *ð"ð "ð "ð "ð,"ð "ð "ð "ð	Lð 	Lð 	Lð 	Lð
,ð 
,ð 
,ð 
,ð
-ð 
-ð 
-ð 
-ð ð  ð  ð  ð
ð 
ð 
ð 
ðð ð ð ð)ð )ð )ð )ð  ð $Ø(,Ø)-Ø04Ø*.ð@ð @ð @ð @ð @ñ „^ð@ðH "&ð/ð à(,Ø04Ø*.ð/ð /ð /ð /ð /ð /ðj $Ø(,Ø*.ðð ð ð ð ð ðF *.Ø04Ø*.ðð ð ð ð ð ð8
ð 
ð 
ð 
ð,ð ,ð ,ð ,ð ,ð ,rC   r   Úrealtime_session)r#   rM   rH   rJ   r(   ÚclientÚreplicasÚintegration_versionr!   r    r%   r$   r#   r"   rM   úOptional[list[str]]rH   úOptional[dict[str, Any]]rJ   r(   r'   r±   úOptional[Client]r²   ú Optional[Sequence[WriteReplica]]Úintegrationr³   r;   c           
     óô   — d| dœ|pi ¥|	|
dœ¥}|�d|ini }|�d|ini }t          d|di |pg d|i|d	œ|¤|¤Ž}|                     ¦   «          |�t          ||z  d
z  ¦  «        nd}t          || ||||¬¦  «        S )uX  Create and post the conversation root span, returning an ``EventSession``.

    ``project_name`` falls back to LangSmith's standard resolution
    (``LANGSMITH_PROJECT``) when omitted, like any other ``RunTree``.

    ``client`` is an optional LangSmith ``Client`` for all tracing writes; child
    spans inherit it via ``create_child``. ``None`` uses the SDK's standard
    env-based client resolution.

    ``replicas`` mirrors the conversation trace to additional destinations
    (see LangSmith's tracing replicas). Set on the root and inherited by child
    spans via ``create_child``; ``None`` disables replication.

    ``max_audio_seconds`` caps how much audio per channel is retained and how far
    into the session the stereo WAV can extend, guarding memory on long-running
    sessions. The default is bounded; pass ``None`` to keep all audio. It is
    converted to a per-channel byte budget at PCM16 (2 bytes/sample).

    ``integration`` / ``integration_version`` stamp ``ls_integration`` and
    ``ls_integration_version`` on the root (the convention the batch integrations
    use) so LangSmith can attribute the trace to a specific integration and the
    framework version in use. Set authoritatively â€” a caller cannot shadow them
    via ``metadata``. ``integration_version`` may be ``None`` when the framework
    version can't be resolved.
    Úaudio)Úls_modalityr!   )Úls_integrationÚls_integration_versionNr#   r±   r   rH   )rJ   rK   rL   rM   rN   r²   rm   )r   r!   r#   r%   r&   r(   r¯   )r   rR   r$   r   )r!   r%   r#   rM   rH   rJ   r(   r±   r²   r¸   r³   rŒ   Úproject_kwargsÚclient_kwargsr   r&   s                   rA   Ústart_sessionrÀ   Ã  s  € ðV Øð
ð 
ð ˆ>�rð
ð &Ø"5ð
ð 
ð 
€Bð 8DÐ7O�n lÐ3Ð3ÐUW€Nð +1Ð*<�X˜vÐ&Ð&À"€MÝ
ð 	ØØØØˆZ�RØ˜2ÐØð	ð 	ð ð	ð ð	ð 	€Cð ‡H‚H�J„J€Jð Ð(õ 	Ð Ñ+¨aÑ/Ñ0Ô0Ð0àð õ
 ØØØ!ØØ'Ø+ðñ ô ð rC   )r!   r    r%   r$   r#   r"   rM   r´   rH   rµ   rJ   r    r(   r'   r±   r¶   r²   r·   r¸   r    r³   r"   r;   r   )%r­   Ú
__future__r   Úloggingr=   Úcollections.abcr   r   Ú
contextlibr   Údataclassesr   r   Útypingr	   r
   r   r   r   Ú	langsmithr   Úlangsmith._internal.voice.audior   r   r   Ú!langsmith._internal.voice.helpersr   r   r   Úlangsmith.run_treesr   Ú	getLoggerrª   rq   r€   r   rÀ   r¯   rC   rA   ú<module>rÌ      sÒ  ððð ð. #Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ø %Ð %Ð %Ð %Ð %Ð %Ø (Ð (Ð (Ð (Ð (Ð (Ð (Ð (Ø >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >à Ð Ð Ð Ð Ð ðð ð ð ð ð ð ð ð ð ð
 @Ð ?Ð ?Ð ?Ð ?Ð ?Ð ?Ð ?àð 1Ø Ð Ð Ð Ð Ð Ø0Ð0Ð0Ð0Ð0Ð0à	ˆÔ	˜8Ñ	$Ô	$€ð ÐVÔ
W€ð ðLð Lð Lð Lð Lñ Lô Lñ „ðLðf #'Ø $Ø)-Ø"Ø)BØ#Ø15à)-ðOð Oð Oð Oð Oð Oð Oð OrC   