§
    ÚŽ’j™&  ã                   óB  — U d Z ddlZddlmZmZmZ ddlmZ ddlm	Z	m
Z
 ddlmZ dd	lmZ dd
lmZmZmZmZmZmZ  G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Zeez  ez  ez  Zeed<    G d„ d¦  «        ZdS )z(Internal utilities for the model module.é    N)ÚAnyÚSelfÚ	TypeAlias)ÚFieldé   )ÚChatResponseÚFinishedReason)Ú	ChatUsageé   )Úlogger)ÚBase64SourceÚ	DataBlockÚ	TextBlockÚThinkingBlockÚToolCallBlockÚ	URLSourcec                   ó^   — e Zd ZU dZ ee¬¦  «        Zee         ed<   de	ddfd„Z
de	fd„ZdS )	Ú_AccTextBlockz‹The accumulating counterpart of ``TextBlock``, whose ``text`` field
    holds the incremental fragments until they are joined in ``build``.©Údefault_factoryÚtextÚblockÚreturnNc                 óD   — | j                              |j         ¦  «         dS )zŽCollect one delta block in constant time.

        Args:
            block (`TextBlock`):
                The delta block to collect.
        N)r   Úappend©Úselfr   s     úEC:\Projects\DSCons\.venv\Lib\site-packages\agentscope\model\_utils.pyr   z_AccTextBlock.append   s"   € ð 	Œ	×Ò˜œÑ$Ô$Ð$Ð$Ð$ó    c           	      óz   — t          di i |                      ¦   «         ¥dd                     | j        ¦  «        i¥¤ŽS )z.Join the fragments into a plain ``TextBlock``.r   Ú © )r   Ú
model_dumpÚjoinr   ©r   s    r   Úbuildz_AccTextBlock.build&   s>   € åÐMÐMÐL˜dŸošoÑ/Ô/ÐL°¸¿ºÀÄÑ9KÔ9KÐLÐLÐMÐMÐMr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úlistr   ÚstrÚ__annotations__r   r   r&   r"   r   r   r   r      s–   € € € € € € ðKð Kð �eØðñ ô €Dˆ$ˆsŒ)ð ð ñ ð%˜Ið %¨$ð %ð %ð %ð %ðN�yð Nð Nð Nð Nð Nð Nr   r   c                   ó^   — e Zd ZU dZ ee¬¦  «        Zee         ed<   de	ddfd„Z
de	fd„ZdS )	Ú_AccThinkingBlockz—The accumulating counterpart of ``ThinkingBlock``, whose ``thinking``
    field holds the incremental fragments until they are joined in
    ``build``.r   Úthinkingr   r   Nc                 ó¬   — | j                              |j         ¦  «         |j        pi                      ¦   «         D ]\  }}|�t	          | ||¦  «         ŒdS )z’Collect one delta block in constant time.

        Args:
            block (`ThinkingBlock`):
                The delta block to collect.
        N)r0   r   Úmodel_extraÚitemsÚsetattr)r   r   ÚkeyÚvalues       r   r   z_AccThinkingBlock.append4   sh   € ð 	Œ×Ò˜Uœ^Ñ,Ô,Ð,ð !Ô,Ð2°×9Ò9Ñ;Ô;ð 	*ð 	*‰JˆC�ØÐ Ý˜˜c 5Ñ)Ô)Ð)øð	*ð 	*r   c           	      óz   — t          di i |                      ¦   «         ¥dd                     | j        ¦  «        i¥¤ŽS )z2Join the fragments into a plain ``ThinkingBlock``.r0   r!   r"   )r   r#   r$   r0   r%   s    r   r&   z_AccThinkingBlock.buildB   sH   € åð 
ð 
ØG�—’Ñ"Ô"ÐG J°·²¸¼Ñ0FÔ0FÐGÐGð
ð 
ð 	
r   )r'   r(   r)   r*   r   r+   r0   r,   r-   r   r   r&   r"   r   r   r/   r/   +   s�   € € € € € € ðð ð  ˜%Øðñ ô €Hˆd�3Œið ð ñ ð*˜Mð *¨dð *ð *ð *ð *ð
�}ð 
ð 
ð 
ð 
ð 
ð 
r   r/   c                   ó^   — e Zd ZU dZ ee¬¦  «        Zee         ed<   de	ddfd„Z
de	fd„ZdS )	Ú_AccToolCallBlockz™The accumulating counterpart of ``ToolCallBlock``, whose ``input``
    field holds the incremental JSON fragments until they are joined in
    ``build``.r   Úinputr   r   Nc                 ó€   — | j                              |j         ¦  «         | j        s|j        r|j        | _        dS dS dS )z’Collect one delta block in constant time.

        Args:
            block (`ToolCallBlock`):
                The delta block to collect.
        N)r:   r   Únamer   s     r   r   z_AccToolCallBlock.appendR   sR   € ð 	Œ
×Ò˜%œ+Ñ&Ô&Ð&ð Œyð 	#˜UœZð 	#Øœ
ˆDŒIˆIˆIð	#ð 	#ð 	#ð 	#r   c           	      óz   — t          di i |                      ¦   «         ¥dd                     | j        ¦  «        i¥¤ŽS )z2Join the fragments into a plain ``ToolCallBlock``.r:   r!   r"   )r   r#   r$   r:   r%   s    r   r&   z_AccToolCallBlock.build_   sH   € åð 
ð 
ØA�—’Ñ"Ô"ÐA G¨R¯WªW°T´ZÑ-@Ô-@ÐAÐAð
ð 
ð 	
r   )r'   r(   r)   r*   r   r+   r:   r,   r-   r   r   r&   r"   r   r   r9   r9   I   s�   € € € € € € ðð ð �uØðñ ô €Eˆ4�Œ9ð ð ñ ð#˜Mð #¨dð #ð #ð #ð #ð
�}ð 
ð 
ð 
ð 
ð 
ð 
r   r9   c                   ó^   — e Zd ZU dZ ee¬¦  «        Zee         ed<   de	ddfd„Z
de	fd„ZdS )	Ú_AccBase64Sourcea¬  The accumulating counterpart of ``Base64Source`` for audio streams,
    whose ``data`` field holds the raw decoded bytes of each delta.

    Base64 strings cannot be concatenated directly: a delta whose byte
    length is not a multiple of three is padded with ``=``, and everything
    after that padding is silently dropped on decoding. So each delta is
    decoded on arrival and the bytes are encoded once in ``build``.
    r   ÚdataÚsourcer   Nc                 óz   — |j         r3| j                              t          j        |j         ¦  «        ¦  «         dS dS )zœDecode one delta source and collect its raw bytes.

        Args:
            source (`Base64Source`):
                The delta source to collect.
        N)r@   r   Úbase64Ú	b64decode©r   rA   s     r   r   z_AccBase64Source.appendt   sA   € ð Œ;ð 	<ØŒI×Ò�VÔ-¨f¬kÑ:Ô:Ñ;Ô;Ð;Ð;Ð;ð	<ð 	<r   c                 ó¨   — t          t          j        d                     | j        ¦  «        ¦  «                             d¦  «        | j        ¬¦  «        S )z/Join the raw bytes and base64-encode them once.r   Úascii©r@   Ú
media_type)r   rC   Ú	b64encoder$   r@   ÚdecoderI   r%   s    r   r&   z_AccBase64Source.build~   sH   € åÝÔ! #§(¢(¨4¬9Ñ"5Ô"5Ñ6Ô6×=Ò=¸gÑFÔFØ”ð
ñ 
ô 
ð 	
r   )r'   r(   r)   r*   r   r+   r@   Úbytesr-   r   r   r&   r"   r   r   r?   r?   f   s�   € € € € € € ðð ð ˜Øðñ ô €Dˆ$ˆuŒ+ð ð ñ ð<˜\ð <¨dð <ð <ð <ð <ð
�|ð 
ð 
ð 
ð 
ð 
ð 
r   r?   c                   óF   — e Zd ZU dZeez  ez  ed<   deddfd„Z	defd„Z
dS )Ú_AccDataBlockzôThe accumulating counterpart of ``DataBlock``.

    Only ``audio/*`` is a streamable delta whose concatenation is
    well-defined. Other media types and URL sources are standalone assets,
    so the latest delta replaces the previous one.
    rA   r   r   Nc                 óÔ  — |j         �|j         | _         |j        }t          | j        t          ¦  «        rFt          |t          ¦  «        r1|j        | j        j        k    r| j                             |¦  «         dS t          |t          ¦  «        rQ|j                             d¦  «        r7t          g |j        ¬¦  «        | _        | j                             |¦  «         dS || _        dS )zŽCollect one delta block in constant time.

        Args:
            block (`DataBlock`):
                The delta block to collect.
        Nzaudio/rH   )r<   rA   Ú
isinstancer?   r   rI   r   Ú
startswith)r   r   rA   s      r   r   z_AccDataBlock.append’   sï   € ð Œ:Ð!Øœ
ˆDŒIà”ˆå�t”{Õ$4Ñ5Ô5ð	!å˜6¥<Ñ0Ô0ð	!ð Ô! T¤[Ô%;Ò;Ð;àŒK×Ò˜vÑ&Ô&Ð&Ð&Ð&å˜¥Ñ-Ô-ð 	!°&Ô2C×2NÒ2NØñ3
ô 3
ð 	!õ
 +ØØ!Ô,ðñ ô ˆDŒKð ŒK×Ò˜vÑ&Ô&Ð&Ð&Ð&ð !ˆDŒKˆKˆKr   c           
      óª   — | j         }t          di i |                      ¦   «         ¥dt          |t          ¦  «        r|                     ¦   «         n|i¥¤ŽS )z.Join the fragments into a plain ``DataBlock``.rA   r"   )rA   r   r#   rP   r?   r&   rE   s     r   r&   z_AccDataBlock.build³   sk   € à”ˆÝð 	
ð 	
ðØ—/’/Ñ#Ô#ðàå! &Õ*:Ñ;Ô;ð �F—L’L‘N”N�Nàðð ð	
ð 	
ð 		
r   )r'   r(   r)   r*   r?   r   r   r-   r   r   r&   r"   r   r   rN   rN   †   s|   € € € € € € ðð ð 	˜<Ñ'¨)Ñ3ðð ñ ð!˜Ið !¨$ð !ð !ð !ð !ðB
�yð 
ð 
ð 
ð 
ð 
ð 
r   rN   Ú	_AccBlockc                   ó6   — e Zd ZdZdd„Zdedefd„Zdefd„ZdS )	Ú_StreamAccumulatoraô  Accumulates the streaming ``ChatResponse`` deltas of one model call.

    Each block keeps its deltas in a fragment list that is joined exactly
    once in ``build``, which makes the accumulation O(n) in the total
    payload size. The ``ChatResponse.append_chat_response`` it replaces
    grows the blocks with ``block.field += delta`` instead, which is
    O(n^2) for large payloads (e.g. tool call arguments of 100k+ chars)
    and can block the event loop long enough to drop the connection.
    r   Nc                 óV   — i | _         d| _        	 d| _        	 t          j        | _        dS )z Initialize an empty accumulator.N)Ú_blocksÚidÚusager	   Ú	COMPLETEDÚfinished_reasonr%   s    r   Ú__init__z_StreamAccumulator.__init__Ò   s0   € ð .0ˆŒà"ˆŒØ1à'+ˆŒ
ØFå/=Ô/GˆÔØ9Ð9r   Úchat_responsec                 ór  — |j         D �]}| j                             |j        ¦  «        }|�8|j        |j        k    r(t          j        d|j        |j        |j        ¦  «         d}|€§|                     ¦   «         }t          |t          ¦  «        rt          di i |¥dg i¥¤Ž}n\t          |t          ¦  «        rt          di i |¥dg i¥¤Ž}n4t          |t          ¦  «        rt          di i |¥dg i¥¤Ž}nt          di |¤Ž}|| j        |j        <   |                     |¦  «         �Œ|j        r|j        | _        | S )z­Collect one delta chunk in constant time per block.

        Args:
            chat_response (`ChatResponse`):
                The streaming delta chunk to collect.
        Nz]Block %s changed its type from %s to %s during streaming, dropping the accumulated fragments.r   r0   r:   r"   )ÚcontentrW   ÚgetrX   Útyper   Úwarningr#   rP   r   r   r   r/   r   r9   rN   r   rY   )r   r]   r   ÚaccÚfieldss        r   Úappend_chat_responsez'_StreamAccumulator.append_chat_responseà   s�  € ð #Ô*ð 	ñ 	ˆEØ”,×"Ò" 5¤8Ñ,Ô,ˆCØˆ 3¤8¨u¬zÒ#9Ð#9Ý”ðEà”HØ”HØ”Jñô ð ð �àˆ{ð ×)Ò)Ñ+Ô+�Ý˜e¥YÑ/Ô/ð 	2Ý'ÐAÐAÐ*@¨VÐ*@°V¸RÐ*@Ð*@ÐAÐA�C�CÝ ¥}Ñ5Ô5ð 2Ý+ÐIÐIÐ.H°Ð.H¸ÀRÐ.HÐ.HÐIÐI�C�CÝ ¥}Ñ5Ô5ð 2Ý+ÐFÐFÐ.E°Ð.E¸À"Ð.EÐ.EÐFÐF�C�Cõ (Ð1Ð1¨&Ð1Ð1�CØ),�”˜UœXÑ&ð �JŠJ�uÑÔÐÑàÔð 	-Ø&Ô,ˆDŒJàˆr   c                 ó    — i }| j         �
| j         |d<   t          dd„ | j                             ¦   «         D ¦   «         d| j        | j        dœ|¤ŽS )z8Join the fragments of every block into a final response.NrX   c                 ó6   — g | ]}|                      ¦   «         ‘ŒS r"   )r&   )Ú.0Ú_s     r   ú
<listcomp>z,_StreamAccumulator.build.<locals>.<listcomp>  s    € Ð>Ð>Ð> 1�Q—W’W‘Y”YÐ>Ð>Ð>r   T)r_   Úis_lastrY   r[   r"   )rX   r   rW   ÚvaluesrY   r[   )r   Úkwargss     r   r&   z_StreamAccumulator.build  sm   € à!#ˆØŒ7ÐØœ7ˆF�4‰Låð 
Ø>Ð>¨¬×(;Ò(;Ñ(=Ô(=Ð>Ñ>Ô>ØØ”*Ø Ô0ð	
ð 
ð
 ð
ð 
ð 	
r   )r   N)	r'   r(   r)   r*   r\   r   r   re   r&   r"   r   r   rU   rU   Ç   sp   € € € € € ðð ð:ð :ð :ð :ð*°,ð *À4ð *ð *ð *ð *ðX
�|ð 
ð 
ð 
ð 
ð 
ð 
r   rU   )r*   rC   Útypingr   r   r   Úpydanticr   Ú_model_responser   r	   Ú_model_usager
   Ú_loggingr   Úmessager   r   r   r   r   r   r   r/   r9   r?   rN   rS   r-   rU   r"   r   r   ú<module>rt      s  ðà .Ð .Ð .Ø €€€Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'à Ð Ð Ð Ð Ð à 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ø #Ð #Ð #Ð #Ð #Ð #Ø Ð Ð Ð Ð Ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ðNð Nð Nð Nð N�Iñ Nô Nð Nð,
ð 
ð 
ð 
ð 
˜ñ 
ô 
ð 
ð<
ð 
ð 
ð 
ð 
˜ñ 
ô 
ð 
ð:
ð 
ð 
ð 
ð 
�|ñ 
ô 
ð 
ð@9
ð 9
ð 9
ð 9
ð 9
�Iñ 9
ô 9
ð 9
ðz Ð%Ñ%Ð(9Ñ9¸MÑIð 
ˆ9ð ð ñ ð
Q
ð Q
ð Q
ð Q
ð Q
ñ Q
ô Q
ð Q
ð Q
ð Q
r   