+
    iHàj?B  ã            
       ó  € R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H
t
 ^ RIHtHtHt ^ RIHt ^ RIHtHt ^ RIHtHt ]P0                  ! R4      tRR	0tR
R0tRRRRRRRRRR/tR R ltR R ltR R lt ! R R4      t R# )zýImage-part handling for ``AIAgent`` API messages.

Vision capability probes, non-vision text fallbacks (cached ``vision_analyze`` descriptions), tool-result
image stripping, and provider quirks (Anthropic dot preservation, Qwen portal message shaping).
N)ÚPath)ÚAnyÚListÚOptional)Úforward_static)Ú_is_multimodal_tool_resultÚ_multimodal_text_summary)Úbase_url_host_matchesÚbase_url_hostnameÚ	run_agentÚ	image_urlÚinput_imageÚtextÚ
input_textz	image/pngz.pngz	image/gifz.gifz
image/webpz.webpú
image/jpegú.jpgz	image/jpgc                ó0   € V ^8„  d   QhR\         R\        /# )é   ÚpartÚreturn©r   Úbool)Úformats   "Ú>/home/ubuntu/.hermes/hermes-agent/agent/vision_message_prep.pyÚ__annotate__r      s   € ÷ Lñ Lœð L¤ñ Ló    c                 ób   € \        V \        4      ;'       d    V P                  R 4      \        9   # )Útype)Ú
isinstanceÚdictÚgetÚ_IMAGE_PART_TYPES)r   s   &r   Ú_is_image_partr"      s&   € Ü�dœDÓ!×KÐK d§h¡h¨vÓ&6Ô:KÑ&KÐKr   c                óR   € V ^8„  d   QhR\         R\        R\         \        ,          /# )r   ÚcontentÚany_dict_textr   )Úlistr   Ústr)r   s   "r   r   r   #   s%   € ÷ ñ ¤ð ¼ð Ä$ÄsÅ)ñ r   c               ó|  € . pV  F³  p\        V\        4      '       d   VP                  4       pMn\        V\        4      '       dW   V'       g   VP	                  R4      \
        9   d5   \        VP	                  RR4      ;'       g    R4      P                  4       pMK˜  V'       g   K¢  VP                  V4       Kµ  	  V# )zStripped, non-empty text from string parts and text-typed dict parts (or any dict's
``text`` when ``any_dict_text``), in order.r   r   Ú )r   r'   Ústripr   r    Ú_TEXT_PART_TYPESÚappend)r$   r%   Útextsr   r   s   &$   r   Ú_salvage_text_partsr.   #   sŒ   € ð €EÛˆÜ�dœC× Ò Ø—:‘:“<‰DÜ˜œd×#Ò#¯¸$¿(¹(À6Ó:JÔN^Ô:^Ü�t—x‘x ¨Ó+×1Ð1¨rÓ2×8Ñ8Ó:‰Dáß‰4Ø�L‰L˜Öñ ð €Lr   c                óR   € V ^8„  d   QhR\         R\        \        \        3,          /# )r   Úagentr   )r   Útupler'   )r   s   "r   r   r   3   s"   € ÷ ñ œsð ¤u¬S´#¨X¥ñ r   c                ó²   € \        V RR4      ;'       g    RP                  4       P                  4       \        V RR4      ;'       g    RP                  4       3# )zœ``(provider.lower(), model)`` as recorded in ``_no_list_tool_content_models``.
Module-level so ``MagicMock(spec=AIAgent)`` agents in tests don't swallow it.Úproviderr)   Úmodel)Úgetattrr*   Úlower)r0   s   &r   Ú_provider_model_keyr7   3   sQ   € ô 
�˜
 BÓ	'×	-Ð	-¨2×4Ñ4Ó6×<Ñ<Ó>Ü	�˜ Ó	$×	*Ð	*¨×1Ñ1Ó3ðð r   c                   óZ  a € ] tR t^<t o Rt]V 3R lR l4       tR$t]V 3R lR l4       tV 3R lR lt	V 3R lR	 lt
V 3R
 lR ltV 3R lR ltR%V 3R lR lltV 3R lR lt]tV 3R lR lt]! RR4      tRR/V 3R lR lltV 3R lR ltV 3R lR ltV 3R lR  ltV 3R! lR" ltR#tV tR# )&ÚVisionMessagePrepMixinzRVision probes + image-part fallbacks for outgoing messages (see module docstring).c                ó&   <€ V ^8„  d   QhRS[ RS[/# )r   r$   r   r   )r   Ú__classdict__s   "€r   r   Ú#VisionMessagePrepMixin.__annotate__@   s   ø€ ÷ [ñ [©#ð [±$ñ [r   c                óš   € \        V \        4      ;'       d5    \        ;QJ d    R  V  4       F  '       g   K   R# 	  R# ! R  V  4       4      # )c              3   ó8   "  € T F  p\        V4      x € K  	  R # 5i©N)r"   )Ú.0r   s   & r   Ú	<genexpr>ÚBVisionMessagePrepMixin._content_has_image_parts.<locals>.<genexpr>A   s   é € Ð0ZÑRYÈ$´À×1EÐ1EÓRYùs   ‚TF)r   r&   Úany)r$   s   &r   Ú_content_has_image_partsÚ/VisionMessagePrepMixin._content_has_image_parts?   s<   € ä˜'¤4Ó(×ZÐZ¯S«SÑ0ZÑRYÓ0Z¯S¬SÐZªSÐZ¨SÑ0ZÑRYÓ0ZÓ-ZÐZr   c                óL   <€ V ^8„  d   QhRS[ RS[S[ S[S[,          3,          /# )r   r   r   )r'   r1   r   r   )r   r;   s   "€r   r   r<   G   s*   ø€ ÷ (ñ (±Cð (¹EÁ#ÁxÑPTÅ~ÐBUÕ<Vñ (r   c                óT  € \        T ;'       g    R 4      P                  R4      w  rp\        V4      \        P                  8”  d"   \
        P                  R\        V4      4       R# VP                  R4      '       d4   V\        R4      R P                  R^4      ^ ,          P                  4       MR p\        P                  VP                  R4      '       d   TMRR4      p\        P                  ! R	VR
R7      p V;_uu_ 4        VP                  \        P                   ! V4      4       RRR4       TP(                  \-        TP(                  4      3#   + '       g   i     L1; i  \"         d5     \$        P&                  ! TP(                  4       h   \*         d     h i ; ii ; i)r)   Ú,z/data-URL payload too large (%d bytes), skippingNúdata:Ú;zimage/r   r   Úanthropic_image_F)ÚprefixÚsuffixÚdelete)r)   N)r'   Ú	partitionÚlenr9   Ú_MAX_DATA_URL_BASE64_BYTESÚloggerÚwarningÚ
startswithÚsplitr*   Ú_DATA_URL_SUFFIXESr    ÚtempfileÚNamedTemporaryFileÚwriteÚbase64Ú	b64decodeÚ	ExceptionÚosÚunlinkÚnameÚOSErrorr   )r   ÚheaderÚ_ÚdataÚmimerM   Útmps   &      r   Ú _materialize_data_url_for_visionÚ7VisionMessagePrepMixin._materialize_data_url_for_visionF   sK  € ä˜iŸo˜o¨2Ó.×8Ñ8¸Ó=‰ˆ�4Üˆt‹9Ô-×HÑHÔHÜ�N‰NÐLÌcÐRVËiÔXØˆOØAG×ARÑARÐSZ×A[ÒA[ˆv”c˜'“l�mÐ$×*Ñ*¨3°Ó2°1Õ5×;Ñ;Ô=ÐacˆÜ#×'Ñ'°·±À×0IÒ0I©È|Ð]cÓdˆÜ×)Ò)Ð1CÈFÐ[`Ôaˆð
	ß’Ø—	‘	œ&×*Ò*¨4Ó0Ô1÷ ð �x‰xœ˜cŸh™h›Ð'Ð'÷ —ûäô 	ðÜ—	’	˜#Ÿ(™(Ô#ð øô ô ØØðúð	úsN   Ã<
E( Ä&EÄ,E( ÅE%	Å E( Å%E( Å(F'Å4 FÆF'ÆF#Æ F'Æ"F#Æ#F'c                ó,   <€ V ^8„  d   QhRS[ RS[ RS[ /# )r   r   Úroler   ©r'   )r   r;   s   "€r   r   r<   \   s#   ø€ ÷ 'ñ 'Áð 'É3ð 'ÑSVñ 'r   c                óL  € \         P                  ! \        T;'       g    R 4      P                  R4      4      P	                  4       pV P
                  P                  V4      pV'       d   V# RRRR/P                  VR4      pRp\        T;'       g    R 4      pVP                  R4      pRp	V'       d   V P                  V4      w  ry ^ R	I	H
p
 \        P                  ! V
! WvR
7      4      p\        V\        4      '       d   \        P                  ! V4      M/ pVP                  R4      ;'       g    R P!                  4       pV	'       d(   V	P%                  4       '       d    V	P'                  4        RT RT;'       g    R R2pT'       d   T'       g   TRT R2,          pYðP
                  T&   T#   \"         d   pRT 2p Rp?L„Rp?ii ; i  \(         d     Lji ; i  T	'       d;   T	P%                  4       '       d$    T	P'                  4        i   \(         d     i i ; ii i ; i)r)   zutf-8Ú	assistantÚtoolztool resultÚuserzªDescribe everything visible in this image in thorough detail. Include any text, code, UI, data, objects, people, layout, colors, and any other notable visual information.rI   N)Úvision_analyze_tool)r   Úuser_promptÚanalysiszImage analysis failed: z[The z- attached an image. Here's what it contains:
zImage analysis failed.Ú]z@
[If you need a closer look, use vision_analyze with image_url: )ÚhashlibÚsha256r'   ÚencodeÚ	hexdigestÚ_anthropic_image_fallback_cacher    rT   rf   Útools.vision_toolsro   ÚasyncioÚrunr   ÚjsonÚloadsr*   r\   Úexistsr^   r`   )Úselfr   ri   Ú	cache_keyÚcachedÚ
role_labelÚanalysis_promptÚvision_sourceÚis_data_urlÚcleanup_pathro   Úresult_jsonÚresultÚdescriptionÚeÚnotes   &&&             r   Ú&_describe_image_for_anthropic_fallbackÚ=VisionMessagePrepMixin._describe_image_for_anthropic_fallback\   sî  € Ü—N’N¤3 y§ °BÓ#7×#>Ñ#>¸wÓ#GÓH×RÑRÓTˆ	Ø×5Ñ5×9Ñ9¸)ÓDˆßØˆMà! ;°¸ÐF×JÑJÈ4ÐQWÓXˆ
ð8ð 	ô ˜IŸO˜O¨Ó,ˆØ#×.Ñ.¨wÓ7ˆØ'+ˆßØ*.×*OÑ*OÐP]Ó*^Ñ'ˆMð	Ý>ä!Ÿ+š+Ñ&9ÀMÔ&oÓpˆKÜ0:¸;Ì×0LÒ0L”T—Z’Z Ô,ÐRTˆFØ!Ÿ:™: jÓ1×7Ð7°R×>Ñ>Ó@ˆK÷  × 3Ñ 3× 5Ò 5ðØ ×'Ñ'Ô)ð �z�lÐ"PÐQ\×QxÐQxÐ`xÐPyÐyzÐ{ˆß§ØÐWÐXeÐWfÐfgÐhÕhˆDà:>×,Ñ,¨YÑ7Øˆøô ô 	8Ø3°A°3Ð7�Kûð	8ûô ô Ùðû÷  × 3Ñ 3× 5Ò 5ðØ ×'Ñ'Õ)øÜô Ùðúð !6ˆ|úsg   ÃA(F1 Ä1F1 Å!G Æ1GÆ<GÇG ÇGÇG ÇGÇGÇH#Ç?HÈH#ÈHÈH#ÈHÈH#c                ó    <€ V ^8„  d   QhRS[ /# ©r   r   ©r   )r   r;   s   "€r   r   r<   …   s   ø€ ÷ 
ñ 
©ñ 
r   c                óô   €  ^ RI Hp ^ RIHp \	        V RR4      ;'       g    RP                  4       p\	        V RR4      ;'       g    RP                  4       pV! W4V! 4       4      RJ #   \         d     R# i ; i)zˆTrue if the active provider+model reports native vision (config override
> models.dev; see ``image_routing._supports_vision_override``).)Úload_config)Ú_lookup_supports_visionr3   r)   r4   TF)Úhermes_cli.configr‘   Úagent.image_routingr’   r5   r*   r\   )r~   r‘   r’   r3   r4   s   &    r   Ú_model_supports_visionÚ-VisionMessagePrepMixin._model_supports_vision…   sq   € ð	Ý5ÝCÜ  j°"Ó5×;Ð;¸×BÑBÓDˆHÜ˜T 7¨BÓ/×5Ð5°2×<Ñ<Ó>ˆEÙ*¨8¹K»MÓJÈdÐRÐRøÜô 	Úð	ús   ‚A( ¢$A( Á A( Á(A7Á6A7c                ó    <€ V ^8„  d   QhRS[ /# rŽ   r�   )r   r;   s   "€r   r   r<   ‘   s   ø€ ÷ ñ ¹ñ r   c                óÜ   €  ^ RI Hp T! \        V RR4      ;'       g    RP                  4       \        V RR4      ;'       g    RP                  4       4      '       * #   \         d     R# i ; i)zÀTrue if the active provider accepts list-type tool content (some, e.g. Xiaomi MiMo, take
multimodal user messages but 400 on list-type tool content; profile ``supports_vision_tool_messages``).)Ú)routed_model_rejects_vision_tool_messagesr3   r)   r4   T)Ú	providersr™   r5   r*   r\   )r~   r™   s   & r   Ú'_provider_supports_vision_tool_messagesÚ>VisionMessagePrepMixin._provider_supports_vision_tool_messages‘   sm   € ð	ÝKÙ@Ü˜˜z¨2Ó.×4Ð4°"×;Ñ;Ó=Ü˜˜w¨Ó+×1Ð1¨r×8Ñ8Ó:óô ð øô ô 	ØÙð	ús   ‚A ž#A ÁA ÁA+Á*A+c                ó,   <€ V ^8„  d   QhRS[ RS[RS[ /# )r   r$   ri   r   )r   r'   )r   r;   s   "€r   r   r<   ž   s'   ø€ ÷ oñ o±Sð oÁð oÉñ or   c                óR  € V P                  V4      '       g   V# . p\        \        V4       F|  pVP                  R / 4      p\	        V\
        4      '       d   VP                  RR4      M\        T;'       g    R4      pTP                  V'       d   V P                  Wb4      MR4       K~  	  RP                  R V 4       4      P                  4       pRP                  \        VRR7      4      P                  4       pV'       d   V'       d   V RV 2# T;'       g    T;'       g    R	# )
r   Úurlr)   z:[An image was attached but no image source was available.]ú

c              3   ó8   "  € T F  q'       g   K  Vx € K  	  R # 5ir?   © )r@   rŠ   s   & r   rA   ÚGVisionMessagePrepMixin._preprocess_anthropic_content.<locals>.<genexpr>«   s   é € ÐB©k d»TŸTšT«kùs   ‚	�
Ú
T©r%   zI[A multimodal message was converted to text for Anthropic compatibility.])rD   Úfilterr"   r    r   r   r'   r,   r‹   Újoinr*   r.   )	r~   r$   ri   Úimage_notesr   Ú
image_datar   rL   rM   s	   &&&      r   Ú_preprocess_anthropic_contentÚ4VisionMessagePrepMixin._preprocess_anthropic_contentž   sø   € Ø×,Ñ,¨W×5Ò5ØˆNà!#ˆÜœ>¨7Ö3ˆDØŸ™ +¨rÓ2ˆJÜ5?À
ÌD×5QÒ5Q˜
Ÿ™ u¨bÔ1ÔWZÐ[e×[kÐ[kÐikÓWlˆIØ×ÑßPY�×;Ñ;¸IÔLØQöñ 4ð —‘ÑB©kÓBÓB×HÑHÓJˆØ—‘Ô.¨wÀdÔKÓL×RÑRÓTˆß—fØ�X˜T & Ð*Ð*Ø×nÐn˜×nÐnÐ#nÐnr   Nc                ó.   <€ V ^8„  d   QhRS[ R,          /# )r   Úapi_modeNrj   )r   r;   s   "€r   r   r<   ±   s   ø€ ÷ 	ñ 	¡s¨T¥zñ 	r   c                ó¶   € T;'       g    V P                   p\        V RR4      pVf	   / ;q0n        VP                  V4      f   ^ RIHp V! V4      W2&   W2,          # )z]Return the cached transport for the given (or current) api_mode (lazy; None if unregistered).Ú_transport_cacheN)Úget_transport)r­   r5   r¯   r    Úagent.transportsr°   )r~   r­   ÚmodeÚcacher°   s   &&   r   Ú_get_transportÚ%VisionMessagePrepMixin._get_transport±   sW   € à×(Ð(˜4Ÿ=™=ˆÜ˜Ð0°$Ó7ˆØŠ=Ø,.Ð.ˆEÔ)Ø�9‰9�T‹?Ò"Ý6Ù'¨Ó-ˆE‰KØ�{Ðr   c                ó&   <€ V ^8„  d   QhRS[ RS[ /# ©r   Úapi_messagesr   ©r&   )r   r;   s   "€r   r   r<   ¼   s   ø€ ÷ ñ Á4ð ÉDñ r   c           
     ó´  a € \         ;QJ d    V 3R lV 4       F  '       g   K   RM	  RM! V 3R lV 4       4      '       d   S P                  4       '       d   V# \        P                  ! V4      pV Fb  p\	        V\
        4      '       g   K  S P                  VP                  R4      \        VP                  RR4      ;'       g    R4      4      VR&   Kd  	  V# )zÀReplace native image parts with cached vision_analyze text when the active model lacks vision;
vision-capable models pass through unchanged (the provider adapter handles image parts natively).c              3   ó”   <"  € T F=  p\        V\        4      ;'       d!    SP                  VP                  R 4      4      x € K?  	  R# 5i)r$   N)r   r   rD   r    )r@   Úmsgr~   s   & €r   rA   ÚPVisionMessagePrepMixin._prepare_messages_for_non_vision_model.<locals>.<genexpr>¿   s<   øé € ð 
ÙcoÐ\_ŒJ�sœDÓ!×WÐW d×&CÑ&CÀCÇGÁGÈIÓDVÓ&WÔWÓcoùs
   ƒAŸ)ATFr$   ri   rn   )	rC   r•   ÚcopyÚdeepcopyr   r   rª   r    r'   )r~   r¸   Útransformedr¼   s   f&  r   Ú&_prepare_messages_for_non_vision_modelÚ=VisionMessagePrepMixin._prepare_messages_for_non_vision_model¼   s°   ø€ ÷ ‹sô 
Ùcoó
�s�sŠsô 
Ùcoó
÷ 
ò 
à×(Ñ(×*Ò*ØÐä—m’m LÓ1ˆÛˆCÜ˜#œt×$Ô$Ø!%×!CÑ!CØ—G‘G˜IÓ&¬¨C¯G©G°F¸FÓ,C×,MÐ,MÀvÓ(Nó"��I“ñ ð
 Ðr   c                ó,   <€ V ^8„  d   QhRS[ RS[RS[/# )r   Ú	tool_namer‡   r   )r'   r   )r   r;   s   "€r   r   r<   Ï   s#   ø€ ÷ /ñ /¹sð /ÉCð /ÑTWñ /r   c           	     ó¦  € \        V4      '       g   V# VP                  R4      ;'       g    . pV P                  V4      '       g   V# V P                  4       '       d�   V P	                  4       '       g.   \
        P                  RV\        V RR4      4       \        V4      # \        V 4      pT\        V RR4      ;'       g    R9   d1   \
        P                  RW^ ,          V^,          4       \        V4      # V# \        V4      pVR8X  d   \        P                  ! R	R
RV/4      # \
        P                  RWP                  V P                  4       V# )z¼Tool message content that is safe for the active model. Text-only providers must not receive
image parts: a rejected tool result becomes canonical history and can break the next user turn.r$   uT   Tool %s: provider %s does not accept list-type tool content â€” sending text summaryr3   r)   Ú_no_list_tool_content_modelsNua   Tool %s: model %s/%s known to reject list-type tool content this session â€” sending text summaryÚcomputer_useÚerrorzÎcomputer_use returned screenshot/image content, but the active model/provider does not support image input. Switch to a vision-capable model for desktop computer use, or use browser tools for browser tasks.Útext_summaryzWTool %s returned image content for non-vision model %s/%s; falling back to text summaryr¢   )r   r    rD   r•   r›   rR   Údebugr5   r   r7   r{   ÚdumpsrS   r3   r4   )r~   rÄ   r‡   r$   ÚkeyÚsummarys   &&&   r   Ú%_tool_result_content_for_active_modelÚ<VisionMessagePrepMixin._tool_result_content_for_active_modelÏ   s?  € ô *¨&×1Ò1ØˆMà—*‘*˜YÓ'×-Ð-¨2ˆØ×,Ñ,¨W×5Ò5ØˆNà×&Ñ&×(Ò(ð ×?Ñ?×AÒAÜ—‘ð7àœw t¨Z¸Ó<ôô
 0°Ó7Ð7Ü% dÓ+ˆCØ”w˜tÐ%CÀTÓJ×PÐPÈbÔQÜ—‘ðDà 1�v s¨1¥vôô
 0°Ó7Ð7ØˆNä*¨6Ó2ˆØ˜Ô&Ü—:’:Øð/ð
  ðó ð ô 	�‰ð+à—}‘} d§j¡jô	
ð
 ˆr   zagent.conversation_compressionÚ"try_shrink_image_parts_in_messagesÚremember_modelTc                ó,   <€ V ^8„  d   QhRS[ RS[RS[/# )r   r¸   rÑ   r   )r&   r   )r   r;   s   "€r   r   r<     s%   ø€ ÷ $ñ $Ù ð$Ù59ð$á	ñ$r   c               ó  € \        V\        4      '       g   R# V'       dW   \        V 4      p\        V R4      '       g   \	        4       V n        V^,          '       d   V P
                  P                  V4       RpV F†  p\        V\        4      '       d   VP                  R4      R8w  d   K1  VP                  R4      pV P                  V4      '       g   K[  RP                  \        VRR7      4      ;'       g    RVR&   R	pKˆ  	  V# )
u  Downgrade list-type tool messages to text in place; True if any were downgraded.

Recovery for providers that 400 on list-type tool content (e.g. MiMo "text is not set"). By default
records (provider, model) in ``_no_list_tool_content_models`` so later results downgrade without a
round-trip; 413 recovery passes ``remember_model=False`` (body too large â‰  provider rejects lists).
FrÆ   ri   rm   r$   r    r¥   uS   [image content removed â€” provider does not accept list-type tool message content]T)r   r&   r7   ÚhasattrÚsetrÆ   Úaddr   r    rD   r§   r.   )r~   r¸   rÑ   rÌ   Úchangedr¼   r$   s   &&$    r   Ú)_try_strip_image_parts_from_tool_messagesÚ@VisionMessagePrepMixin._try_strip_image_parts_from_tool_messages  sã   € ô ˜,¬×-Ò-Ùçä% dÓ+ˆCÜ˜4Ð!?×@Ò@Ü47³E�Ô1Ø�1�vŒvØ×1Ñ1×5Ñ5°cÔ:àˆÛˆCÜ˜c¤4×(Ò(¨C¯G©G°F«O¸vÔ,EÙØ—g‘g˜iÓ(ˆGà×0Ñ0°×9Ò9Ùð $Ÿ[™[Ô)<¸WÐTYÔ)ZÓ[÷ ð ð2ð �	‰Nð ŠGñ  ð ˆr   c                ó    <€ V ^8„  d   QhRS[ /# rŽ   r�   )r   r;   s   "€r   r   r<   (  s   ø€ ÷ 
ñ 
©$ñ 
r   c                óò  € \        V RR4      ;'       g    RP                  4       R9   d   R# \        V RR4      ;'       g    RP                  4       p\        V4      pRV9   ;'       g�    \        VR4      ;'       g|    RV9   ;'       go    \        VR4      ;'       d    R	V9   ;'       gN    \        VR
4      ;'       g:    \        VR4      ;'       g&    \        VR4      ;'       g    VP	                  R4      # )a7  True for anthropic-compatible endpoints that keep dots in model names (DashScope, MiniMax, Xiaomi
MiMo, OpenCode Go/Zen, ZAI/Zhipu; Bedrock's dotted inference-profile IDs 400 on the hyphenated form).

Alibaba/DashScope keeps dots (e.g. qwen3.5-plus). OpenCode Go/Zen keeps dots for non-Claude models
(e.g. minimax-m2.5-free). ``global.anthropic.claude-opus-4-7``,
``us.anthropic.claude-sonnet-4-5-20250929-v1:0``) and rejects the hyphenated form with ``HTTP 400
The provided model identifier is invalid``. Regression for #11976; mirrors the opencode-go fix for
#5211
r3   r)   ÚminimaxTÚbase_urlÚ	dashscopezaliyuncs.comzopencode.aiz/zen/zbigmodel.cnzxiaomimimo.comzaiplatform.googleapis.comzbedrock-runtime.>	   ÚzaiÚvertexÚxiaomiÚalibabaÚbedrockrÜ   ú
minimax-cnúopencode-goúopencode-zen)r5   r6   r
   r	   rT   )r~   ÚbaseÚhosts   &  r   Ú_anthropic_preserve_dotsÚ/VisionMessagePrepMixin._anthropic_preserve_dots(  s  € ô �D˜* bÓ)×/Ð/¨R×6Ñ6Ó8ð =
ô 
ñ Ü˜˜j¨"Ó-×3Ð3°×:Ñ:Ó<ˆÜ  Ó&ˆà˜4Ñ÷ 3ð 3Ü$ T¨>Ó:÷3ð 3à˜DÑ ÷3ð 3ô & d¨MÓ:×NÐN¸wÈ$¹÷3ð 3ô % T¨=Ó9÷	3ð 3ô
 % TÐ+;Ó<÷3ð 3ô % TÐ+FÓG÷3ð 3ð �‰Ð1Ó2ð	
r   c                ó    <€ V ^8„  d   QhRS[ /# rŽ   r�   )r   r;   s   "€r   r   r<   G  s   ø€ ÷ Mñ M¡ñ Mr   c                ó.   € \        V P                  R4      # )z2Return True when the base URL targets Qwen Portal.zportal.qwen.ai)r	   Ú_base_url_lower)r~   s   &r   Ú_is_qwen_portalÚ&VisionMessagePrepMixin._is_qwen_portalG  s   € ä$ T×%9Ñ%9Ð;KÓLÐLr   c                ó&   <€ V ^8„  d   QhRS[ RS[ /# r·   r¹   )r   r;   s   "€r   r   r<   K  s   ø€ ÷ ñ ¹ð Áñ r   c                óT   € \         P                  ! V4      pV P                  V4       V# )zUDeep-copy ``api_messages`` and shape them for Qwen Portal (see the in-place variant).)r¾   r¿   Ú#_qwen_prepare_chat_messages_inplace)r~   r¸   Úprepareds   && r   Ú_qwen_prepare_chat_messagesÚ2VisionMessagePrepMixin._qwen_prepare_chat_messagesK  s#   € ä—=’= Ó.ˆØ×0Ñ0°Ô:Øˆr   c                ó$   <€ V ^8„  d   QhRS[ RR/# )r   Úmessagesr   Nr¹   )r   r;   s   "€r   r   r<   Q  s   ø€ ÷ ñ ¹Dð ÀTñ r   c           	     óÂ  € V F¿  p\        V\        4      '       g   K  VP                  R4      p\        V\        4      '       d   RRRV/.VR&   KN  \        V\        4      '       g   Kf  V Uu. uF?  p\        V\        \        34      '       g   K!  \        V\        4      '       d   RRRV/MTNKA  	  ppV'       g   K»  WRR&   KÁ  	  V FŽ  p\        V\        4      '       g   K  VP                  R4      R8X  g   K3  VP                  R4      p\        V\        4      '       d4   V'       d,   \        VR	,          \        4      '       d   RR/VR	,          R&    R# 	  R# u upi )
uº   Qwen Portal shaping, in place: every content becomes a list of parts (bare strings â†’ text
dicts, dicts kept), then ``cache_control`` is injected on the last part of the system message.r$   r   r   ri   ÚsystemÚ	ephemeralÚcache_controlNéÿÿÿÿ)r   r   r    r'   r&   )r~   r÷   r¼   r$   r   Únormalized_partss   &&    r   rò   Ú:VisionMessagePrepMixin._qwen_prepare_chat_messages_inplaceQ  s)  € ó ˆCÜ˜c¤4×(Ò(ÙØ—g‘g˜iÓ(ˆGÜ˜'¤3×'Ò'Ø#)¨6°6¸7Ð"CÐ!D��I“Ü˜G¤T×*Ô*ñ !(ó$á '˜¬:°d¼SÄ$¸K×+Hô V´jÀÄs×6KÒ6K�V˜V V¨TÑ2ÐQUÒUÙ 'ð !ð $÷ $Ñ#Ø%5˜	“Nñ ó ˆCÜ˜#œt×$Ô$¨¯©°«¸HÖ)DØŸ'™' )Ó,�Ü˜g¤t×,Ò,·¼ZÈÐPRÍÔUY×=ZÒ=ZØ4:¸KÐ3H�G˜B•K Ñ0Úó ùò$s   Á-EÂ"E)rÆ   r¯   i  @r?   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚstaticmethodrD   rQ   rf   r‹   r•   r›   rª   r´   rÁ   Ú#_prepare_anthropic_messages_for_apirÎ   Ú_forward_staticÚ#_try_shrink_image_parts_in_messagesrØ   ré   rî   rô   rò   Ú__static_attributes__Ú__classdictcell__)r;   s   @r   r9   r9   <   sÞ   ø‡ € Ù\à÷[ó ð[ð "2Ðà÷(ó ð(÷*'ð '÷R
ð 
÷ð ÷oð o÷&	ò 	÷ð ð" +QÐ'÷/ð /ñb +:Ð:Zð  ]Aó  +BÐ'ð$Ø<@÷$ò $÷L
ð 
÷>Mð M÷ð ÷ö r   r9   )!r  Úloggingry   rZ   r¾   rs   r{   r]   rW   Úpathlibr   Útypingr   r   r   Úagent.lazy_forwardr   r  Úagent.tool_dispatch_helpersr   r   Úutilsr	   r
   Ú	getLoggerrR   r!   r+   rV   r"   r.   r7   r9   r¢   r   r   Ú<module>r     sš   ðñó
 Û Û Û Û Û Û 	Û Ý ß &Ñ &å @ß \ß :ð 
×	Ò	˜;Ó	'€à  -Ð0Ð Ø˜LÐ)Ð à�˜ f¨l¸GÀ\ÐSYÐ[fÐhnðÐ õ
Lõõ ÷kó kr   