§
    ‰eîin?  ã                   ó¦   — d Z ddlZddlmZmZmZ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  G d„ d	e¦  «        Zdd
lmZ  ede¦  «         dS )uÞ  OpenAI Chat Completions transport.

Handles the default api_mode ('chat_completions') used by ~16 OpenAI-compatible
providers (OpenRouter, Nous, NVIDIA, Qwen, Ollama, DeepSeek, xAI, Kimi, etc.).

Messages and tools are already in OpenAI format â€” convert_messages and
convert_tools are near-identity.  The complexity lives in build_kwargs
which has provider-specific conditionals for max_tokens defaults,
reasoning configuration, temperature handling, and extra_body assembly.
é    N)ÚAnyÚDictÚListÚOptional)Úis_moonshot_modelÚsanitize_moonshot_tools)ÚDEVELOPER_ROLE_MODELS)ÚProviderTransport)ÚNormalizedResponseÚToolCallÚUsagec                   óz  — e Zd ZdZedefd„¦   «         Zdeeee	f                  deeee	f                  fd„Z
deeee	f                  deeee	f                  fd„Z	 dd	edeeee	f                  deeeee	f                           deee	f         fd
„Zde	defd„Zde	defd„Zde	deeeef                  fd„ZdS )ÚChatCompletionsTransportzfTransport for api_mode='chat_completions'.

    The default path for OpenAI-compatible providers.
    Úreturnc                 ó   — dS )NÚchat_completions© )Úselfs    úC/home/div/.hermes/hermes-agent/agent/transports/chat_completions.pyÚapi_modez!ChatCompletionsTransport.api_mode   s   € à!Ð!ó    Úmessagesc                 óž  — d}|D ]x}t          |t          ¦  «        sŒd|v sd|v rd} nU|                     d¦  «        }t          |t          ¦  «        r*|D ]#}t          |t          ¦  «        rd|v sd|v rd} nŒ$|r nŒy|s|S t	          j        |¦  «        }|D ]´}t          |t          ¦  «        sŒ|                     dd¦  «         |                     dd¦  «         |                     d¦  «        }t          |t          ¦  «        rF|D ]C}t          |t          ¦  «        r,|                     dd¦  «         |                     dd¦  «         ŒDŒµ|S )	u9  Messages are already in OpenAI format â€” sanitize Codex leaks only.

        Strips Codex Responses API fields (``codex_reasoning_items`` /
        ``codex_message_items`` on the message, ``call_id``/``response_item_id``
        on tool_calls) that strict chat-completions providers reject with 400/422.
        FÚcodex_reasoning_itemsÚcodex_message_itemsTÚ
tool_callsÚcall_idÚresponse_item_idN)Ú
isinstanceÚdictÚgetÚlistÚcopyÚdeepcopyÚpop)r   r   ÚkwargsÚneeds_sanitizeÚmsgr   ÚtcÚ	sanitizeds           r   Úconvert_messagesz)ChatCompletionsTransport.convert_messages   s�  € ð ˆØð 	ð 	ˆCÝ˜c¥4Ñ(Ô(ð ØØ&¨#Ð-Ð-Ð1FÈ#Ð1MÐ1MØ!%�Ø�ØŸš Ñ.Ô.ˆJÝ˜*¥dÑ+Ô+ð Ø$ð ð �BÝ! "¥dÑ+Ô+ð °¸b°°ÐDVÐZ\ÐD\ÐD\Ø)-˜Ø˜øØ!ð Ø�Eøàð 	ØˆOå”M (Ñ+Ô+ˆ	Øð 
	9ð 
	9ˆCÝ˜c¥4Ñ(Ô(ð ØØ�GŠGÐ+¨TÑ2Ô2Ð2Ø�GŠGÐ)¨4Ñ0Ô0Ð0ØŸš Ñ.Ô.ˆJÝ˜*¥dÑ+Ô+ð 9Ø$ð 9ð 9�BÝ! "¥dÑ+Ô+ð 9ØŸš˜y¨$Ñ/Ô/Ð/ØŸšÐ1°4Ñ8Ô8Ð8øøØÐr   Útoolsc                 ó   — |S )u0   Tools are already in OpenAI format â€” identity.r   )r   r,   s     r   Úconvert_toolsz&ChatCompletionsTransport.convert_toolsG   s   € àˆr   NÚmodelc                 ó  ‡&— |                       |¦  «        }|                     dd¦  «        }|rW|                     d¦  «        }|                     d¦  «        }||u r|� ||¦  «        }n|� ||¦  «         n|� ||¦  «        }|                     d|pd                     ¦   «         ¦  «        Š&|rzt          |d         t          ¦  «        r_|d                              d	¦  «        d
k    r@t          ˆ&fd„t          D ¦   «         ¦  «        r t          |¦  «        }i |d         ¥d	di¥|d<   ||dœ}	|                     d¦  «        }
|
�|
|	d<   |                     d¦  «        }|                     dd¦  «        }|r|	                     dd¦  «         n|�||	d<   |                     d¦  «        }|r|r||	d<   |r#t          |¦  «        rt          |¦  «        }||	d<   |                     d¦  «        }|                     d¦  «        }|                     d¦  «        }|                     d¦  «        }|                     dd¦  «        }|                     dd¦  «        }|                     d¦  «        }|�!|r|	                      ||¦  «        ¦  «         n“|�!|r|	                      ||¦  «        ¦  «         np|r!|r|	                      |d¦  «        ¦  «         nM|r!|r|	                      |d¦  «        ¦  «         n*|r!|r|	                      |d¦  «        ¦  «         n|�||	d<   |rœt          |o+t          |t          ¦  «        o|                     d¦  «        du ¦  «        }|s_d }|rVt          |t          ¦  «        rA|                     d!¦  «        pd                     ¦   «                              ¦   «         }|d"v r|}||	d#<   i }|                     d$d¦  «        }|                     d%d¦  «        }|                     d&d¦  «        }|                     d'¦  «        }|r|r||d(<   |r=d)}|r.t          |t          ¦  «        r|                     d¦  «        du rd}d*|rdnd+i|d,<   |                     d-d¦  «        rX|r|                     d.¦  «        }|�||d/<   n9|�/t	          |¦  «        }|r|                     d¦  «        du rn||d/<   nd)d d0œ|d/<   |rd1g|d2<   |                     d3¦  «        } | r |                     d4i ¦  «        }!| |!d5<   |!|d4<   |                     d6d¦  «        rw|rut          |t          ¦  «        r`|                     d!¦  «        pd                     ¦   «                              ¦   «         }"|                     dd)¦  «        }#|"d7k    s|#du rd|d8<   |rd)|d9<   |                     d:¦  «        }$|$r|                     |$¦  «         |r||	d;<   |                     d<¦  «        }%|%r|	                     |%¦  «         |	S )=u  Build chat.completions.create() kwargs.

        This is the most complex transport method â€” it handles ~16 providers
        via params rather than subclasses.

        params:
            timeout: float â€” API call timeout
            max_tokens: int | None â€” user-configured max tokens
            ephemeral_max_output_tokens: int | None â€” one-shot override (error recovery)
            max_tokens_param_fn: callable â€” returns {max_tokens: N} or {max_completion_tokens: N}
            reasoning_config: dict | None
            request_overrides: dict | None
            session_id: str | None
            qwen_session_metadata: dict | None â€” {sessionId, promptId} precomputed
            model_lower: str â€” lowercase model name for pattern matching
            # Provider detection flags (all optional, default False)
            is_openrouter: bool
            is_nous: bool
            is_qwen_portal: bool
            is_github_models: bool
            is_nvidia_nim: bool
            is_kimi: bool
            is_custom_provider: bool
            ollama_num_ctx: int | None
            # Provider routing
            provider_preferences: dict | None
            # Qwen-specific
            qwen_prepare_fn: callable | None â€” runs AFTER codex sanitization
            qwen_prepare_inplace_fn: callable | None â€” in-place variant for deepcopied lists
            # Temperature
            fixed_temperature: Any â€” from _fixed_temperature_for_model()
            omit_temperature: bool
            # Reasoning
            supports_reasoning: bool
            github_reasoning_extra: dict | None
            # Claude on OpenRouter/Nous max output
            anthropic_max_output: int | None
            # Extra
            extra_body_additions: dict | None â€” pre-built extra_body entries
        Úis_qwen_portalFÚqwen_prepare_fnÚqwen_prepare_inplace_fnNÚmodel_lowerÚ r   ÚroleÚsystemc              3   ó    •K  — | ]}|‰v V — Œ	d S ©Nr   )Ú.0Úpr4   s     €r   ú	<genexpr>z8ChatCompletionsTransport.build_kwargs.<locals>.<genexpr>”   s(   øè è € ÐDÐD¨�A˜Ð$ÐDÐDÐDÐDÐDÐDr   Ú	developer)r/   r   ÚtimeoutÚfixed_temperatureÚomit_temperatureÚtemperatureÚqwen_session_metadataÚmetadatar,   Úmax_tokens_param_fnÚephemeral_max_output_tokensÚ
max_tokensÚanthropic_max_outputÚis_nvidia_nimÚis_kimiÚreasoning_configi @  i   i }  ÚenabledÚmediumÚeffort)ÚlowrL   ÚhighÚreasoning_effortÚis_openrouterÚis_nousÚis_github_modelsÚprovider_preferencesÚproviderTÚtypeÚdisabledÚthinkingÚsupports_reasoningÚgithub_reasoning_extraÚ	reasoning)rK   rM   zproduct=hermes-agentÚtagsÚollama_num_ctxÚoptionsÚnum_ctxÚis_custom_providerÚnoneÚthinkÚvl_high_resolution_imagesÚextra_body_additionsÚ
extra_bodyÚrequest_overrides)r+   r!   Úlowerr   r    Úanyr	   r"   r%   r   r   ÚupdateÚboolÚstrip)'r   r/   r   r,   Úparamsr*   Úis_qwenÚ	qwen_prepÚqwen_prep_inplaceÚ
api_kwargsr>   Ú
fixed_tempÚ	omit_tempÚ	qwen_metaÚmax_tokens_fnÚ	ephemeralrF   Úanthropic_max_outrH   rI   rJ   Ú_kimi_thinking_offÚ_kimi_effortÚ_ere   rQ   rR   rS   Úprovider_prefsÚ_kimi_thinking_enabledÚgh_reasoningÚrcÚ
ollama_ctxr^   Ú_effortÚ_enabledÚ	additionsÚ	overridesr4   s'                                         @r   Úbuild_kwargsz%ChatCompletionsTransport.build_kwargsK   so  ø€ ð` ×)Ò)¨(Ñ3Ô3ˆ	ð
 —*’*Ð-¨uÑ5Ô5ˆØð 	5ØŸ
š
Ð#4Ñ5Ô5ˆIØ &§
¢
Ð+DÑ EÔ EÐØ˜HÐ$Ð$ØÐ(Ø ) 	¨)Ñ 4Ô 4�Iøð %Ð0Ø%Ð% iÑ0Ô0Ð0Ð0ØÐ*Ø ) 	¨)Ñ 4Ô 4�Ið —j’j °°¸"×0CÒ0CÑ0EÔ0EÑFÔFˆàð	Aå˜9 Qœ<­Ñ.Ô.ð	Að ˜!”× Ò  Ñ(Ô(¨HÒ4Ð4ÝÐDÐDÐDÐDÕ.CÐDÑDÔDÑDÔDð 5õ ˜Y™œˆIØ@˜i¨œlÐ@¨F°KÐ@Ð@ˆI�a‰Lð Ø!ð&
ð &
ˆ
ð
 —*’*˜YÑ'Ô'ˆØÐØ$+ˆJ�yÑ!ð —Z’ZÐ 3Ñ4Ô4ˆ
Ø—J’JÐ1°5Ñ9Ô9ˆ	Øð 	3Ø�NŠN˜=¨$Ñ/Ô/Ð/Ð/ØÐ#Ø(2ˆJ�}Ñ%ð —J’JÐ6Ñ7Ô7ˆ	Øð 	/˜ð 	/Ø%.ˆJ�zÑ"ð ð 	(õ ! Ñ'Ô'ð 7Ý/°Ñ6Ô6�Ø"'ˆJ�wÑð Ÿ
š
Ð#8Ñ9Ô9ˆØ—J’JÐ<Ñ=Ô=ˆ	Ø—Z’Z Ñ-Ô-ˆ
Ø"ŸJšJÐ'=Ñ>Ô>ÐØŸ
š
 ?°EÑ:Ô:ˆØ—*’*˜Y¨Ñ.Ô.ˆØ!Ÿ:š:Ð&8Ñ9Ô9ÐàÐ  ]Ð Ø×Ò˜m˜m¨IÑ6Ô6Ñ7Ô7Ð7Ð7ØÐ#¨Ð#Ø×Ò˜m˜m¨JÑ7Ô7Ñ8Ô8Ð8Ð8Øð 	9˜}ð 	9Ø×Ò˜m˜m¨EÑ2Ô2Ñ3Ô3Ð3Ð3Øð 	9˜ð 	9Ø×Ò˜m˜m¨EÑ2Ô2Ñ3Ô3Ð3Ð3Øð 	9˜ð 	9à×Ò˜m˜m¨EÑ2Ô2Ñ3Ô3Ð3Ð3ØÐ*Ø'8ˆJ�|Ñ$ð ð 	>Ý!%Ø ð =ÝÐ/µÑ6Ô6ð=à$×(Ò(¨Ñ3Ô3°uÐ<ñ"ô "Ðð
 &ð >Ø'�Ø#ð *­
Ð3CÅTÑ(JÔ(Jð *Ø*×.Ò.¨xÑ8Ô8Ð>¸B×EÒEÑGÔG×MÒMÑOÔO�BØÐ6Ð6Ð6Ø')˜Ø1=�
Ð-Ñ.ð &(ˆ
àŸ
š
 ?°EÑ:Ô:ˆØ—*’*˜Y¨Ñ.Ô.ˆØ!Ÿ:š:Ð&8¸%Ñ@Ô@ÐàŸšÐ$:Ñ;Ô;ˆØð 	4˜mð 	4Ø%3ˆJ�zÑ"ð ð 	Ø%)Ð"Øð 3¥JÐ/?ÅÑ$FÔ$Fð 3Ø#×'Ò'¨	Ñ2Ô2°eÐ;Ð;Ø-2Ð*àÐ%;ÐK˜	˜	Àð&ˆJ�zÑ"ð
 �:Š:Ð*¨EÑ2Ô2ð 	TØð TØ%ŸzšzÐ*BÑCÔC�ØÐ+Ø.:�J˜{Ñ+øà#Ð/ÝÐ.Ñ/Ô/�BØð 5 2§6¢6¨)Ñ#4Ô#4¸Ð#=Ð#=Øà24˜
 ;Ñ/Ð/à:>È(Ð.SÐ.S�J˜{Ñ+àð 	:Ø"8Ð!9ˆJ�vÑð —Z’ZÐ 0Ñ1Ô1ˆ
Øð 	,Ø —n’n Y°Ñ3Ô3ˆGØ!+ˆG�IÑØ$+ˆJ�yÑ!ð �:Š:Ð*¨EÑ2Ô2ð 	0Øð 0¥JÐ/?ÅÑ$FÔ$Fð 0Ø+×/Ò/°Ñ9Ô9Ð?¸R×FÒFÑHÔH×NÒNÑPÔP�Ø+×/Ò/°	¸4Ñ@Ô@�Ø˜fÒ$Ð$¨°EÐ(9Ð(9Ø*/�J˜wÑ'àð 	;Ø6:ˆJÐ2Ñ3ð —J’JÐ5Ñ6Ô6ˆ	Øð 	)Ø×Ò˜iÑ(Ô(Ð(àð 	2Ø'1ˆJ�|Ñ$ð —J’JÐ2Ñ3Ô3ˆ	Øð 	)Ø×Ò˜iÑ(Ô(Ð(àÐr   Úresponsec           	      ól  — |j         d         }|j        }|j        pd}d}|j        rËg }|j        D ]Á}i }t	          |dd¦  «        }	|	€,t          |d¦  «        r|j        pi                      d¦  «        }	|	�;t          |	d¦  «        r&	 |	                     ¦   «         }	n# t          $ r Y nw xY w|	|d<   | 
                    t          |j        |j        j        |j        j        |pd¬¦  «        ¦  «         ŒÂd}
t          |d¦  «        rS|j        rL|j        }t#          t	          |d	d¦  «        pdt	          |d
d¦  «        pdt	          |dd¦  «        pd¬¦  «        }
t	          |dd¦  «        }t	          |dd¦  «        }i }|r||d<   t	          |dd¦  «        }|r||d<   t%          |j        ||||
|pd¬¦  «        S )u¦  Normalize OpenAI ChatCompletion to NormalizedResponse.

        For chat_completions, this is near-identity â€” the response is already
        in OpenAI format.  extra_content on tool_calls (Gemini thought_signature)
        is preserved via ToolCall.provider_data.  reasoning_details (OpenRouter
        unified format) and reasoning_content (DeepSeek/Moonshot) are also
        preserved for downstream replay.
        r   ÚstopNÚextra_contentÚmodel_extraÚ
model_dump)ÚidÚnameÚ	argumentsÚprovider_dataÚusageÚprompt_tokensÚcompletion_tokensÚtotal_tokens)r�   r�   r‘   r[   Úreasoning_contentÚreasoning_details)Úcontentr   Úfinish_reasonr[   rŽ   r�   )ÚchoicesÚmessager•   r   ÚgetattrÚhasattrrˆ   r!   r‰   Ú	ExceptionÚappendr   rŠ   Úfunctionr‹   rŒ   rŽ   r   r   r”   )r   r„   r&   Úchoicer(   r•   r   r)   Útc_provider_dataÚextrarŽ   Úur[   r’   r�   Úrds                   r   Únormalize_responsez+ChatCompletionsTransport.normalize_response'  sD  € ð Ô! !Ô$ˆØŒnˆØÔ,Ð6°ˆàˆ
ØŒ>ð 	ØˆJØ”nð ð �ð
 46Ð Ý  O°TÑ:Ô:�Ø�=¥W¨R°Ñ%?Ô%?�=Øœ^Ð1¨r×6Ò6°ÑGÔG�EØÐ$Ý˜u lÑ3Ô3ð !ð!Ø$)×$4Ò$4Ñ$6Ô$6˜E˜EøÝ(ð !ð !ð !Ø ˜Dð!øøøà8=Ð$ _Ñ5Ø×!Ò!¥(Ø”uØœÔ)Ø œkÔ3Ø"2Ð":°dð	#ñ #ô #ñ ô ð ð ð ˆÝ�8˜WÑ%Ô%ð 	¨(¬.ð 	Ø”ˆAÝÝ% a¨¸!Ñ<Ô<ÐAÀÝ")¨!Ð-@À!Ñ"DÔ"DÐ"IÈÝ$ Q¨¸Ñ:Ô:Ð?¸aðñ ô ˆEõ ˜C ¨dÑ3Ô3ˆ	Ý# CÐ)<¸dÑCÔCÐà(*ˆØð 	CØ1BˆMÐ-Ñ.Ý�SÐ-¨tÑ4Ô4ˆØð 	4Ø13ˆMÐ-Ñ.å!Ø”KØ!Ø'ØØØ'Ð/¨4ð
ñ 
ô 
ð 	
s   ÂBÂ
B(Â'B(c                 óR   — |€dS t          |d¦  «        r|j        €dS |j        sdS dS )z&Check that response has valid choices.NFr–   T)r™   r–   )r   r„   s     r   Úvalidate_responsez*ChatCompletionsTransport.validate_responsen  sA   € àÐØ�5Ý�x Ñ+Ô+ð 	¨xÔ/?Ð/GØ�5ØÔð 	Ø�5Øˆtr   c                 ó¸   — t          |dd¦  «        }|€dS t          |dd¦  «        }|€dS t          |dd¦  «        pd}t          |dd¦  «        pd}|s|r||dœS dS )zAExtract OpenRouter/OpenAI cache stats from prompt_tokens_details.rŽ   NÚprompt_tokens_detailsÚcached_tokensr   Úcache_write_tokens)r§   Úcreation_tokens)r˜   )r   r„   rŽ   ÚdetailsÚcachedÚwrittens         r   Úextract_cache_statsz,ChatCompletionsTransport.extract_cache_statsx  sŠ   € å˜ '¨4Ñ0Ô0ˆØˆ=Ø�4Ý˜%Ð!8¸$Ñ?Ô?ˆØˆ?Ø�4Ý˜ /°1Ñ5Ô5Ð:¸ˆÝ˜'Ð#7¸Ñ;Ô;Ð@¸qˆØð 	I�Wð 	IØ%+ÀÐHÐHÐHØˆtr   r9   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚpropertyÚstrr   r   r   r   r+   r.   r   rƒ   r   r¢   rj   r¤   Úintr­   r   r   r   r   r      s³  € € € € € ðð ð
 ð"˜#ð "ð "ð "ñ „Xð"ð&¨¨d°3¸°8¬nÔ)=ð &ÈDÐQUÐVYÐ[^ÐV^ÔQ_ÔL`ð &ð &ð &ð &ðP 4¨¨S°#¨X¬Ô#7ð ¸DÀÀcÈ3ÀhÄÔ<Pð ð ð ð ð 15ð	Zð ZàðZð �t˜C ˜H”~Ô&ðZð ˜˜T # s (œ^Ô,Ô-ð	Zð 
ˆc�3ˆhŒðZð Zð Zð ZðxE
¨3ð E
Ð=Oð E
ð E
ð E
ð E
ðN¨#ð °$ð ð ð ð ð¨Cð °H¸TÀ#ÀsÀ(¼^Ô4Lð ð ð ð ð ð r   r   )Úregister_transportr   )r±   r#   Útypingr   r   r   r   Úagent.moonshot_schemar   r   Úagent.prompt_builderr	   Úagent.transports.baser
   Úagent.transports.typesr   r   r   r   Úagent.transportsrµ   r   r   r   ú<module>r¼      sû   ðð	ð 	ð €€€Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,à LÐ LÐ LÐ LÐ LÐ LÐ LÐ LØ 6Ð 6Ð 6Ð 6Ð 6Ð 6Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø FÐ FÐ FÐ FÐ FÐ FÐ FÐ FÐ FÐ Fðoð oð oð oð oÐ0ñ oô oð oðf 0Ð /Ð /Ð /Ð /Ð /à Ð Ð%Ð'?Ñ @Ô @Ð @Ð @Ð @r   