
    /j                       % 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J	r	J
r
JrJrJ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  SSKJrJr  SSKJr  SSKJ r   \(       a
  SSK!J"r"J#r#J$r$   " S S\%5      r& " S S\5      r' " S S\5      r(\S   r)S\*S'    " S S\SS9r+ " S S\SS9r, " S S \5      r-\'\(-  \&-  \%-  r.S\*S!'    " S" S#\5      r/ " S$ S%\5      r0 " S& S'\5      r1 " S( S)\5      r2\	\-\/-  \0-  \1-  \2-  \" S*S+94   r3 " S, S-5      r4 " S. S/\45      r5S3S4S0 jjr6  S5       S6S1 jjr7S7S2 jr8g)8    )annotationsN)	GeneratorSequence)TYPE_CHECKING	AnnotatedAnyLiteral	TypeAliasoverload)	BaseModelFieldPrivateAttrTypeAdapter)	TypedDict)rtc   )utils)logger)	NOT_GIVEN
NotGivenOr)is_given   )_provider_format)LLMToolToolsetc                     ^  \ rS rSr% SrS\S'   S\S'   SSS.       SU 4S	 jjjr\SS
 j5       r\SS j5       r	SS jr
SS jrSS jrSS jrSS jr\SS j5       rSrU =r$ )Instructions%   a  Instructions that adapt based on the user's input modality (audio vs. text).

``str(self)`` is what providers see when treating this as a plain string.
By default it equals the ``audio`` variant; after :meth:`as_modality` it
equals the chosen variant.

``_audio_variant`` and ``_text_variant`` are always preserved so
:meth:`as_modality` can be called again for a different modality (e.g.,
when the same ``ChatContext`` is reused across tool-call turns).
str_audio_variant
str | None_text_variantN)text
_representc               H   > [         TU ]  Xb  UOU5      nXl        X$l        U$ )zCreate an Instructions object.

Args:
    audio: The audio (voice) variant.
    text: The text variant.  Falls back to ``audio`` when omitted.
)super__new__r!   r#   )clsaudior$   r%   instance	__class__s        P/app/agent/.venv/lib/python3.13/site-packages/livekit/agents/llm/chat_context.pyr(   Instructions.__new__4   s,     7?36L
RWX"'!%    c                    U R                   $ )z.The audio (voice) variant of the instructions.)r!   selfs    r-   r*   Instructions.audioB   s     """r/   c                L    U R                   b  U R                   $ U R                  $ )zjThe text variant of the instructions.

Falls back to the audio variant when no text variant was provided.
)r#   r!   r1   s    r-   r$   Instructions.textG   s&     &*%7%7%Ct!!\I\I\\r/   c           	        [        S U 5       5      =(       d     [        S UR                  5        5       5      nU(       a  [        S U 5       5      n[        S U 5       5      nUR                  5        VVs0 s H)  u  pgU[	        U[
        5      (       a  UR                  OU_M+     nnnUR                  5        VVs0 s H)  u  pgU[	        U[
        5      (       a  UR                  OU_M+     n	nnOU=pEU=p[        U R                  R                  " U0 UD6U(       d  U R                  b  U R                  R                  " U0 U	D6OS[        U 5      R                  " U0 UD6S9$ s  snnf s  snnf )z9Format the instructions with the given keyword arguments.c              3  B   #    U  H  n[        U[        5      v   M     g 7fN
isinstancer   .0args     r-   	<genexpr>&Instructions.format.<locals>.<genexpr>R   s     Mz#|<<   c              3  B   #    U  H  n[        U[        5      v   M     g 7fr8   r9   )r<   vs     r-   r>   r?   R   s      U
1@AJq,''r@   c              3  h   #    U  H(  n[        U[        5      (       a  UR                  OUv   M*     g 7fr8   )r:   r   r*   r;   s     r-   r>   r?   V   s(     c^bWZJsL,I,IsyysR^b   02c              3  h   #    U  H(  n[        U[        5      (       a  UR                  OUv   M*     g 7fr8   )r:   r   r$   r;   s     r-   r>   r?   W   s(     a\`UX*S,*G*GchhSP\`rD   Nr*   r$   r%   )anyvaluestupleitemsr:   r   r*   r$   formatr#   r    )
r2   argskwargsany_instructions
audio_args	text_argskrB   audio_kwargstext_kwargss
             r-   rK   Instructions.formatO   s^    MMM 
QT U
17U
 R
 c^bccJa\`aaIMS\\^M[TQjL99177q@^   MSLLNLZDAZ<88166a?N  K &*)J)//L**##Z@<@ $t'9'9'E 		  );{;4y''88
 	
s   80E&>0E,c                |    [        U R                  U R                  US:X  a  U R                  S9$ U R                  S9$ )zReturn a copy whose ``str`` value is the correct variant for *modality*.

Both ``_audio_variant`` and ``_text_variant`` are preserved so this can
be called again for a different modality (e.g. across tool-call turns).
r*   rF   )r   r!   r#   r*   r$   )r2   modalitys     r-   as_modalityInstructions.as_modalityl   sE     %%##%-%8tzz
 	
 ?Cii
 	
r/   c                   [        U[        5      (       az  U R                  SL=(       d    UR                  SLn[        U R                  UR                  -   U(       a  U R                  UR                  -   OS[        U 5      [        U5      -   S9$ [        U[
        5      (       a@  [        U R                  U-   U R                  b  U R                  U-   OS[        U 5      U-   S9$ [        S[        U5       35      e)zAConcatenate, propagating both variants and the current str value.NrF   zCannot add Instructions and )r:   r   r#   r*   r$   r    	TypeErrortype)r2   otherhas_texts      r-   __add__Instructions.__add__x   s    e\**))5X9L9LTX9XHjj5;;.19dii%**,tt9s5z1 
 eS!!jj5(595G5G5Sd((50Y]t9u, 
 6tE{mDEEr/   c                    [        U[        5      (       a>  [        XR                  -   U R                  b  XR                  -   OSU[        U 5      -   S9$ [        S[        U5       S35      e)z@Support ``plain_str + Instructions``, propagating both variants.NrF   zCannot add z and Instructions)r:   r    r   r*   r#   rZ   r[   )r2   r\   s     r-   __radd__Instructions.__radd__   sg    eS!!jj(595G5G5Se000Y] 3t9, 
 +d5k]2CDEEr/   c                "    S[        U 5      < S3$ )NzInstructions())r    r1   s    r-   __repr__Instructions.__repr__   s    s4ym1--r/   c           	        ^  SSK Jn  S	U 4S jjnS	U 4S jjnS
S jnUR                  UR                  U5      UR                  U5      UR	                  USS9S9$ )Nr   )core_schemac                   > [        U [        5      (       a  U $ [        U [        5      (       a.  U R                  S5      S:X  a  T" U S   U R                  S5      S9$ [	        S[        U 5      < S35      eNr[   instructionsr*   r$   )r$   zCannot convert z to Instructions)r:   r   dictget
ValueErrorr[   rB   r)   s    r-   validate_pythonBInstructions.__get_pydantic_core_schema__.<locals>.validate_python   sc    !\**!T""quuV}'F1W:AEE&M::tAwk9IJKKr/   c                   > [        U [        5      (       a.  U R                  S5      S:X  a  T" U S   U R                  S5      S9$ [        S[	        U 5      < S35      erj   )r:   rl   rm   rn   r[   ro   s    r-   validate_json@Instructions.__get_pydantic_core_schema__.<locals>.validate_json   sQ    !T""quuV}'F1W:AEE&M::tAwk9IJKKr/   c                \    SU R                   S.nU R                  b  U R                  US'   U$ )Nrk   )r[   r*   r$   )r*   r#   )rB   ds     r-   	serialize<Instructions.__get_pydantic_core_schema__.<locals>.serialize   s,    )7!'' JA*OO&	Hr/   F)info_arg)python_schemajson_schemaserialization)rB   r   returnr   )rB   r   r}   dict[str, Any])pydantic_corerh   json_or_python_schema no_info_plain_validator_function$plain_serializer_function_ser_schema)r)   source_typehandlerrh   rp   rs   rw   s   `      r-   __get_pydantic_core_schema__)Instructions.__get_pydantic_core_schema__   sf    -	L	L
	 00%FFW#DD]S%JJE K  1 
 	
r/    )r*   r    r$   r"   r%   r"   r}   r   )r}   r    )rL   objectrM   r   r}   r   )rV   zLiteral['audio', 'text']r}   r   )r\   r   r}   r   )r   r   r   r   r}   r   )__name__
__module____qualname____firstlineno____doc____annotations__r(   propertyr*   r$   rK   rW   r^   ra   re   classmethodr   __static_attributes____classcell__)r,   s   @r-   r   r   %   s    	  04d",AK	  # # ] ]
:

F"F. 
 
r/   r   c                      \ rS rSr% Sr\" S S9rS\S'    \" SS9rS	\S
'   S\S'    Sr	S\S'    Sr
S\S'    SrS\S'    SrS\S'    \" \S9rS\S'   Srg)ImageContent   a  
ImageContent is used to input images into the ChatContext on supported LLM providers / plugins.

You may need to consult your LLM provider's documentation on supported URL types.

```python
# Pass a VideoFrame directly, which will be automatically converted to a JPEG data URL internally
async for event in rtc.VideoStream(video_track):
    chat_image = ImageContent(image=event.frame)
    # this instance is now available for your ChatContext

# Encode your VideoFrame yourself for more control, and pass the result as a data URL (see EncodeOptions for more details)
from livekit.agents.utils.images import encode, EncodeOptions, ResizeOptions

image_bytes = encode(
    event.frame,
    EncodeOptions(
        format="PNG",
        resize_options=ResizeOptions(width=512, height=512, strategy="scale_aspect_fit"),
    ),
)
chat_image = ImageContent(
    image=f"data:image/png;base64,{base64.b64encode(image_bytes).decode('utf-8')}"
)

# With an external URL
chat_image = ImageContent(image="https://example.com/image.jpg")
```
c                 .    [         R                  " S5      $ )Nimg_r   	shortuuidr   r/   r-   <lambda>ImageContent.<lambda>   s    EOOF,Cr/   default_factoryr    idimage_contentdefaultzLiteral['image_content']r[   zstr | rtc.VideoFrameimageN
int | Noneinference_widthinference_heightautozLiteral['auto', 'high', 'low']inference_detailr"   	mime_typezdict[Any, Any]_cacher   )r   r   r   r   r   r   r   r   r[   r   r   r   r   r   rl   r   r   r   r/   r-   r   r      s    < $CDBD &+?%CD
"C #'OZ& $(j' 8>4=
 !Iz  )>FN>r/   r   c                  D    \ rS rSr% \" SS9rS\S'   S\S'   SrS	\S
'   Srg)AudioContent   audio_contentr   zLiteral['audio_content']r[   zlist[rtc.AudioFrame]frameNr"   
transcriptr   )	r   r   r   r   r   r[   r   r   r   r   r/   r-   r   r      s"    %*?%CD
"C!J
!r/   r   )	developersystemuser	assistantr
   ChatRolec                  *    \ rS rSr% S\S'   S\S'   Srg)MetricsMetadata   r    
model_namemodel_providerr   Nr   r   r   r   r   r   r   r/   r-   r   r      s    Or/   r   F)totalc                      \ rS rSr% S\S'   S\S'   S\S'    S\S'    S\S'    S\S'    S\S	'    S\S
'    S\S'   S\S'   S\S'   Srg)MetricsReporti  floatstarted_speaking_atstopped_speaking_attranscription_delayend_of_turn_delayon_user_turn_completed_delayllm_node_ttfttts_node_ttfbe2e_latencyr   llm_metadatatts_metadatastt_metadatar   Nr   r   r/   r-   r   r     sn    
 
 #('
 
 
 
 "!!!!!r/   r   c                      \ rS rSr% \" S S9rS\S'   SrS\S'   S	\S
'   S\S'   SrS\S'   Sr	S\S'   \" \
S9rS\S'   \" S S9rS\S'   \" \R                  S9rS\S'   \" SSS9rS\S'   \S S j5       rSrg)!ChatMessagei1  c                 .    [         R                  " S5      $ Nitem_r   r   r/   r-   r   ChatMessage.<lambda>2      EOOG,Dr/   r   r    r   messagezLiteral['message']r[   r   rolezlist[ChatContent]contentFboolinterruptedNzfloat | Nonetranscript_confidencer~   extrac                     [        5       $ r8   )r   r   r/   r-   r   r   9  s    =?r/   r   metricsr   
created_atzhash is deprecated)r   
deprecatedzbytes | Nonehashc                    U R                    Vs/ s H  n[        U[        5      (       d  M  UPM     nnU(       d  gSR                  U5      $ s  snf )zp
Returns a string of all text content in the message.

Multiple text content items will be joined by a newline.
N
)r   r:   r    join)r2   c
text_partss      r-   text_contentChatMessage.text_content=  s@     "&DAAs1Ca
Dyy$$ Es
   AAr   )r}   r"   )r   r   r   r   r   r   r   r[   r   r   rl   r   r   timer   r   r   r   r   r   r/   r-   r   r   1  s    $DEBE(D
(
NK*.<.!$7E>7"3JKG]Kdii8J8t8LMD,M	% 	%r/   r   ChatContentc                      \ rS rSr% \" S S9rS\S'   SrS\S'   S\S	'   S\S
'   S\S'   \" \R                  S9r	S\S'   \" \
S9rS\S'    SrS\S'   Srg)FunctionCalliM  c                 .    [         R                  " S5      $ r   r   r   r/   r-   r   FunctionCall.<lambda>N  r   r/   r   r    r   function_callzLiteral['function_call']r[   call_id	argumentsnamer   r   r~   r   Nr"   group_idr   )r   r   r   r   r   r   r   r[   r   r   rl   r   r   r   r   r/   r-   r   r   M  sc    $DEBE%4D
"4LN
Idii8J8!$7E>77HjTr/   r   c                      \ rS rSr% \" S S9rS\S'   \" SS9rS\S	'   \" S
S9rS\S'   S\S'   S\S'   S\S'   \" \	R                  S9r
S\S'   Srg)FunctionCallOutputi]  c                 .    [         R                  " S5      $ r   r   r   r/   r-   r   FunctionCallOutput.<lambda>^  r   r/   r   r    r   function_call_outputr   zLiteral['function_call_output']r[    r   r   outputr   is_errorr   r   r   N)r   r   r   r   r   r   r   r[   r   r   r   r   r   r/   r-   r   r   ]  sT    $DEBE,1:P,QD
)Qb!D#!LKNdii8J8r/   r   c                      \ rS rSr% \" S S9rS\S'   \" SS9rS\S	'   S
rS\S'   S\S'   \" \	R                  S9r
S\S'   Srg
)AgentHandoffig  c                 .    [         R                  " S5      $ r   r   r   r/   r-   r   AgentHandoff.<lambda>h  r   r/   r   r    r   agent_handoffr   zLiteral['agent_handoff']r[   Nr"   old_agent_idnew_agent_idr   r   r   )r   r   r   r   r   r   r   r[   r   r   r   r   r   r/   r-   r   r   g  sE    $DEBE%*?%CD
"C#L*#dii8J8r/   r   c                      \ rS rSr% \" S S9rS\S'   \" SS9rS\S	'   S
rS\S'   S
r	S\S'   S
r
S\S'   \" \R                  S9rS\S'   \" \S9rS\S'   Srg
)AgentConfigUpdateio  c                 .    [         R                  " S5      $ r   r   r   r/   r-   r   AgentConfigUpdate.<lambda>p  r   r/   r   r    r   agent_config_updater   zLiteral['agent_config_update']r[   NzInstructions | str | Nonerk   zlist[str] | Nonetools_addedtools_removedr   r   z
list[Tool]_toolsr   )r   r   r   r   r   r   r   r[   rk   r  r  r   r   r   listr  r   r   r/   r-   r   r   o  si    $DEBE+09N+OD
(O.2L+2$(K!(&*M#*dii8J8$T:FJ:Ar/   r   r[   )discriminatorc                     \ rS rSr\4S)S jjr\S*S j5       r\S+S j5       r	\	R                  S,S j5       r	S-S jr\\\\\S.               S.S jjrS/S	 jrS0S
 jrS1S jrSSSSS\S.             S2S jjrS3S jrSSSS.         S4S jjrSSSSSSS.             S5S jjr\SS.     S6S jj5       r\SSS.       S7S jj5       r\SS.     S8S jj5       r\SS.     S9S jj5       r\    S:S j5       r\S;S j5       rSS.       S<S jjrS=S jrSS .S>S! jjrS"S#.     S?S$ jjr\S@S% j5       r\SAS& j5       rSBS' jrS(rg)CChatContexti  c                @    [        U5      (       a  Xl        g / U l        g r8   )r   _itemsr2   rJ   s     r-   __init__ChatContext.__init__  s    /7eBr/   c                    U " / 5      $ r8   r   )r)   s    r-   emptyChatContext.empty  s    2wr/   c                    U R                   $ r8   r  r1   s    r-   rJ   ChatContext.items  s    {{r/   c                    Xl         g r8   r  r  s     r-   rJ   r    s    r/   c                t    U R                    Vs/ s H  n[        U[        5      (       d  M  UPM     sn$ s  snf )zNReturn only chat messages, ignoring function calls, outputs, and other events.)r  r:   r   )r2   items     r-   messagesChatContext.messages  s'    !%N
40MNNNs   55)r   r   r   r   r   c                  0 n[        U5      (       a  X8S'   [        U5      (       a  XHS'   [        U5      (       a  XXS'   [        U5      (       a  XhS'   [        U5      (       a  XxS'   [        U[        5      (       a  [        SX/S.UD6n	O[        SXS.UD6n	[        U5      (       a,  U R	                  US9n
U R
                  R                  X5        U	$ U R
                  R                  U	5        U	$ )	Nr   r   r   r   r   r   r   r   r   )r   r:   r    r   find_insertion_indexr  insertappend)r2   r   r   r   r   r   r   r   rM   r   idxs              r-   add_messageChatContext.add_message  s     "$B<<4LK  $/=!J#-< G '9E??#7Ogs##!ItYI&IG!GtGGGJ++z+BCKKs,  KKw'r/   c                    [        U[        5      (       a  [        U5      OU/nU H7  nU R                  UR                  S9nU R
                  R                  XC5        M9     g)zGInsert an item or list of items into the chat context by creation time.r  N)r:   r   r  r  r   r  r  )r2   r  rJ   _itemr   s        r-   r  ChatContext.insert  sP    (x88T
tfE++u7G7G+HCKKs* r/   c                D   ^ [        U4S jU R                   5       S 5      $ )Nc              3  J   >#    U  H  oR                   T:X  d  M  Uv   M     g 7fr8   r   )r<   r  item_ids     r-   r>   (ChatContext.get_by_id.<locals>.<genexpr>  s     GjdGGw4FTTjs   #	#)nextrJ   r2   r)  s    `r-   	get_by_idChatContext.get_by_id  s    GdjjGNNr/   c                V   ^ [        U4S j[        U R                  5       5       S 5      $ )Nc              3  P   >#    U  H  u  pUR                   T:X  d  M  Uv   M     g 7fr8   r(  )r<   ir  r)  s      r-   r>   *ChatContext.index_by_id.<locals>.<genexpr>  s"     R&;71tww'?QQQ&;s   &	&)r+  	enumeraterJ   r,  s    `r-   index_by_idChatContext.index_by_id  s     Ri

&;RTXYYr/   F)exclude_function_callexclude_instructionsexclude_empty_messageexclude_handoffexclude_config_updatetoolsc                 ^
^^^ / nSSK Jm
JmJm      SU
UUU4S jjmU(       a  [	        T" U5      5      O	[	        5       nU R
                   H  n	U(       a  U	R                  S;   a  M  U(       a"  U	R                  S:X  a  U	R                  S;   a  ME  U(       a#  U	R                  S:X  a  U	R                  (       d  Mo  U(       a  U	R                  S:X  a  M  U(       a  U	R                  S:X  a  M  [        U5      (       a2  U	R                  S	:X  d  U	R                  S
:X  a  U	R                  U;  a  M  UR                  U	5        M     [        U5      $ )Nr   )FunctionToolRawFunctionToolr   c              3    >#    U  Hx  n[        U[        5      (       a  Uv   M  [        UTT45      (       a  UR                  R                  v   MK  [        UT5      (       a  T" UR                  5       S h  vN   Mx  Mz     g  N7fr8   )r:   r    infor   r;  )r;  toolr=  r>  r   get_tool_namess     r-   rB  (ChatContext.copy.<locals>.get_tool_names  sm      dC((J|_&EFF))..(g..-djj999   :s   A4B7B8Br   r   r   r   r   r   r  r   r   )r;  zSequence[Tool | Toolset | str]r}   zGenerator[str, None, None])tool_contextr=  r>  r   setrJ   r[   r   r   r   r   r  r	  )r2   r6  r7  r8  r9  r:  r;  rJ   valid_toolsr  r=  r>  r   rB  s             @@@@r-   copyChatContext.copy  s    HH	1	'	 	 5:c./0suJJD$ 7 *  %II*II!88$i)?499#?$6K)K YY/1TYYBX5XII[0LL= @ 5!!r/   c                 ^ [        U R                  5      U::  a  U $ [        S U R                   5       S5      mU R                  U* S nU(       a@  US   R                  S;   a-  UR	                  S5        U(       a  US   R                  S;   a  M-  T(       a,  [        U4S jU 5       5      (       d  UR                  ST5        X R                  SS& U $ )zTruncate the chat context to the last N items in place.

Removes leading function calls to avoid partial function outputs.
Preserves the first instruction message (system/developer) by adding it back
to the beginning.
c              3  n   #    U  H+  nUR                   S :X  d  M  UR                  S;   d  M'  Uv   M-     g7f)r   rE  N)r[   r   )r<   r  s     r-   r>   'ChatContext.truncate.<locals>.<genexpr>  s7      'D99	) .2ii;R.R 's   55	5Nr   rD  c              3  T   >#    U  H  oR                   TR                   :H  v   M     g 7fr8   r(  )r<   r  rk   s     r-   r>   rM  $  s     #U94GG|$>9s   %()lenr  r+  r[   poprG   r  )r2   	max_items	new_itemsrk   s      @r-   truncateChatContext.truncate  s     t{{y(K KK
 
 KK
,	 IaL-- 2
 
 MM!	 IaL-- 2
 
 #U9#U U UQ-"Ar/   )r6  r7  r:  c                  U R                    Vs1 s H  oUR                  iM     nnUR                   H  nU(       a  UR                  S;   a  M  U(       a"  UR                  S:X  a  UR                  S;   a  ME  U(       a  UR                  S:X  a  M^  UR                  U;  d  Mp  U R                  UR                  S9nU R                   R                  Xu5        UR                  UR                  5        M     U $ s  snf )zkAdd messages from `other_chat_ctx` into this one, avoiding duplicates, and keep items sorted by created_at.rD  r   rE  r  r  )	r  r   rJ   r[   r   r  r   r  add)r2   other_chat_ctxr6  r7  r:  r  existing_idsr   s           r-   mergeChatContext.merge*  s     -1KK8KDK8"((D$ 7 *  %II*II!88$6K)Kwwl*//4??/K""3-  )) ), 1 9s   C7T)exclude_imageexclude_audioexclude_timestampr6  exclude_metricsr:  c                  / nU R                    H  nU(       a  UR                  S;   a  M  U(       a  UR                  S:X  a  M5  UR                  S:X  a  UR                  5       nU(       a9  UR                   V	s/ s H  n	[	        U	[
        5      (       a  M  U	PM     sn	Ul        U(       a9  UR                   V	s/ s H  n	[	        U	[        5      (       a  M  U	PM     sn	Ul        UR                  U5        M     [        5       n
U(       a  U
R                  S5        U(       a  U
R                  S5        SU Vs/ s H  nUR                  SSS	U
S
9PM     sn0$ s  sn	f s  sn	f s  snf )NrD  r  r   r   r   rJ   jsonTF)modeexclude_noneexclude_defaultsexclude)rJ   r[   
model_copyr   r:   r   r   r  rG  rV  
model_dump)r2   r[  r\  r]  r6  r^  r:  rJ   r  r   exclude_fieldss              r-   to_dictChatContext.to_dictM  s6    !#JJD$ 7 * $6K)KyyI%( /3||#_|!:aQ]C^A|#_DL /3||#_|!:aQ]C^A|#_DLLL# & $'5|,y)  " "D !%%**	    "

 
	
 $`#_s   9EE9EE8E")inject_dummy_user_messagec                   g r8   r   r2   rK   rj  s      r-   to_provider_formatChatContext.to_provider_format}  s     ,/r/   N)rj  thought_signaturesc                   g r8   r   )r2   rK   rj  ro  s       r-   rm  rn    s	     GJr/   c                   g r8   r   rl  s      r-   rm  rn    s	     EHr/   c                   g r8   r   rl  s      r-   rm  rn    s	     MPr/   c                    g r8   r   )r2   rK   s     r-   rm  rn    s	     KNr/   c                    g r8   r   )r2   rK   rM   s      r-   rm  rn    s    X[r/   c                  X#S'   US:X  a!  [         R                  R                  " U 40 UD6$ US:X  a!  [         R                  R                  " U 40 UD6$ US:X  a!  [         R                  R                  " U 40 UD6$ US:X  a!  [         R
                  R                  " U 40 UD6$ US:X  a!  [         R                  R                  " U 40 UD6$ US:X  a  [         R                  R                  U 5      $ [        SU 35      e)	a:  Convert the chat context to a provider-specific format.

If ``inject_dummy_user_message`` is ``True``, a dummy user message will be added
to the beginning or end of the chat context depending on the provider.

This is necessary because some providers expect a user message to be present for
generating a response.
rj  openaizopenai.responsesgoogleaws	anthropic	mistralaizUnsupported provider format: )
r   rv  to_chat_ctxto_responses_chat_ctxrw  rx  ry  rz  to_conversations_ctxrn   )r2   rK   rj  rM   s       r-   rm  rn    s      /H*+X#**66tFvFF))#**@@PPPx#**66tFvFFu_#''33DCFCC{"#--99$I&II{"#--BB4HH<VHEFFr/   c                   [        [        [        U R                  5      5      5       H'  nU R                  U   R                  U::  d  M"  US-   s  $    g)z
Returns the index to insert an item by creation time.

Iterates in reverse, assuming items are sorted by `created_at`.
Finds the position after the last item with `created_at <=` the given timestamp.
r   r   )reversedrangerO  r  r   )r2   r   r1  s      r-   r   ChatContext.find_insertion_index  sE     %DKK 012A{{1~((J61u 3 r/   )allow_type_mismatchc               T   U R                  UR                  5      nUbo  U(       dY  UR                  U R                  U   R                  :w  a2  [	        SUR                   SU R                  U   R                   35      eXR                  U'   gU R                  R                  U5        g)zBUpdate an item with the same ID if it exists, otherwise append it.NzItem type mismatch: z != )r4  r   r[   r  rn   r  )r2   r  r  r   s       r-   _upsert_itemChatContext._upsert_item  s    tww'?&499C8H8M8M+M #7		{$t{{SVGWG\G\F]!^__#KKKKt$r/   r   )keep_last_turnsc               X  #    US-  n[        U R                  5      nUS:  at  Sn[        [        U R                  5      S-
  SS5       HI  nU R                  U   n[        U[        5      (       d  M)  UR
                  S;   d  M;  US-  nXS:  d  MG  Un  O   U $ US:X  a  U $ U R                  S U U R                  US  p/ n
U H  n[        U[        5      (       aq  UR
                  S;  a  M*  UR                  R                  S5      SL a  MJ  UR                  =(       d    SR                  5       nU(       a  U
R                  U5        M  M  [        U[        [        45      (       d  M  U
R                  U5        M     U
(       d  U $ / nU
 H  n[        U[        [        45      (       a/  UR                  [        U5      R                  =(       d    S5        MM  UR                  [        UR
                  UR                  =(       d    SR                  5       5      5        M     S	R                  U5      R                  5       nU(       d  U $ [!        5       nUR#                  S
[$        R&                  " S5      S9  UR#                  SSU 3S9  / nUR)                  US9 IS h  vN nU  S h  vN nUR*                  (       d  M  UR*                  R,                  (       d  M9  UR                  UR*                  R,                  5        M`   Nf N]
 S S S 5      IS h  vN    O! , IS h  vN  (       d  f       O= fSR                  U5      R                  5       nU(       d  U $ / nU HX  n[        U[        5      (       a  UR
                  S;   a  M*  [        U[        [        45      (       a  MG  UR                  U5        MZ     UU l        U	(       a  U	S   R0                  S-
  OUS   R0                  S-   nU R#                  S[        SU5      USS0S9  U R.                  R3                  U	5        U $ 7f)Nr   r   r   )r   r   
is_summaryTr   r   r   u3                  Compress older conversation history into a short, faithful summary.

                The conversation is formatted as XML. Here is how to read it:
                - <user>…</user>  — something the user said.
                - <assistant>…</assistant>  — something the assistant said.
                - <function_call name="…" call_id="…">…</function_call>  — the assistant invoked an action.
                - <function_call_output name="…" call_id="…">…</function_call_output>  — the result of that                 action. May contain <error>…</error> if it failed.

                Guidelines:
                - Distill the *information learned* from function call outputs into the summary.                 Do not mention that a tool/function was called — just preserve the knowledge gained.
                - Focus on: user goals, constraints, decisions, key facts, preferences, entities,                 and any pending or unresolved tasks.
                - Omit greetings, filler, and chit-chat.
                - Be concise.r  r   zConversation to summarize:

)chat_ctxgư>r   chat_history_summaryr   r   r   r   )rO  rJ   r  r:   r   r   r   rm   r   stripr  r   r   _function_call_item_to_messageto_xmlr   r	  r!  textwrapdedentchatdeltar   r  r   extend)r2   llm_vr  
msg_budget	split_idx	msg_countr1  r  
head_items
tail_itemsto_summarizer$   contentsmsource_textr  chunksstreamchunksummary	preserveditcreated_at_hints                          r-   
_summarizeChatContext._summarize  s     %q(


O	>I3tzz?Q.B7zz!}dK00TYYBW5WNI .$%	 8 >K!%JY!7IJ9OJ OQD$,,99$99::>>,/47))/R668 ''- D<1C"DEE##D)  K !A!l,>?@@ >q A N N TRTUqvv0D"/K/K/M NO	  ii)//1K=OO %! " 	 	
( 	4[MB 	 	

 ::x:00F% 7e;;;5;;#6#6#6MM%++"5"56 17v 100000
 ''&/'')K %'	B"k**rww:O/O"|-?@AAR     2<Z]%%,*R.B[B[^bBb 	 	17;&&	 	 	
 	:&s   A+P*1P*P*CP*&D7P*LP*!L$L(L)L,L L'LP*LL	P*LP*L2!L$"L2.C<P*c                f    [        [        [           5      nUR                  US   5      nU " U5      $ )NrJ   )r   r  ChatItemrp   )r)   dataitem_adapterrJ   s       r-   	from_dictChatContext.from_dictW  s.    "4>2,,T'];5zr/   c                    g)NFr   r1   s    r-   readonlyChatContext.readonly]  s    r/   c                   XL a  g[        U R                  5      [        UR                  5      :w  a  g[        U R                  UR                  SS9 GH  u  p#UR                  UR                  :w  d  UR                  UR                  :w  a    gUR                  S:X  ab  UR                  S:X  aR  UR
                  UR
                  :w  d4  UR                  UR                  :w  d  UR                  UR                  :w  a    gM  UR                  S:X  ac  UR                  S:X  aS  UR                  UR                  :w  d4  UR                  UR                  :w  d  UR                  UR                  :w  a    gGM!  UR                  S:X  d  GM4  UR                  S:X  d  GMG  UR                  UR                  :w  dQ  UR                  UR                  :w  d7  UR                  UR                  :w  d  UR                  UR                  :w  d  GM    g   g)a  
Return True if `other` has the same sequence of items with matching
essential fields (IDs, types, and payload) as this context.

Comparison rules:
  - Messages: compares the full `content` list, `role` and `interrupted`.
  - Function calls: compares `name`, `call_id`, and `arguments`.
  - Function call outputs: compares `name`, `call_id`, `output`, and `is_error`.

Does not consider timestamps or other metadata.
TF)strictr   r   r   )rO  rJ   zipr   r[   r   r   r   r   r   r   r   r   )r2   r\   abs       r-   is_equivalentChatContext.is_equivalenta  so    =tzz?c%++..

EKK>DAttqtt|qvv/vv"qvv':66QVV#q}}'EVWV_V_I_  J` ?*qvv/H66QVV#qyyAII'=PQP[P[A[  B\ 11aff@V6VFFaff$yyAII-xx188+zzQZZ/ ' ?* r/   r  )rJ   zNotGivenOr[list[ChatItem]])r}   r	  r}   list[ChatItem])rJ   r  r}   None)r}   zlist[ChatMessage])r   r   r   zlist[ChatContent] | strr   zNotGivenOr[str]r   zNotGivenOr[bool]r   zNotGivenOr[float]r   zNotGivenOr[MetricsReport]r   zNotGivenOr[dict[str, Any]]r}   r   )r  zChatItem | Sequence[ChatItem]r}   r  )r)  r    r}   zChatItem | None)r)  r    r}   r   )r6  r   r7  r   r8  r   r9  r   r:  r   r;  z*NotGivenOr[Sequence[Tool | Toolset | str]]r}   r	  )rQ  intr}   r	  )
rW  r	  r6  r   r7  r   r:  r   r}   r	  )r[  r   r\  r   r]  r   r6  r   r^  r   r:  r   r}   r~   )rK   z%Literal['openai', 'openai.responses']rj  r   r}   z tuple[list[dict], Literal[None]])rK   zLiteral['google']rj  r   ro  zdict[str, bytes] | Noner}   z;tuple[list[dict], _provider_format.google.GoogleFormatData])rK   zLiteral['aws']rj  r   r}   z9tuple[list[dict], _provider_format.aws.BedrockFormatData])rK   zLiteral['anthropic']rj  r   r}   zAtuple[list[dict], _provider_format.anthropic.AnthropicFormatData])rK   zLiteral['mistralai']r}   z?tuple[list[dict], _provider_format.mistralai.MistralFormatData])rK   r    rM   r   r}   tuple[list[dict], Any])rK   zVLiteral['openai', 'openai.responses', 'google', 'aws', 'anthropic', 'mistralai'] | strrj  r   rM   r   r}   r  )r   r   r}   r  )r  r  r  r   r}   r  )r  r   r  r  r}   r	  )r  r~   r}   r	  r}   r   )r\   r	  r}   r   )r   r   r   r   r   r  r   r  r   rJ   setterr  r!  r  r-  r4  rI  rS  rY  rh  r   rm  r  r  r  r  r  r  r   r   r/   r-   r	  r	    s   ;D G     \\ O ((1(1-6,5! ! )	!
 ! &! &! +! *! 
!F+OZ ',%*&+ %&+<E="  $=" #	="
  $=" ="  $=" :=" 
="~!N ',%*&+!#!  $	!
 #!  $! 
!L #""&&+ %&+.
 .
 	.

  .
  $.
 .
  $.
 
.
` 
 +/	/5/ $(	/
 
*/ / 
 +/6:J!J $(	J
 4J 
EJ J KOH$HDHH	BH H QUP*PJNP	JP P N*N	HN N [ [ +/GG
 $(G G 
 GB KP %  !	}} 	}
 
}~  
  'r/   r	  c                  V    \ rS rSrSrSr " S S\\   5      rS
S jr	\
SS j5       rSrg	)_ReadOnlyChatContexti  z@A read-only wrapper for ChatContext that prevents modifications.zttrying to modify a read-only chat context, please use .copy() and agent.update_chat_ctx() to modify the chat contextc                  T    \ rS rSrSS jr\=r=r=r=r=r	=r
r\=r=r=rrSS jrSrg)#_ReadOnlyChatContext._ImmutableListi  c                |    [         R                  " [        R                  5        [	        [        R                  5      er8   )r   errorr  	error_msgRuntimeError)r2   rL   rM   s      r-   _raise_error0_ReadOnlyChatContext._ImmutableList._raise_error  s'    LL-7783==>>r/   c                    [        U 5      $ r8   )r  r1   s    r-   rI  (_ReadOnlyChatContext._ImmutableList.copy  s    :r/   r   N)rL   r   rM   r   r}   r  r  )r   r   r   r   r  r  r  rP  removeclearsortreverse__setitem____delitem____iadd____imul__rI  r   r   r/   r-   _ImmutableListr    sG    	?
 CONNN#NNN:FFFkFHx	r/   r  c                0    U R                  U5      U l        g r8   )r  r  r  s     r-   r  _ReadOnlyChatContext.__init__  s    ))%0r/   c                    g)NTr   r1   s    r-   r  _ReadOnlyChatContext.readonly  s    r/   r  N)rJ   r  r  )r   r   r   r   r   r  r  r  r  r  r   r  r   r   r/   r-   r  r    s9    J	T 

h 
1  r/   r  c           
         U (       a:  SR                  U R                  5        VVs/ s H  u  pU SU S3PM     snn5      $ g s  snnf )N z="")r   rJ   )attrsrQ   rB   s      r-   _to_attrs_strr    s@    xx%++-@-$!A3b1-@AA As   A
c                    [        U5      nU(       a,  SR                  U(       a	  SU  SU S3OSU  S3USU  S3/5      $ U(       a	  SU  SU S3$ SU  S3$ )Nr   <r  >z</z />)r  r   )tag_namer   r  	attrs_strs       r-   r  r    s{    
 e$Iyy/8!H:Qyk+(1oXJa 
 	
 1:8*Ai[,P8*C?PPr/   c           
        [        U [        5      (       aC  [        S[        SU R                  U R
                  U R                  S.S9/U R                  SS0S9$ [        U [        5      (       aj  [        S[        S	U R                  (       d  U R                  O[        S
U R                  5      U R                  U R
                  S.S9/U R                  SS0S9$ g )Nr   r   )r   r   )r  is_function_callTr  r   r   r  )r   r   is_function_call_output)r:   r   r   r  r   r   r   r   r   r   r   )r  s    r-   r  r    s    $%%#NN $		#'<<	 %t,
 	
 
D,	-	-*'+}}DKK&$++:V#'<< $			 ,d3
 	
 
.r/   r8   )r  dict[str, Any] | Noner}   r"   )NN)r  r    r   r"   r  r  r}   r    )r  z!FunctionCall | FunctionCallOutputr}   r   )9
__future__r   r  r   collections.abcr   r   typingr   r   r   r	   r
   r   pydanticr   r   r   r   typing_extensionsr   livekitr   r   r   logr   typesr   r   
utils.miscr   r   llmr   r   r   r    r   r   r   r   r   r   r   r   r   r   r   r   r   r  r	  r  r  r  r  r   r/   r-   <module>r     sz   #   / N N ? ? '    ) ! ((M
3 M
`<?9 <?~"9 " HI) I
iu 
*"IU *"Z%) %2 &4|CcIY IT9 T 9 999 9B	 B ,!33lBEVV	!E EP; 8 #'QQQ !Q 		Q& 
r/   