§
    ÚŽ’j«I  ã                   óð   — d 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	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$The OpenAI formatter for agentscope.é    N)ÚABC)Úfnmatch)ÚAny)Úurlparse)ÚFieldé   )ÚFormatterBaseé   )Úlogger)	ÚMsgÚ	URLSourceÚ	TextBlockÚ	DataBlockÚBase64SourceÚToolCallBlockÚToolResultBlockÚ	HintBlockÚThinkingBlockc                   ó”   — e Zd ZdZdedeeef         dz  fd„Zde	e
z  deeef         fd„Zede	e
z  deeef         fd„¦   «         ZdS )	Ú_OpenAIFormatterBasezSBase class for OpenAI formatters, providing shared data block
    formatting logic.ÚblockÚreturnNc                 ó°  ‡— t          ˆfd„| j        D ¦   «         ¦  «        s:t          j        d‰j        j        d                     | j        ¦  «        ¦  «         dS ‰j        j                             d¦  «        d         }|dk    r|                      ‰j        ¦  «        S |dk    r|  	                    ‰j        ¦  «        S t          j        d	|¦  «         dS )
a  Format a DataBlock into the required format for OpenAI API.

        For image blocks, URLs are returned as-is (or converted to base64 for
        local ``file://`` paths). For audio blocks, data is always converted
        to base64 as required by the OpenAI input_audio format.

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

        Returns:
            `dict[str, Any] | None`:
                A dictionary in OpenAI API format, or ``None`` if the block
                should be skipped.
        c              3   óL   •K  — | ]}t          ‰j        j        |¦  «        V — Œd S )N)r   ÚsourceÚ
media_type)Ú.0Úpatternr   s     €úTC:\Projects\DSCons\.venv\Lib\site-packages\agentscope\formatter\_openai_formatter.pyú	<genexpr>zA_OpenAIFormatterBase._format_openai_data_block.<locals>.<genexpr>2   sF   øè è € ð 
ð 
àõ �E”LÔ+¨WÑ5Ô5ð
ð 
ð 
ð 
ð 
ð 
ó    zZUnsupported media type %s for OpenAI API. Supported types: %s. This block will be skipped.z, Nú/r   ÚimageÚaudiozJUnsupported main media type %s for OpenAI API. This block will be skipped.)
ÚanyÚsupported_input_media_typesr   Úwarningr   r   ÚjoinÚsplitÚ_format_image_sourceÚ_format_audio_source)Úselfr   Ú	main_types    ` r   Ú_format_openai_data_blockz._OpenAIFormatterBase._format_openai_data_block   sÿ   ø€ õ& ð 
ð 
ð 
ð 
àÔ;ð
ñ 
ô 
ñ 
ô 
ð 
	õ ŒNðCà”Ô'Ø—	’	˜$Ô:Ñ;Ô;ñ	ô ð ð �4à”LÔ+×1Ò1°#Ñ6Ô6°qÔ9ˆ	à˜ÒÐØ×,Ò,¨U¬\Ñ:Ô:Ð:à˜ÒÐØ×,Ò,¨U¬\Ñ:Ô:Ð:åŒð*àñ	
ô 	
ð 	
ð
 ˆtr!   r   c                 ó(  — t          |t          ¦  «        rd|j        › d|j        › �}nä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|› �}n"|}nt          dt          |¦  «        › �¦  «        ‚dd	|id
œS )ap  Convert an image source to OpenAI image_url format.

        Local ``file://`` URLs are read from disk and converted to base64
        data URIs. Remote URLs are passed through unchanged. Subclasses may
        override this to apply provider-specific handling (e.g. forcing
        remote URLs to be downloaded and base64-encoded for APIs that don't
        accept raw HTTPS URLs).

        Args:
            source (`URLSource | Base64Source`):
                The image source to convert.

        Returns:
            `dict[str, Any]`:
                A dictionary with ``"type": "image_url"`` in OpenAI format.
        zdata:z;base64,úfile://Úrbúutf-8NzUnsupported image source type: Ú	image_urlÚurl)Útyper3   )Ú
isinstancer   r   Údatar   Ústrr4   Ú
startswithÚremoveprefixÚopenÚbase64Ú	b64encodeÚreadÚdecodeÚ
ValueErrorr5   )r,   r   r4   Úurl_strÚ
local_pathÚfÚencodeds          r   r*   z)_OpenAIFormatterBase._format_image_sourceM   sq  € õ( �f�lÑ+Ô+ð 	OØB˜&Ô+ÐBÐB°V´[ÐBÐBˆCˆCå˜¥	Ñ*Ô*ð 	OÝ˜&œ*‘o”oˆGØ×!Ò! )Ñ,Ô,ð à$×1Ò1°)Ñ<Ô<�
Ý˜* dÑ+Ô+ð I¨qÝ$Ô.¨q¯vªv©x¬xÑ8Ô8×?Ò?ÀÑHÔH�GðIð Ið Iñ Iô Ið Ið Ið Ið Ið Ið Iøøøð Ið Ið Ið IàB˜fÔ/ÐBÐB¸ÐBÐB��ð ��õ ÐM½tÀF¹|¼|ÐMÐMÑNÔNÐNð  Ø ˜ð
ð 
ð 	
s   Â:CÃCÃCc                 óX  — t          | t          ¦  «        rD| j        }|dvrt          d|› d�¦  «        ‚d| j        |                     d¦  «        d         dœdœS t          | t          ¦  «        �rœt          | j        ¦  «        }| 	                    d	¦  «        r¼| 
                    d	¦  «        }|                     d
d¦  «        d                              ¦   «         }|dvrt          d|› d�¦  «        ‚t          |d¦  «        5 }t          j        |                     ¦   «         ¦  «                             d¦  «        }ddd¦  «         n# 1 swxY w Y   n¯t%          |¦  «        }|j                             d
d¦  «        d                              ¦   «         }|dvrt          d|› d�¦  «        ‚t)          j        |d¬¦  «        }|                     ¦   «          t          j        |j        ¦  «                             d¦  «        }d||dœdœS t          dt1          | ¦  «        › d
�¦  «        ‚)aÃ  Convert an audio source to OpenAI input_audio format.

        Local ``file://`` URLs are read from disk. Remote URLs are downloaded.
        Only ``wav`` and ``mp3`` formats are supported by the OpenAI API.

        Args:
            source (`URLSource | Base64Source`):
                The audio source to convert.

        Returns:
            `dict[str, Any]`:
                A dictionary with ``"type": "input_audio"`` in OpenAI format.
        )z	audio/wavz	audio/mp3zUnsupported audio media type: z-, only audio/wav and audio/mp3 are supported.Úinput_audior"   éÿÿÿÿ)r7   Úformat)r5   rF   r0   ú.r   )ÚwavÚmp3z"Unsupported audio file extension: z, wav and mp3 are supported.r1   r2   Né   )ÚtimeoutzUnsupported audio source type: )r6   r   r   Ú	TypeErrorr7   r)   r   r8   r4   r9   r:   ÚrsplitÚlowerr;   r<   r=   r>   r?   r   ÚpathÚrequestsÚgetÚraise_for_statusÚcontentr5   )	r   r   rA   rB   Ú	extensionrC   r7   ÚparsedÚresponses	            r   r+   z)_OpenAIFormatterBase._format_audio_sourcex   sÇ  € õ" �f�lÑ+Ô+ð 	ØÔ*ˆJØÐ!;Ð;Ð;ÝðB°Zð Bð Bð Bñô ð ð
 &à"œKØ(×.Ò.¨sÑ3Ô3°BÔ7ð ð  ðð ð õ �f�iÑ(Ô(ñ  	Ý˜&œ*‘o”oˆGØ×!Ò! )Ñ,Ô,ð Jà$×1Ò1°)Ñ<Ô<�
Ø&×-Ò-¨c°1Ñ5Ô5°bÔ9×?Ò?ÑAÔA�	Ø NÐ2Ð2Ý#ð5¸Yð 5ð 5ð 5ñô ð õ ˜* dÑ+Ô+ð F¨qÝ!Ô+¨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øõ " 'Ñ*Ô*�Ø"œK×.Ò.¨s°AÑ6Ô6°rÔ:×@Ò@ÑBÔB�	Ø NÐ2Ð2Ý#ð5¸Yð 5ð 5ð 5ñô ð õ $œ<¨¸Ð<Ñ<Ô<�Ø×)Ò)Ñ+Ô+Ð+ÝÔ'¨Ô(8Ñ9Ô9×@Ò@ÀÑIÔI�ð &à Ø'ð ð  ðð ð õ ÐI½$¸v¹,¼,ÐIÐIÐIÑJÔJÐJs   Ä:E	Å	EÅE)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Údictr8   r   r.   r   r   r*   Ústaticmethodr+   © r!   r   r   r      sÓ   € € € € € ðð ð,àð,ð 
ˆc�3ˆhŒ˜$Ñ	ð,ð ,ð ,ð ,ð\)
à˜LÑ(ð)
ð 
ˆc�3ˆhŒð)
ð )
ð )
ð )
ðV ðAKØ˜LÑ(ðAKà	ˆc�3ˆhŒðAKð AKð AKñ „\ðAKð AKð AK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 )
ÚOpenAIChatFormatterzÄThe OpenAI formatter class for chatbot scenario, where only a user
    and an agent are involved. We use the `name` field in OpenAI API to
    identify different entities in the conversation.
    c                  ó
   — g d¢S ©N)z
text/plainzimage/*zaudio/*r_   r_   r!   r   ú<lambda>zOpenAIChatFormatter.<lambda>Ä   ó   € Ð DÐ DÐ D€ r!   úPThe supported input types. Defaults to ``["text/plain", "image/*", "audio/*"]``.©Údefault_factoryÚdescriptionÚinput_typesÚmsgsr   c              ƒ   óî  K  — |                       |¦  «         g }d}|t          |¦  «        k     �rÅ||         }g }g }|                     ¦   «         D �]?}t          |t          ¦  «        r|                     d|j        dœ¦  «         Œ6t          |t          ¦  «        r-|                      |¦  «        }|�|                     |¦  «         Œxt          |t          ¦  «        �r|s|r2|j
        |j        |pddœ}	|r||	d<   |                     |	¦  «         g }g }t          |j        t          ¦  «        r#|                     dd|j        dœgdœ¦  «         �Œg }
|j        D ]v}t          |t          ¦  «        r|
                     d|j        dœ¦  «         Œ5t          |t          ¦  «        r,|                      |¦  «        }|�|
                     |¦  «         Œw|
r|                     d|
dœ¦  «         �Œ�t          |t          ¦  «        r-|                     |j        d	|j        |j        d
œdœ¦  «         �Œßt          |t"          ¦  «        �r|s|r2|j
        |j        |pddœ}|r||d<   |                     |¦  «         g }g }|                      |j        ¦  «        \  }}|                     d|j        ||j        dœ¦  «         |r–g }|D ]v}t          |t          ¦  «        r|                     d|j        dœ¦  «         Œ5t          |t          ¦  «        r,|                      |¦  «        }|�|                     |¦  «         Œw|r|                     dd|dœ¦  «         �Œt          |t(          ¦  «        r�Œt+          j        dt/          |¦  «        ¦  «         �ŒA|j
        |j        |pddœ}	|r||	d<   |	d         s|	                     d¦  «        r|                     |	¦  «         |dz  }|t          |¦  «        k     �°Å|S )aN  Format message objects into OpenAI API required format.

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

        Returns:
            `list[dict[str, Any]]`:
                A list of dictionaries, where each dictionary has "name",
                "role", and "content" keys.
        r   Útext©r5   rm   N)ÚroleÚnamerU   Ú
tool_callsÚuser©ro   rU   Úfunction)rp   Ú	arguments)Úidr5   rt   Útool)ro   Útool_call_idrU   rp   zsystem-reminderz2Unsupported block type %s in the message, skipped.rU   r   )Úassert_list_of_msgsÚlenÚget_content_blocksr6   r   Úappendrm   r   r.   r   ro   rp   Úhintr8   r   rv   Úinputr   Úconvert_tool_result_to_stringÚoutputr   r   r'   r5   rS   )r,   rk   ÚmessagesÚiÚmsgÚcontent_blocksrq   r   Ú	formattedÚ
msg_openaiÚ
hint_partsÚsubÚformatted_subÚmsg_openai_flushÚtextual_outputÚmultimodal_dataÚpromo_contentÚitemÚfmt_items                      r   rH   zOpenAIChatFormatter.formatË   s0  è è € ð 	× Ò  Ñ&Ô&Ð&à!ˆØˆØ•#�d‘)”)Šm‰mØ�q”'ˆCØˆNØˆJà×/Ò/Ñ1Ô1ð yñ y�Ý˜e¥YÑ/Ô/ð xØ"×)Ò)°6À5Ä:Ð*NÐ*NÑOÔOÐOÐOå ¥yÑ1Ô1ð uØ $× >Ò >Øñ!ô !�Ið !Ð,Ø&×-Ò-¨iÑ8Ô8Ð8øå ¥yÑ1Ô1ñ nØ%ð 
(¨ð 
(à$'¤HØ$'¤HØ'5Ð'=¸ð&ð &˜
ð
 &ð BØ7A˜J |Ñ4Ø Ÿš¨
Ñ3Ô3Ð3Ø)+˜Ø%'˜
å! %¤*­cÑ2Ô2ð Ø Ÿšà(.à-3¸U¼ZÐ$HÐ$Hð,"ðð ñô ð ñ ð 24˜
Ø#(¤:ð 
Eð 
E˜CÝ)¨#­yÑ9Ô9ð 	EØ *× 1Ò 1Ø-3¸S¼XÐ$FÐ$Fñ!"ô !"ð !"ð !"õ ",¨CµÑ!;Ô!;ð EØ04×0NÒ0NØ$'ñ1"ô 1" ð $1Ð#<Ø$.×$5Ò$5°mÑ$DÔ$DÐ$DøØ%ð Ø$ŸOšOØ)/¸JÐ GÐ Gñô ð ùõ   ¥}Ñ5Ô5ð FØ×%Ò%à"'¤(Ø$.à(-¬
Ø-2¬[ð)ð )ðð ñ	ô 	ð 	ñ 	õ   ¥Ñ7Ô7ñ :Ø%ð 
(¨ð 
(à$'¤HØ$'¤HØ'5Ð'=¸ð,ð ,Ð(ð
 &ð HØ=GÐ,¨\Ñ:Ø ŸšÐ(8Ñ9Ô9Ð9Ø)+˜Ø%'˜
ð
 ×:Ò:¸5¼<ÑHÔHñØ&Ø'ð —O’Oà$*Ø,1¬HØ'5Ø$)¤Jð	ð ñô ð ð 'ð Ø(*˜Ø$3ð 
Cð 
C˜DÝ)¨$µ	Ñ:Ô:ð 	CØ -× 4Ò 4Ø-3¸T¼YÐ$GÐ$Gñ!"ô !"ð !"ð !"õ ",¨Dµ)Ñ!<Ô!<ð CØ+/×+IÒ+IØ$(ñ,"ô ," ð $,Ð#7Ø$1×$8Ò$8¸Ñ$BÔ$BÐ$BøØ(ð Ø$ŸOšOà,2Ø,=Ø/<ð!"ð !"ñô ð ùõ   ¥}Ñ5Ô5ð 	ñ õ ”NØLÝ˜U™œñô ð ñ ð œØœØ)Ð1¨Tðð ˆJð ð 6Ø+5�
˜<Ñ(ð ˜)Ô$ð ,¨
¯ª°|Ñ(DÔ(Dð ,Ø—’ 
Ñ+Ô+Ð+ð �‰FˆAð] •#�d‘)”)Šm‰mð` ˆr!   N)rY   rZ   r[   r\   r   rj   Úlistr8   Ú__annotations__r   r]   r   rH   r_   r!   r   ra   ra   ½   s˜   € € € € € € ðð ð
 #˜UØDÐDðDðñ ô €K��c”ð ð ñ ðcà�3Œiðcð 
ˆd�3˜�8ŒnÔ	ðcð cð cð cð cð cr!   ra   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 )ÚOpenAIMultiAgentFormatterzö
    OpenAI formatter for multi-agent conversations, where more than
    a user and an agent are involved.

    .. tip:: This formatter is compatible with OpenAI API and
        OpenAI-compatible services like vLLM, Azure OpenAI, and others.
    zg# Conversation History
The content between <history></history> tags contains your conversation history
z7The prompt to use for the conversation history section.)Údefaultri   Úconversation_history_promptc                  ó
   — g d¢S rc   r_   r_   r!   r   rd   z"OpenAIMultiAgentFormatter.<lambda>„  re   r!   rf   rg   rj   rk   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 OpenAI API
        for multi-agent conversations.r   ÚsystemNr   TÚtool_sequenceÚagent_messageF)	ry   rz   ro   r|   Ú_format_system_messageÚ_group_messagesÚextendÚ_format_tool_sequenceÚ_format_agent_message)r,   rk   Úformatted_msgsÚstart_indexÚis_first_agent_messageÚtypÚgroups          r   rH   z OpenAIMultiAgentFormatter.format‹  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 OpenAI API.)rj   N)ra   rj   rH   )r,   rk   s     r   rž   z/OpenAIMultiAgentFormatter._format_tool_sequenceª  sN   è è € õ )ØÔ(ð
ñ 
ô 
ç
Š&�‰,Œ,ðð ð ð ð ð ð 	r!   TÚis_firstc              ƒ   óÊ  K  — |r| j         }nd}g }g }g }g }|D ]”}|                     ¦   «         D ]}}	t          |	t          ¦  «        r%|                     |j        › d|	j        › �¦  «         Œ<t          |	t          ¦  «        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„ |D ¦   «         ¦  «        }g }|r|                     d|dœ¦  «         |                     |¦  «         |r|                     d|dœ¦  «         |S )zyGiven a sequence of messages without tool calls/results, format
        them into the required format for the OpenAI API.Ú z: Nrm   ú
r   z
<history>
rG   z
</history>z
</history>c              3   óB   K  — | ]}|                      d d¦  «        V — ŒdS )rm   r¨   N)rS   )r   Úbs     r   r    zBOpenAIMultiAgentFormatter._format_agent_message.<locals>.<genexpr>é  sA   è è € ð -
ð -
Ø"#ˆA�EŠE�&˜"ÑÔð-
ð -
ð -
ð -
ð -
ð -
r!   rn   rr   rs   )r•   r{   r6   r   r|   rp   rm   r   r.   r(   rS   Úinsertr�   )r,   rk   r¦   r•   r    Úconversation_blocksÚaccumulated_textÚmedia_blocksrƒ   r   r…   Úconversation_blocks_textÚcontent_lists                r   rŸ   z/OpenAIMultiAgentFormatter._format_agent_message´  sŸ  è è € ð ð 	-Ø*.Ô*JÐ'Ð'à*,Ð'à%'ˆØ$&ÐØÐØ#%ˆàð 
	7ð 
	7ˆCØ×/Ò/Ñ1Ô1ð 	7ð 	7�Ý˜e¥YÑ/Ô/ð 7Ø$×+Ò+¨s¬xÐ,GÐ,G¸5¼:Ð,GÐ,GÑHÔHÐHÐHå ¥yÑ1Ô1ð 7Ø $× >Ò >Øñ!ô !�Ið !Ð,Ø$×+Ò+¨IÑ6Ô6Ð6øð	7ð ð 	Ø×&Ò&Ø˜ŸšÐ#3Ñ4Ô4Ð5ñô ð ð ð 	CØ" 1Ô%×)Ò)¨&Ñ1Ô1ð 
à/Ø#ñ$à)¨!Ô,¨VÔ4ñ5ð $ AÔ& vÑ.Ð.ð $×*Ò*ØØÐ8¸=ÑHÐIñô ð ð
 # 2Ô&×*Ò*¨6Ñ2Ô2ð CØ# BÔ'¨Ð/Ð/Ô/°>ÑAÐ/Ð/Ñ/Ð/à#×*Ò*¨F°LÐ+AÑBÔBÐBà#'§9¢9ð -
ð -
Ø':ð-
ñ -
ô -
ñ $
ô $
Ð ð .0ˆØ#ð 	Ø×ÒØÐ)AÐBÐBñô ð ð 	×Ò˜LÑ)Ô)Ð)àð 	MØ×!Ò!¨6¸lÐ"KÐ"KÑLÔLÐLàÐr!   rƒ   c              ƒ   ó4   K  — d|                       ¦   «         dœS )z%Format system message for OpenAI API.r˜   rs   )Úget_text_content)rƒ   s    r   r›   z0OpenAIMultiAgentFormatter._format_system_messageù  s)   è è € ð Ø×+Ò+Ñ-Ô-ð
ð 
ð 	
r!   N)T)rY   rZ   r[   r\   r   r•   r8   r‘   rj   r�   r   r]   r   rH   rž   ÚboolrŸ   r^   r›   r_   r!   r   r“   r“   q  s„  € € € € € € ðð ð (- uð*ð Nð(ñ (ô (Ð ð ð ñ ð #˜UØDÐDðDðñ ô €K��c”ð ð ñ ð  c¤ð ¨t°D¸¸c¸´NÔ/Cð ð ð ð ð>à�3Œiðð 
ˆd�3˜�8ŒnÔ	ðð ð ð ð ðCð Cà�3ŒiðCð ðCð 
ˆd�3˜�8ŒnÔ	ð	Cð Cð Cð CðJ ð
Øð
à	ˆc�3ˆhŒð
ð 
ð 
ñ „\ð
ð 
ð 
r!   r“   )r\   r<   Úabcr   r   Útypingr   Úurllib.parser   rR   Úpydanticr   Ú_formatter_baser	   Ú_loggingr   Úmessager   r   r   r   r   r   r   r   r   r   ra   r“   r_   r!   r   ú<module>r¼      s¹  ðà *Ð *Ø €€€Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø !Ð !Ð !Ð !Ð !Ð !à €€€Ø Ð Ð Ð Ð Ð à *Ð *Ð *Ð *Ð *Ð *Ø Ð Ð Ð Ð Ð ð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð_Kð _Kð _Kð _Kð _K˜=¨#ñ _Kô _Kð _KðDqð qð qð qð qÐ.ñ qô qð qðhP
ð P
ð P
ð P
ð P
Ð 4ñ P
ô P
ð P
ð P
ð P
r!   