ó
    üÞ jX  ã            	      ó\  • S r SSKJr  SSKrSSKrSSKJrJr  SSKJ	r	  SSK
JrJr  SSKJrJrJrJrJr  SSKJr  SS	KJrJrJr  SS
KJrJr  \(       a  SSKJr  SSKJr  \R>                  " \ 5      r!\S   r"\ " S S5      5       r#SSSS\SSSS.                       SS jjr$g)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                  óÊ  • \ rS rSr% SrS\S'   S\S'   S\S'   S	\S
'   SrS\S'   \rS\S'   \	" \
R                  S9rS\S'   \	" \S9rS\S'   \	" \S9rS\S'   \	" SSS9rS	\S'   \	" SSS9rS	\S'   \	" SSS9rS\S'   SrS	\S'   \	" \S9rS\S'   \	" SSS9rS \S!'   \	" SSS9rS	\S"'   \	" SSS9rS	\S#'   \	" SSS9rS\S$'   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=S, jr SAS- jr!SBS. jr"\#S/SSSSS0.                   SCS1 jj5       r$ SDS2SSSS3.             SES4 jjjr%S/SSS5.         SFS6 jjr&SSSS7.         SGS8 jjr'SHS9 jr(S=S: jr)S;r*g)IÚEventSessioné3   uù  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                óF   • [         R                  " 5       U R                  -
  $ )uD   Seconds since the session started â€” the timeline used for the WAV.)ÚtimeÚ	monotonicr,   ©Úselfs    Ú[/var/www/html/gaurav/venv/lib/python3.13/site-packages/langsmith/_internal/voice/session.pyÚnowÚEventSession.nowa   s   € ä�~Š~Ó $§'¡'Ñ)Ð)ó    c           	     ó  • U R                  5         U =R                  S-  sl        [        U R                  5      U l        U R
                  R                  SS0 S/SSU R                  00S9nUR                  5         Xl        g)aW  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_turnr9   Úlenr6   r:   r    Úcreate_childÚpostr8   )r@   rG   s     rA   Ú
start_turnÚEventSession.start_turne   s}   € ð 	×ÑÔØ×Ò˜AÑÕÜ" 4§=¡=Ó1ˆÔØ�x‰x×$Ñ$ØØØØ�Ø ¨×(8Ñ(8Ð9Ð:ð %ð 
ˆð 	�	‰	ŒØ!ÕrD   c                óÜ   • U R                   c  gU R                  U R                  S nU R                   R                  U(       a  SU0O0 S9  U R                   R	                  5         SU l         g)z>End the currently open turn span, if any, with its transcript.Nr6   ©Úoutputs)r8   r6   r:   ÚendÚpatch)r@   Úmsgss     rA   rO   ÚEventSession._close_turn{   sb   € à×ÑÑ%ØØ�}‰}˜T×1Ñ1Ð3Ð4ˆØ×Ñ×Ñ¾T¨
°DÑ'9ÀrÐÑJØ×Ñ× Ñ Ô"Ø!ˆÕrD   c                ó”   • U=(       d    SR                  5       nU(       a(  U R                  R                  U[        U5      S.5        gg)zþ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)Ústripr6   Úappendr   )r@   r^   r_   s      rA   Úadd_messageÚEventSession.add_message„   s9   € ð —=˜b×'Ñ'Ó)ˆÞØ�M‰M× Ñ ¨$¼5À»>Ñ!JÕKð rD   c                óÀ   • U R                  U R                  U5      nU(       d  gU =R                  [        U5      -  sl        U R                  R	                  X45        g)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_chunkr1   rP   r-   ra   ©r@   ÚtÚdataÚchunks       rA   Úrecord_userÚEventSession.record_user�   sM   € ð ×)Ñ)¨$×*:Ñ*:¸DÓAˆÞØØ×ÒœC ›JÑ&ÕØ×Ñ×Ñ  
Õ+rD   c                óÀ   • U R                  U R                  U5      nU(       d  gU =R                  [        U5      -  sl        U R                  R	                  X45        g)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   r2   rP   r.   ra   rf   s       rA   Úrecord_agentÚEventSession.record_agent›   sM   € ð ×)Ñ)¨$×*;Ñ*;¸TÓBˆÞØØ×ÒœS ›ZÑ'ÕØ×Ñ× Ñ  ! Õ,rD   c                óÆ   • U R                   c  U$ U R                   U-
  nX3S-  -  nUS::  a  U R                  5         g[        U5      U::  a  U$ U R                  5         US U $ )Né   r   rD   )r'   Ú_note_audio_truncatedrP   )r@   Úcurrent_bytesrh   Ú	remainings       rA   re   Ú!EventSession._bounded_audio_chunk§   so   € Ø×ÑÑ'ØˆKØ×(Ñ(¨=Ñ8ˆ	Ø ‘]Ñ"ˆ	Ø˜‹>Ø×&Ñ&Ô(ØÜˆt‹9˜	Ó!ØˆKØ×"Ñ"Ô$Ø�J�YÐÐrD   c                ó`   • U R                   (       a  gSU l         [        R                  S5        g)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)r4   ÚloggerÚwarningr?   s    rA   rq   Ú"EventSession._note_audio_truncated´   s(   € à× × ØØ $ˆÔÜ�‰ðJõ	
rD   c                ó¾   • U=(       d    SR                  5       nU(       a  U R                  (       a  g[        S[        U5      5      U R                  l        SU l        g)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@   Útexts     rA   Ú	set_titleÚEventSession.set_title¾   s?   € ð —
˜×!Ñ!Ó#ˆÞ�t——ØÜ˜U¤E¨$£KÓ0ˆ�‰ŒØˆ�rD   c                óî   • U R                   c  gU R                   R                  =(       d    0 n[        UR                  S5      =(       d    0 5      nUR	                  U5        X2S'   X R                   l        g)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   )r8   rN   ÚdictÚgetÚupdate)r@   ÚkvrN   rH   s       rA   Úadd_turn_metadataÚEventSession.add_turn_metadataÍ   sa   € ð ×ÑÑ%ØØ×"Ñ"×(Ñ(×.¨BˆÜ˜Ÿ	™	 *Ó-×3°Ó4ˆØ�‰˜ÔØ$ˆjÑØ#(×ÑÕ rD   r   )rK   rL   rW   Úusage_metadatarH   c             #  ó€  #   • U =R                   S-  sl         [        [        U5      5      n
USL=(       d    USL=(       d    US:g  nS[        US5      0nU(       a  X¬S'   U	(       a  UR	                  U	5        Ub  [        U5      nOU(       a  0 nOU(       a  U
O0 nU R
                  =(       d    U R                  nUR                  UUUS/SU0S	9nUR                  5          Uv •  Ub  UR                  [        S
U5      S9  U(       a  UR                  Ub  [        U5      O0 S9  OUR                  U(       a  0 OU
S9  UR                  5         g! Ub  UR                  [        S
U5      S9  U(       a  UR                  Ub  [        U5      O0 S9  OUR                  U(       a  0 OU
S9  UR                  5         f = f7f)uê  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_eventÚeventrH   rI   r
   ©r„   rV   )r5   r   r   Úroundr€   r8   r    rQ   rR   Úsetr   rX   rY   )r@   r‰   Út_nowrJ   ÚinboundrK   rL   rW   r„   rH   ÚpayloadÚcuratedÚmdÚ
run_inputsÚparentr    s                   rA   Ú
event_spanÚEventSession.event_spanÝ   s‹  é € ð8 	×Ò˜AÑÕÜœ
 5Ó)Ó*ˆð  Ð$×R¨°tÐ(;×R¸xÈ7Ñ?Rˆà-¬u°U¸A«Ð?ˆÞØ%ˆ{‰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    ‚CF>Ã"E Ã&A*F>ÅA+F;Æ;F>Úmodel)rJ   rL   r„   rH   c          	     óÌ  • U=(       d    U R                   =(       d    U R                  nUc=  [        U R                  5      nU(       a  US   R	                  S5      S:X  a  USS nSU0nUR                  US[        U5      S/SU=(       d    0 0S	9nUR                  5         Ub  UR                  [        S
U5      S9  UR                  [        U5      S9  UR                  5         g)u1  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éÿÿÿÿr^   Ú	assistantr6   r   r–   rH   rI   r
   rŠ   rV   )r8   r    Úlistr6   r   rQ   r   rR   rŒ   r   rX   rY   )	r@   r“   rJ   rW   rL   r„   rH   Úcontextr    s	            rA   Ú
record_llmÚEventSession.record_llm   sÐ   € ð< ×9˜4×-Ñ-×9°·±ˆØ‰>Ü˜4Ÿ=™=Ó)ˆGÞ˜7 2™;Ÿ?™?¨6Ó2°kÓAØ! # 2˜,�Ø  'Ð*ˆFØ×!Ñ!ØØÜ˜“=Ø�Ø˜xŸ~¨2Ð.ð "ð 
ˆð 	�‰Œ
ØÑ%Ø�G‰G¤4¨¨~Ó#>ˆGÑ?Ø�‰œ˜g›ˆÑ'Ø�	‰	�rD   )rK   rL   rH   c          	     óè   • U =R                   S-  sl         U R                  =(       d    U R                  nUR                  UUUb  [	        U5      O0 S/SU=(       d    0 0S9nUR                  5         U$ )uQ  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   r‰   rH   rI   )r5   r8   r    rQ   r   rR   )r@   rJ   rK   rL   rH   r“   r    s          rA   Ú	open_spanÚEventSession.open_spanQ  ss   € ð& 	×Ò˜AÑÕØ×#Ñ#×/ t§x¡xˆØ×!Ñ!ØØØ$*Ñ$6”5˜”=¸BØ�Ø˜xŸ~¨2Ð.ð "ð 
ˆð 	�‰Œ
Øˆ
rD   )rW   r„   rH   c               ó\  • Ub  UR                  [        SU5      S9  U(       a\  UR                  =(       d    0 n[        UR	                  S5      =(       d    0 5      nUR                  [        U5      5        XeS'   XQl        UR                  Ub  [        U5      O0 S9  UR                  5         g)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   rV   )	rŒ   r   rN   r~   r   r€   r   rX   rY   )r@   r    rW   r„   rH   rN   Úmergeds          rA   Ú
close_spanÚEventSession.close_spanp  s†   € ð" Ñ%Ø�G‰G¤4¨¨~Ó#>ˆGÑ?ÞØ—I‘I—O ˆEÜ˜%Ÿ)™) JÓ/×5°2Ó6ˆFØ�M‰Mœ% ›/Ô*Ø &�*ÑØŒIØ�‰¨'Ñ*=œ˜gœÀ2ˆÑFØ�	‰	�rD   c                ón   • [        U R                  U R                  U R                  U R                  5      $ ©N)r   r-   r.   r&   r)   r?   s    rA   Ú_audio_exceeds_duration_capÚ(EventSession._audio_exceeds_duration_capŒ  s3   € Ü/Ø×ÑØ×ÑØ×ÑØ×"Ñ"ó	
ð 	
rD   c                óT  • U R                  5         U R                  5       (       a  U R                  5         U R                  R                  =(       d    0 n[        UR                  S5      =(       d    0 5      nU R                  US'   [        [        R                  " 5       U R                  -
  S5      US'   U R                  (       a  SUS'   X!S'   XR                  l         [        U R                  U R                  U R                   U R"                  S9nU(       a  SSU40U R                  l        U R                  R-                  U R.                  (       a  SU R.                  0O0 S9  U R                  R1                  5         g! [$         a    [&        R)                  SSS	9  S
n N‘f = f)zü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   r5   rp   Ú
duration_sTÚaudio_truncated)Úmax_duration_secondsz*voice tracing: failed to build session WAV)Úexc_inforD   Úconversationz	audio/wavr6   rV   N)rO   r§   rq   r    rN   r~   r   r5   r‹   r=   r>   r,   r4   r   r-   r.   r&   r)   Ú	Exceptionrv   rw   ÚattachmentsrX   r6   rY   )r@   rN   rH   Úwavs       rA   ÚfinalizeÚEventSession.finalize”  sZ  € ð 	×ÑÔØ×+Ñ+×-Ñ-Ø×&Ñ&Ô(Ø $§¡§¡× 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   Ã!4F Æ F'Æ&F')r4   r8   r;   r:   )Úreturnr+   )r´   ÚNone)r^   r!   r_   r!   r´   rµ   )rg   r+   rh   Úbytesr´   rµ   )rr   r%   rh   r¶   r´   r¶   )rz   r!   r´   rµ   )r�   r
   r´   rµ   )r‰   r
   r�   r+   rJ   r!   rŽ   r3   rK   ÚRunKindrL   údict[str, Any] | NonerW   r¸   r„   r¸   rH   r¸   r´   zIterator[RunTree]r¦   )r“   r7   rJ   r!   rW   zdict[str, Any]rL   r¸   r„   r¸   rH   r¸   r´   rµ   )
rJ   r!   rK   r·   rL   r¸   rH   r¸   r´   r   )
r    r   rW   r¸   r„   r¸   rH   r¸   r´   rµ   )r´   r3   )+Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__r'   r   r)   r   r=   r>   r,   rš   r-   r.   r1   r2   r4   r5   r6   r8   r9   r:   r;   rB   rS   rO   rb   rj   rm   re   rq   r{   r‚   r   r”   rœ   rŸ   r£   r§   r²   Ú__static_attributes__© rD   rA   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
÷,rD   r   Úrealtime_session)r$   rM   rH   rJ   r)   ÚclientÚreplicasÚintegration_versionc           
     óô   • SU S.U=(       d    0 EU	U
S.EnUb  SU0O0 nUb  SU0O0 n[        SUS0 U=(       d    / SU0US	.UDUD6nUR                  5         Ub  [        Xa-  S
-  5      OSn[        UU UUUUS9$ )u  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Ã   rp   )r    r"   r$   r&   r'   r)   rÀ   )r   rR   r%   r   )r"   r&   r$   rM   rH   rJ   r)   rÂ   rÃ   ÚintegrationrÄ   r‘   Úproject_kwargsÚclient_kwargsr    r'   s                   rA   Ú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àð ô
 ØØØ!ØØ'Ø+ñð rD   )r"   r!   r&   r%   r$   r#   rM   zOptional[list[str]]rH   zOptional[dict[str, Any]]rJ   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¹   rv   r·   r   rÍ   rÀ   rD   rA   Ú<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rD   