Ë
    ³ŒjX  ã            	      óN  — 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$y)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#<   d:d$„Zd;d%„Zd;d&„Zd<d'„Zd=d(„Zd=d)„Zd>d*„Zd;d+„Zd?d,„Z d@d-„Z!e"d.d
d
d
d
d/œ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dAd0„«       Z#	 dBd1d
d
d
d2œ	 	 	 	 	 	 	 	 	 	 	 	 	 dCd3„Z$d.d
d
d4œ	 	 	 	 	 	 	 	 	 dDd5„Z%d
d
d
d6œ	 	 	 	 	 	 	 	 	 dEd7„Z&dFd8„Z'd;d9„Z(y
)GÚ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_setc                óD   — t        j                  «       | j                  z
  S )uD   Seconds since the session started â€” the timeline used for the WAV.)ÚtimeÚ	monotonicr+   ©Úselfs    úk/var/www/html/Fitness-lenito-AI-main/venv/lib/python3.12/site-packages/langsmith/_internal/voice/session.pyÚnowzEventSession.nowa   s   € ä�~‰~Ó $§'¡'Ñ)Ð)ó    c           	     ó  — | j                  «        | xj                  dz  c_        t        | j                  «      | _        | j
                  j                  ddi dgdd| j                  ii¬«      }|j                  «        || _        y)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?   rE   s     r@   Ú
start_turnzEventSession.start_turne   s   € ð 	×ÑÔØ×Ò˜AÑÕÜ" 4§=¡=Ó1ˆÔØ�x‰x×$Ñ$ØØØØ�Ø ¨×(8Ñ(8Ð9Ð:ð %ó 
ˆð 	�	‰	ŒØ!ˆÕrB   c                óÖ   — | j                   €y| j                  | j                  d }| j                   j                  |rd|ini ¬«       | j                   j	                  «        d| _         y)z>End the currently open turn span, if any, with its transcript.Nr5   ©Úoutputs)r7   r5   r9   ÚendÚpatch)r?   Úmsgss     r@   rM   zEventSession._close_turn{   sb   € à×ÑÐ%ØØ�}‰}˜T×1Ñ1Ð3Ð4ˆØ×Ñ×Ñ¹T¨
°DÑ'9ÀrÐÔJØ×Ñ× Ñ Ô"Ø!ˆÕrB   c                ó€   — |xs dj                  «       }|r(| j                  j                  |t        |«      dœ«       yy)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.
        Ú )ÚroleÚcontentN)Ústripr5   Úappendr   )r?   rZ   r[   s      r@   Úadd_messagezEventSession.add_message„   s9   € ð ’=˜b×'Ñ'Ó)ˆÙØ�M‰M× Ñ ¨$¼5À»>Ñ!JÕKð rB   c                ó¸   — | j                  | j                  |«      }|sy| xj                  t        |«      z  c_        | j                  j	                  ||f«       y)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   rN   r,   r]   ©r?   ÚtÚdataÚchunks       r@   Úrecord_userzEventSession.record_user�   sO   € ð ×)Ñ)¨$×*:Ñ*:¸DÓAˆÙØØ×ÒœC ›JÑ&ÕØ×Ñ×Ñ  E 
Õ+rB   c                ó¸   — | j                  | j                  |«      }|sy| xj                  t        |«      z  c_        | j                  j	                  ||f«       y)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)r`   r1   rN   r-   r]   ra   s       r@   Úrecord_agentzEventSession.record_agent›   sO   € ð ×)Ñ)¨$×*;Ñ*;¸TÓBˆÙØØ×ÒœS ›ZÑ'ÕØ×Ñ× Ñ  ! U Õ,rB   c                óÂ   — | j                   €|S | j                   |z
  }||dz  z  }|dk  r| j                  «        yt        |«      |k  r|S | j                  «        |d | S )Né   r   rB   )r&   Ú_note_audio_truncatedrN   )r?   Úcurrent_bytesrc   Ú	remainings       r@   r`   z!EventSession._bounded_audio_chunk§   sq   € Ø×ÑÐ'ØˆKØ×(Ñ(¨=Ñ8ˆ	Ø�Y ‘]Ñ"ˆ	Ø˜Š>Ø×&Ñ&Ô(ØÜˆt‹9˜	Ò!ØˆKØ×"Ñ"Ô$Ø�J�YÐÐrB   c                óV   — | j                   ryd| _         t        j                  d«       y)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    r@   rj   z"EventSession._note_audio_truncated´   s(   € à× Ò ØØ $ˆÔÜ�‰ðJõ	
rB   c                ó    — |xs dj                  «       }|r| j                  ryt        dt        |«      «      | j                  _        d| _        y)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``.
        rY   Nr    T)r\   r:   r   r   r   rH   )r?   Útexts     r@   Ú	set_titlezEventSession.set_title¾   s?   € ð ’
˜×!Ñ!Ó#ˆÙ�t—’ØÜ˜U¤E¨$£KÓ0ˆ�‰ŒØˆ�rB   c                óÜ   — | j                   €y| j                   j                  xs i }t        |j                  d«      xs i «      }|j	                  |«       ||d<   || j                   _        y)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.
        NrF   )r7   rL   ÚdictÚgetÚupdate)r?   ÚkvrL   rF   s       r@   Úadd_turn_metadatazEventSession.add_turn_metadataÍ   se   € ð ×ÑÐ%ØØ×"Ñ"×(Ñ(Ò.¨BˆÜ˜Ÿ	™	 *Ó-Ò3°Ó4ˆØ�‰˜ÔØ$ˆˆjÑØ#(ˆ×ÑÕ rB   r   )rI   rJ   rT   Úusage_metadatarF   c             #  ó4  K  — | xj                   dz  c_         t        t        |«      «      }
|duxs |duxs |dk7  }dt        |d«      i}|r|
|d<   |	r|j	                  |	«       |�t        |«      }n|ri }n|r|
ni }| j
                  xs | j                  }|j                  |||dgd|i¬	«      }|j                  «        	 |–— |�|j                  t        d
|«      ¬«       |r |j                  |�t        |«      ni ¬«       n|j                  |ri n|
¬«       |j                  «        y# |�|j                  t        d
|«      ¬«       |r |j                  |�t        |«      ni ¬«       n|j                  |ri n|
¬«       |j                  «        w xY w­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.
        rD   Nr   Úreceived_at_sé   Ú	raw_eventÚeventrF   rG   r
   ©ry   rS   )r4   r   r   Úroundrv   r7   r   rO   rP   Úsetr   rU   rV   )r?   r~   Út_nowrH   ÚinboundrI   rJ   rT   ry   rF   ÚpayloadÚcuratedÚmdÚ
run_inputsÚparentr   s                   r@   Ú
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‰JÙØ‰Já$+™°ˆJà×#Ñ#Ò/ t§x¡xˆØ×!Ñ!ØØØØ�Ø˜rÐ"ð "ó 
ˆð 	�‰Œ
ð		ØŠIàÐ)Ø—‘¤t¨E°>Ó'B�ÔCÙØ—‘°'Ð2E¤ g¤È2�ÕNà—‘¡g¡°7�Ô;Ø�I‰I�Køð Ð)Ø—‘¤t¨E°>Ó'B�ÔCÙØ—‘°'Ð2E¤ g¤È2�ÕNà—‘¡g¡°7�Ô;Ø�I‰I�Küs    ‚B?FÃD- ÃA'FÄ-A(FÆFÚmodel)rH   rJ   ry   rF   c          	     ó°  — |xs | j                   xs | j                  }|€7t        | j                  «      }|r|d   j	                  d«      dk(  r|dd }d|i}|j                  |dt        |«      dgd|xs i i¬	«      }|j                  «        |�|j                  t        d
|«      ¬«       |j                  t        |«      ¬«       |j                  «        y)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Š   rF   rG   r
   r   rS   )r7   r   Úlistr5   ru   rO   r   rP   r�   r   rU   rV   )	r?   rˆ   rH   rT   rJ   ry   rF   Úcontextr   s	            r@   Ú
record_llmzEventSession.record_llm   sÐ   € ð< Ò9˜4×-Ñ-Ò9°·±ˆØˆ>Ü˜4Ÿ=™=Ó)ˆGÙ˜7 2™;Ÿ?™?¨6Ó2°kÒAØ! # 2˜,�Ø  'Ð*ˆFØ×!Ñ!ØØÜ˜“=Ø�Ø˜xš~¨2Ð.ð "ó 
ˆð 	�‰Œ
ØÐ%Ø�G‰G¤4¨¨~Ó#>ˆGÔ?Ø�‰œ˜g›ˆÔ'Ø�	‰	�rB   )rI   rJ   rF   c          	     óØ   — | xj                   dz  c_         | j                  xs | j                  }|j                  |||�t	        |«      ni dgd|xs i i¬«      }|j                  «        |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).
        rD   r~   rF   rG   )r4   r7   r   rO   r   rP   )r?   rH   rI   rJ   rF   rˆ   r   s          r@   Ú	open_spanzEventSession.open_spanQ  ss   € ð& 	×Ò˜AÑÕØ×#Ñ#Ò/ t§x¡xˆØ×!Ñ!ØØØ$*Ð$6”5˜”=¸BØ�Ø˜xš~¨2Ð.ð "ó 
ˆð 	�‰Œ
Øˆ
rB   )rT   ry   rF   c               óJ  — |�|j                  t        d|«      ¬«       |rT|j                  xs i }t        |j	                  d«      xs i «      }|j                  t        |«      «       ||d<   ||_        |j                  |�t        |«      ni ¬«       |j                  «        y)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   rF   rS   )	r�   r   rL   rt   ru   rv   r   rU   rV   )r?   r   rT   ry   rF   rL   Úmergeds          r@   Ú
close_spanzEventSession.close_spanp  sŠ   € ð" Ð%Ø�G‰G¤4¨¨~Ó#>ˆGÔ?ÙØ—I‘I’O ˆEÜ˜%Ÿ)™) JÓ/Ò5°2Ó6ˆFØ�M‰Mœ% ›/Ô*Ø &ˆE�*ÑØˆCŒIØ�‰¨'Ð*=œ˜gœÀ2ˆÔFØ�	‰	�rB   c                ón   — t        | j                  | j                  | j                  | j                  «      S ©N)r   r,   r-   r%   r(   r>   s    r@   Ú_audio_exceeds_duration_capz(EventSession._audio_exceeds_duration_capŒ  s3   € Ü/Ø×ÑØ×ÑØ×ÑØ×"Ñ"ó	
ð 	
rB   c                ó*  — | j                  «        | j                  «       r| j                  «        | j                  j                  xs i }t        |j                  d«      xs i «      }| j                  |d<   t        t        j                  «       | j                  z
  d«      |d<   | j                  rd|d<   ||d<   || j                  _        	 t        | j                  | j                  | j                   | j"                  ¬«      }|rdd|fi| j                  _        | j                  j-                  | j.                  rd| j.                  ini ¬«       | j                  j1                  «        y# t$        $ r t&        j)                  dd¬	«       d
}Y ŒŒw xY w)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__``).
        rF   r4   ri   Ú
duration_sTÚaudio_truncated)Úmax_duration_secondsz*voice tracing: failed to build session WAV)Úexc_inforB   Úconversationz	audio/wavr5   rS   N)rM   r˜   rj   r   rL   rt   ru   r4   r€   r<   r=   r+   r3   r   r,   r-   r%   r(   Ú	Exceptionrn   ro   ÚattachmentsrU   r5   rV   )r?   rL   rF   Úwavs       r@   ÚfinalizezEventSession.finalize”  s[  € ð 	×ÑÔØ×+Ñ+Ô-Ø×&Ñ&Ô(Ø $§¡§¡Ò 4°"ˆÜ#'¨¯	©	°*Ó(=Ò(CÀÓ#DˆØ"&×"2Ñ"2ˆ�ÑÜ!&¤t§~¡~Ó'7¸$¿'¹'Ñ'AÀ1Ó!Eˆ�ÑØ× Ò Ø*.ˆHÐ&Ñ'Ø$ˆˆjÑØˆ�‰Œð	Ü*Ø× Ñ Ø×!Ñ!Ø× Ñ Ø%)×%;Ñ%;ô	ˆCñ ð  ¨cÐ 2ð$ˆD�H‰HÔ ð 	�‰�‰¸D¿MºM˜j¨$¯-©-Ñ8ÈrˆÔRØ�‰�‰Õøô# ò 	ô �N‰NÐGÐRVˆNÔWØŠCð		ús   Ã7E- Å-"FÆF)Úreturnr*   )r£   ÚNone)rZ   r    r[   r    r£   r¤   )rb   r*   rc   Úbytesr£   r¤   )rk   r$   rc   r¥   r£   r¥   )rq   r    r£   r¤   )rw   r
   r£   r¤   )r~   r
   r‚   r*   rH   r    rƒ   r2   rI   ÚRunKindrJ   údict[str, Any] | NonerT   r§   ry   r§   rF   r§   r£   zIterator[RunTree]r—   )rˆ   r6   rH   r    rT   zdict[str, Any]rJ   r§   ry   r§   rF   r§   r£   r¤   )
rH   r    rI   r¦   rJ   r§   rF   r§   r£   r   )
r   r   rT   r§   ry   r§   rF   r§   r£   r¤   )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:   rA   rQ   rM   r^   re   rg   r`   rj   rr   rx   r   r‰   r�   r’   r•   r˜   r¢   © rB   r@   r   r   3   s·  … ñð 
ƒLØƒNØÓØÓð &*€O�]Ó)Ø)BÐ�ÓBá d§n¡nÔ5€BˆÓ5ñ .3À4Ô-H€KÐ*ÓHÙ.3ÀDÔ.I€LÐ+ÓIá Q¨UÔ3€K�Ó3Ù a¨eÔ4€L�#Ó4Ù"¨5°uÔ=Ð�dÓ=Ø€K�Óñ &+¸4Ô%@€HÐ"Ó@ñ %*°$¸UÔ$C€M�>ÓCÙ Q¨UÔ3€K�Ó3Ù ¨°Ô7€O�SÓ7á U°Ô7€J�Ó7ó*ó"ó,"ó	Ló
,ó
-ó ó
óó)ð  ð $Ø(,Ø)-Ø04Ø*.ñ@àð@ð ð@ð
 ð@ð ð@ð ð@ð &ð@ð 'ð@ð .ð@ð (ð@ð 
ò@ó ð@ðH "&ð/ð à(,Ø04Ø*.ñ/àð/ð ð	/ð
  ð/ð &ð/ð .ð/ð (ð/ð 
ó/ðj $Ø(,Ø*.ñð ðð ð	ð
 &ðð (ðð 
óðF *.Ø04Ø*.ñàðð 'ð	ð
 .ðð (ðð 
óó8
ô,rB   r   Úrealtime_session)r#   rK   rF   rH   r(   ÚclientÚreplicasÚintegration_versionc           
     óâ   — d| dœ|xs i ¥|	|
dœ¥}|�d|ini }|�d|ini }t        d|di |xs g d|i|d	œ|¤|¤Ž}|j                  «        |�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   rF   )rH   rI   rJ   rK   rL   r°   ri   )r   r!   r#   r%   r&   r(   r­   )r   rP   r$   r   )r!   r%   r#   rK   rF   rH   r(   r¯   r°   Úintegrationr±   r†   Úproject_kwargsÚclient_kwargsr   r&   s                   r@   Ústart_sessionrº   Ã  sä   € ðV Øñ
ð Š>�rð
ð &Ø"5ò
€Bð 8DÐ7O�n lÑ3ÐUW€Nð +1Ð*<�X˜vÑ&À"€MÜ
ð 	ØØØØŠZ�RØ˜2ÐØñ	ð ð	ð ñ	€Cð ‡H�H„Jð Ð(ô 	Ð Ñ+¨aÑ/Ô0àð ô
 ØØØ!ØØ'Ø+ôð rB   )r!   r    r%   r$   r#   r"   rK   zOptional[list[str]]rF   zOptional[dict[str, Any]]rH   r    r(   r'   r¯   zOptional[Client]r°   z Optional[Sequence[WriteReplica]]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¨   rn   r¦   r   rº   r­   rB   r@   Ú<module>rÆ      s  ðñõ. #ã Û ß .Ý %ß (ß >Õ >å ÷ñ ÷
 @áÝ Ý0à	ˆ×	Ñ	˜8Ó	$€ð ÐVÑ
W€ð ÷Lð Ló ðLðf #'Ø $Ø)-Ø"Ø)BØ#Ø15à)-ñOàðOð ðOð  ð	Oð
 ðOð 'ðOð ðOð 'ðOð ðOð /ðOð ðOð 'ðOð ôOrB   