§
    ÚŽ’jÛ>  ã                   óì   — d Z ddlZddlZddlmZ ddlmZ ddlZddlm	Z	 ddl
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mZmZmZ  G d„ dee¦  «        Z G d„ de¦  «        Z G d„ de¦  «        ZdS )z*Google Gemini API formatter in agentscope.é    N)ÚABC)ÚAny)ÚFieldé   )ÚFormatterBaseé   )Úlogger)Ú_json_loads_with_repair)	ÚMsgÚ	TextBlockÚThinkingBlockÚ	HintBlockÚ	DataBlockÚToolCallBlockÚToolResultBlockÚ	URLSourceÚBase64Sourcec                   ón   — e Zd ZdZdedeeef         dz  fd„Ze	de
ez  deeef         fd„¦   «         ZdS )Ú_GeminiFormatterBasezSBase class for Gemini formatters, providing shared data block
    formatting logic.ÚblockÚreturnNc                 ó¸   ‡— |j         }|j        Št          ˆfd„| j        D ¦   «         ¦  «        st	          j        d‰¦  «         dS |                      |¦  «        S )aK  Format a DataBlock into Gemini API format.

        Args:
            block (`DataBlock`):
                The data block to format.

        Returns:
            `dict[str, Any] | None`:
                The formatted data block in Gemini ``inline_data`` format,
                or None if the media type is not supported.
        c              3   óB   •K  — | ]}t          j         ‰|¦  «        V — Œd S )N)Úfnmatch)Ú.0ÚpatternÚ
media_types     €úTC:\Projects\DSCons\.venv\Lib\site-packages\agentscope\formatter\_gemini_formatter.pyú	<genexpr>zA_GeminiFormatterBase._format_gemini_data_block.<locals>.<genexpr>2   sC   øè è € ð 
ð 
àõ ŒO˜J¨Ñ0Ô0ð
ð 
ð 
ð 
ð 
ð 
ó    z(Media type %s is not supported, skipped.N)Úsourcer   ÚanyÚsupported_input_media_typesr	   ÚwarningÚ_format_media_source)Úselfr   r!   r   s      @r   Ú_format_gemini_data_blockz._GeminiFormatterBase._format_gemini_data_block   sˆ   ø€ ð ”ˆØÔ&ˆ
õ ð 
ð 
ð 
ð 
àÔ;ð
ñ 
ô 
ñ 
ô 
ð 	õ ŒNØ:Øñô ð ð �4à×(Ò(¨Ñ0Ô0Ð0r    r!   c                 óÒ  — t          | t          ¦  «        rd| j        | j        dœiS t          | t          ¦  «        �rt          | j        ¦  «        }|                     d¦  «        r‚|                     d¦  «        }t          |d¦  «        5 }t          j        |                     ¦   «         ¦  «                             d¦  «        }ddd¦  «         n# 1 swxY w Y   d|| j        dœiS t          j        |d¬¦  «        }|                     ¦   «          t          j        |j        ¦  «                             d¦  «        }d|| j        dœiS t%          d	t'          | ¦  «        › �¦  «        ‚)
a  Format a media source into Gemini API ``inline_data`` format.

        Args:
            source (`URLSource | Base64Source`):
                The media source to format.

        Returns:
            `dict[str, Any]`:
                The formatted media source.
        Úinline_data)ÚdataÚ	mime_typezfile://Úrbzutf-8Né   )ÚtimeoutzUnsupported source type: )Ú
isinstancer   r*   r   r   ÚstrÚurlÚ
startswithÚremoveprefixÚopenÚbase64Ú	b64encodeÚreadÚdecodeÚrequestsÚgetÚraise_for_statusÚcontentÚ
ValueErrorÚtype)r!   r1   Ú	file_pathÚfr*   Úresponses         r   r%   z)_GeminiFormatterBase._format_media_source>   sÄ  € õ �f�lÑ+Ô+ð  	IàØ"œKØ!'Ô!2ð ð  ðð õ ˜¥	Ñ*Ô*ñ 	IÝ�f”j‘/”/ˆCØ�~Š~˜iÑ(Ô(ð à×,Ò,¨YÑ7Ô7�	Ý˜) TÑ*Ô*ð F¨aÝ!Ô+¨A¯FªF©H¬HÑ5Ô5×<Ò<¸WÑEÔE�DðFð Fð Fñ Fô Fð Fð Fð Fð Fð Fð Føøøð Fð Fð Fð Fð "Ø $Ø%+Ô%6ð$ð $ðð õ $œ<¨°RÐ8Ñ8Ô8�Ø×)Ò)Ñ+Ô+Ð+ÝÔ'¨Ô(8Ñ9Ô9×@Ò@ÀÑIÔI�à!Ø $Ø%+Ô%6ð$ð $ðð õ ÐG½¸f¹¼ÐGÐGÑHÔHÐHs   Â:CÃCÃC)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Údictr0   r   r'   Ústaticmethodr   r   r%   © r    r   r   r      s–   € € € € € ðð ð1àð1ð 
ˆc�3ˆhŒ˜$Ñ	ð1ð 1ð 1ð 1ð> ð-IØ˜LÑ(ð-Ià	ˆc�3ˆhŒð-Ið -Ið -Iñ „\ð-Ið -Ið -Ir    r   c                   ó~   — e Zd ZU dZ ed„ d¬¦  «        Zee         ed<   dee	         dee
eef                  fd„Zd	S )
ÚGeminiChatFormatterz¶The Gemini formatter class for chatbot scenario, where only a user
    and an agent are involved. We use the `role` field to identify different
    entities in the conversation.
    c                  ó
   — g d¢S ©N)z
text/plainzimage/*zaudio/*zvideo/*rH   rH   r    r   ú<lambda>zGeminiChatFormatter.<lambda>v   ó   € ð !
ð !
ð !
€ r    ú[The supported input types. Defaults to ``["text/plain", "image/*", "audio/*", "video/*"]``.©Údefault_factoryÚdescriptionÚinput_typesÚmsgsr   c           	   ƒ   óà  K  — |                       |¦  «         g }d}|t          |¦  «        k     �r¾||         }g }|                     ¦   «         D �]\}t          |t          ¦  «        r|                     d|j        i¦  «         Œ5t          |t          ¦  «        r%|j        r|                     d|j        dœ¦  «         Œot          |t          ¦  «        �r|r)|j
        dk    rdnd}|                     ||dœ¦  «         g }t          |j        t          ¦  «        r!|                     dd|j        igdœ¦  «         Œëg }|j        D ]u}	t          |	t          ¦  «        r|                     d|	j        i¦  «         Œ4t          |	t          ¦  «        r,|                      |	¦  «        }
|
r|                     |
¦  «         Œv|r|                     d|dœ¦  «         �Œ†t          |t          ¦  «        r.|                      |¦  «        }|r|                     |¦  «         �ŒÉt          |t          ¦  «        r;|                     d	|j        |j        t%          |j        pd
¦  «        dœi¦  «         �Œt          |t(          ¦  «        �r|r)|j
        dk    rdnd}|                     ||dœ¦  «         g }|                      |j        ¦  «        \  }}|                     dd|j        |j        d|idœigdœ¦  «         |r”g }|D ]u}t          |t          ¦  «        r|                     d|j        i¦  «         Œ4t          |t          ¦  «        r,|                      |¦  «        }|�|                     |¦  «         Œv|r|                     d|dœ¦  «         �Œ:t/          j        dt3          |¦  «        ¦  «         �Œ^|j
        dk    rdnd}|r|                     ||dœ¦  «         |dz  }|t          |¦  «        k     �°¾|S )a  Format message objects into Gemini API required format.

        Args:
            msgs (`list[Msg]`):
                The list of message objects to format.

        Returns:
            `list[dict[str, Any]]`:
                The formatted messages as a list of dictionaries.
        r   ÚtextT)ÚthoughtrV   Ú	assistantÚmodelÚuser©ÚroleÚpartsÚfunction_callz{})ÚidÚnameÚargsÚfunction_responseÚoutput)r_   r`   rA   Nz2Unsupported block type %s in the message, skipped.r   )Úassert_list_of_msgsÚlenÚget_content_blocksr/   r   ÚappendrV   r   Úthinkingr   r\   Úhintr0   r   r'   r   r_   r`   r
   Úinputr   Úconvert_tool_result_to_stringrc   r	   r$   r>   )r&   rT   ÚmessagesÚiÚmsgr]   r   r\   Ú
hint_partsÚsubÚformatted_subÚ	formattedÚtextual_outputÚmultimodal_dataÚpromo_partsÚitemÚfmt_items                    r   ÚformatzGeminiChatFormatter.format‚   sé  è è € ð 	× Ò  Ñ&Ô&Ð&à!ˆØˆØ•#�d‘)”)Šm‰mØ�q”'ˆCØˆEà×/Ò/Ñ1Ô1ð tñ t�Ý˜e¥YÑ/Ô/ð sØ—L’L &¨%¬*Ð!5Ñ6Ô6Ð6Ð6å ¥}Ñ5Ô5ð pð ”~ð ØŸšØ(,°e´nÐEÐEñô ð øõ   ¥yÑ1Ô1ñ cØð #Ø*-¬(°kÒ*AÐ*A˜w˜wÀv˜Ø Ÿš°ÀÐ(FÐ(FÑGÔGÐGØ "˜å! %¤*­cÑ2Ô2ð Ø Ÿšà(.Ø+1°5´:Ð*>Ð)?ðð ñô ð ð ð 24˜
Ø#(¤:ð Eð E˜CÝ)¨#­yÑ9Ô9ð EØ *× 1Ò 1°6¸3¼8Ð2DÑ EÔ EÐ EÐ EÝ!+¨CµÑ!;Ô!;ð EØ04×0NÒ0NØ$'ñ1"ô 1" ð $1ð !EØ$.×$5Ò$5°mÑ$DÔ$DÐ$DøØ%ð Ø$ŸOšOØ)/¸*Ð EÐ Eñô ð ùõ   ¥yÑ1Ô1ð FØ $× >Ò >¸uÑ EÔ E�IØ ð 0ØŸš YÑ/Ô/Ð/ùå ¥}Ñ5Ô5ð AØ—L’Là+Ø&+¤hØ(-¬
õ
 )@Ø$)¤KÐ$7°4ñ)"ô )"ð
.ð 
.ðñô ð ñ õ    ¥Ñ7Ô7ñ 0Øð #Ø*-¬(°kÒ*AÐ*A˜w˜wÀv˜Ø Ÿš°ÀÐ(FÐ(FÑGÔGÐGØ "˜ð
 ×:Ò:¸5¼<ÑHÔHñØ&Ø'ð —O’Oà$*ð %8Ø.3¬hØ05´
à,4°nð5*ð:&ð :&ð!"ð
&ðð ñô ð ð" 'ð Ø&(˜Ø$3ð Að A˜DÝ)¨$µ	Ñ:Ô:ð AØ +× 2Ò 2°F¸D¼IÐ3FÑ GÔ GÐ GÐ GÝ!+¨Dµ)Ñ!<Ô!<ð AØ+/×+IÒ+IØ$(ñ,"ô ," ð $,Ð#7Ø$/×$6Ò$6°xÑ$@Ô$@Ð$@øØ&ð Ø$ŸOšOØ)/¸+Ð FÐ Fñô ð ùõ
 ”NØLÝ˜U™œñô ð ñ ð "œh¨+Ò5Ð5�7�7¸6ˆDàð Ø—’à $Ø!&ðð ñô ð ð �‰FˆAðK •#�d‘)”)Šm‰mðN ˆr    N)rB   rC   rD   rE   r   rS   Úlistr0   Ú__annotations__r   rF   r   rx   rH   r    r   rJ   rJ   o   sœ   € € € € € € ðð ð
 #˜Uð
ð 
ðOðñ ô €K��c”ð ð ñ ðYà�3ŒiðYð 
ˆd�3˜�8ŒnÔ	ðYð Yð Yð Yð Yð Yr    rJ   c            
       óJ  — e Zd ZU dZ edd¬¦  «        Zeed<    ed„ d¬¦  «        Ze	e         ed	<   d
e	e
         de	eeef                  fd„Zd
e	e
         de	eeef                  fd„Z	 dd
e	e
         dede	eeef                  fd„Zede
deeef         fd„¦   «         ZdS )ÚGeminiMultiAgentFormattera¶  The multi-agent formatter for Google Gemini API, where more than a
    user and an agent are involved.

    .. note:: This formatter will combine previous messages (except tool
     calls/results) into a history section in the first system message with
     the conversation history prompt.

    .. note:: For tool calls/results, they will be presented as separate
     messages as required by the Gemini API. Therefore, the tool calls/
     results messages are expected to be placed at the end of the input
     messages.

    .. tip:: Telling the assistant's name in the system prompt is very
     important in multi-agent conversations. So that LLM can know who it
     is playing as.

    zg# Conversation History
The content between <history></history> tags contains your conversation history
z7The prompt to use for the conversation history section.)ÚdefaultrR   Úconversation_history_promptc                  ó
   — g d¢S rL   rH   rH   r    r   rM   z"GeminiMultiAgentFormatter.<lambda>;  rN   r    rO   rP   rS   rT   r   c              ƒ   ó"  K  — |                       |¦  «         g }d}t          |¦  «        dk    rG|d         j        dk    r6|                     |                      |d         ¦  «        ƒ d{V —†¦  «         d}d}|                      ||d…         ¦  «        2 3 d{V —†\  }}|xdk    r0 |                     |                      |¦  «        ƒ d{V —†¦  «         ŒAdk    r2|                     |                      ||¦  «        ƒ d{V —†¦  «         d}ŒxŒy6 |S )	zjFormat input messages into the structure required by the Gemini
        API for multi-agent conversations.r   ÚsystemNr   TÚtool_sequenceÚagent_messageF)	rd   re   r\   rg   Ú_format_system_messageÚ_group_messagesÚextendÚ_format_tool_sequenceÚ_format_agent_message)r&   rT   Úformatted_msgsÚstart_indexÚis_first_agent_messageÚtypÚgroups          r   rx   z GeminiMultiAgentFormatter.formatG  s˜  è è € ð 	× Ò  Ñ&Ô&Ð&àˆØˆÝˆt‰9Œ9�qŠ=ˆ=˜T !œWœ\¨XÒ5Ð5Ø×!Ò!Ø×1Ò1°$°q´'Ñ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:ñô ð ð ˆKà!%ÐØ $× 4Ò 4°T¸+¸,¸,Ô5GÑ HÔ Hð 	3ð 	3ð 	3ð 	3ð 	3ð 	3ð 	3‘*�#�uØØ$�_’_�_�_Ø"×)Ò)Ø"×8Ò8¸Ñ?Ô?Ð?Ð?Ð?Ð?Ð?Ð?ñô ð ð ð %’_�_Ø"×)Ò)Ø"×8Ò8Ø!Ø2ñô ð ð ð ð ð ð ñô ð ð .3Ð*Ð*ð %ð !Ið Ðs   ÂDc              ƒ   ób   K  — t          | j        ¬¦  «                             |¦  «        ƒ d{V —†S )zoGiven a sequence of tool call/result messages, format them into
        the required format for the Gemini API.)rS   N)rJ   rS   rx   )r&   rT   s     r   r‡   z/GeminiMultiAgentFormatter._format_tool_sequencef  sN   è è € õ )ØÔ(ð
ñ 
ô 
ç
Š&�‰,Œ,ðð ð ð ð ð ð 	r    TÚis_firstc              ƒ   ó~  K  — |r| j         }nd}g }g }g }|D ]Â}|                     ¦   «         D ]«}t          |t          ¦  «        r%|                     |j        › d|j        › �¦  «         Œ<t          |t          ¦  «        rZ|r,|                     dd                     |¦  «        i¦  «         g }|  	                    |¦  «        }	|	r|                     |	¦  «         Œ¬ŒÃ|r*|                     dd                     |¦  «        i¦  «         |rµ|d          
                    d¦  «        r|dz   |d         d         z   |d         d<   n|                     dd|dz   i¦  «         |d          
                    d¦  «        r|d         dxx         dz  cc<   n|                     dd	i¦  «         |                     d
|dœ¦  «         |S )zyGiven a sequence of messages without tool calls/results, format
        them into the required format for the Gemini API.Ú z: rV   ú
r   z
<history>
éÿÿÿÿz
</history>z
</history>rZ   r[   )r~   rf   r/   r   rg   r`   rV   r   Újoinr'   r:   Úinsert)
r&   rT   r�   r~   r‰   Úconversation_partsÚaccumulated_textrn   r   rr   s
             r   rˆ   z/GeminiMultiAgentFormatter._format_agent_messagep  s]  è è € ð ð 	-Ø*.Ô*JÐ'Ð'à*,Ð'à%'ˆØ)+ÐØ&(Ðàð 	=ð 	=ˆCØ×/Ò/Ñ1Ô1ð =ð =�Ý˜e¥YÑ/Ô/ð =Ø$×+Ò+¨s¬xÐ,GÐ,G¸5¼:Ð,GÐ,GÑHÔHÐHÐHå ¥yÑ1Ô1ð 
=à'ð .Ø*×1Ò1Ø# T§Y¢YÐ/?Ñ%@Ô%@ÐAñô ð ð ,.Ð(à $× >Ò >¸uÑ EÔ E�IØ ð =Ø*×1Ò1°)Ñ<Ô<Ð<øð=ð  ð 	Ø×%Ò%Ø˜ŸšÐ#3Ñ4Ô4Ð5ñô ð ð
 ð 	Ø! !Ô$×(Ò(¨Ñ0Ô0ð 
à/Ø#ñ$à(¨Ô+¨FÔ3ñ4ð # 1Ô% fÑ-Ð-ð #×)Ò)ØØÐ8¸=ÑHÐIñô ð ð
 " "Ô%×)Ò)¨&Ñ1Ô1ð BØ" 2Ô& vÐ.Ð.Ô.°.Ñ@Ð.Ð.Ñ.Ð.à"×)Ò)¨6°<Ð*@ÑAÔAÐAà×!Ò!à"Ø/ðð ñô ð ð Ðr    rn   c              ƒ   ó:   K  — dd|                       ¦   «         igdœS )z)Format system message for the Gemini API.rZ   rV   r[   )Úget_text_content)rn   s    r   r„   z0GeminiMultiAgentFormatter._format_system_message³  s7   è è € ð ð ˜C×0Ò0Ñ2Ô2ððð
ð 
ð 	
r    N)T)rB   rC   rD   rE   r   r~   r0   rz   rS   ry   r   rF   r   rx   r‡   Úboolrˆ   rG   r„   rH   r    r   r|   r|     s†  € € € € € € ðð ð$ (- uð*ð Nð(ñ (ô (Ð ð ð ñ ð #˜Uð
ð 
ðOðñ ô €K��c”ð ð ñ ð  c¤ð ¨t°D¸¸c¸´NÔ/Cð ð ð ð ð>à�3Œiðð 
ˆd�3˜�8ŒnÔ	ðð ð ð ð ðAð Aà�3ŒiðAð ðAð 
ˆd�3˜�8ŒnÔ	ð	Að Að Að AðF ð	
¨#ð 	
°$°s¸C°x´.ð 	
ð 	
ð 	
ñ „\ð	
ð 	
ð 	
r    r|   )rE   r5   r   Úabcr   Útypingr   r9   Úpydanticr   Ú_formatter_baser   Ú_loggingr	   Ú_utils._commonr
   Úmessager   r   r   r   r   r   r   r   r   r   rJ   r|   rH   r    r   ú<module>r¢      s°  ðà 0Ð 0Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð à €€€Ø Ð Ð Ð Ð Ð à *Ð *Ð *Ð *Ð *Ð *Ø Ð Ð Ð Ð Ð Ø 4Ð 4Ð 4Ð 4Ð 4Ð 4ð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ðQIð QIð QIð QIð QI˜=¨#ñ QIô QIð QIðhlð lð lð lð lÐ.ñ lô lð lð^_
ð _
ð _
ð _
ð _
Ð 4ñ _
ô _
ð _
ð _
ð _
r    