§
    øžyjÝ'  ã                  óÊ   — U d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	m
Z
 ddlZ ej        e¦  «        Zg d¢Zded<   g d	¢Zd
ed<   dd„Zdd„Zdd„Zdd„Zdd„Zddd„ZdS ) z8Codex model discovery from API, local cache, and config.é    )ÚannotationsN)ÚPath)ÚListÚOptional)úgpt-5.6-solúgpt-5.6-sol-proúgpt-5.6-terraúgpt-5.6-terra-proúgpt-5.6-lunaúgpt-5.6-luna-proúgpt-5.5úgpt-5.4-miniúgpt-5.4úgpt-5.3-codexúgpt-5.3-codex-sparkú	List[str]ÚDEFAULT_CODEX_MODELS)
)r   ©r   r   )r   r   )r	   r   )r
   r   )r   r   )r   r   )r   )r   r   r   )r   ©r   )r   r   )r   r   z!List[tuple[str, tuple[str, ...]]]Ú_FORWARD_COMPAT_TEMPLATE_MODELSÚ	model_idsÚreturnc                ó<  ‡— g }t          ¦   «         Š| D ]0}|‰vr*|                     |¦  «         ‰                     |¦  «         Œ1t          D ]O\  }}|‰v rŒ
t	          ˆfd„|D ¦   «         ¦  «        r*|                     |¦  «         ‰                     |¦  «         ŒP|S )a   Add Clawdbot-style synthetic forward-compat Codex models.

    If a newer Codex slug isn't returned by live discovery, surface it when an
    older compatible template model is present. This mirrors Clawdbot's
    synthetic catalog / forward-compat behavior for GPT-5 Codex variants.
    c              3  ó    •K  — | ]}|‰v V — Œ	d S ©N© )Ú.0ÚtemplateÚseens     €ú=/home/ragecks/.hermes/hermes-agent/hermes_cli/codex_models.pyú	<genexpr>z-_add_forward_compat_models.<locals>.<genexpr>Z   s(   øè è € Ð@Ð@ Hˆx˜4ÐÐ@Ð@Ð@Ð@Ð@Ð@ó    )ÚsetÚappendÚaddr   Úany)r   ÚorderedÚmodel_idÚsynthetic_modelÚtemplate_modelsr   s        @r    Ú_add_forward_compat_modelsr+   I   sÃ   ø€ ð €GÝ‘U”U€DØð ð ˆØ˜4ÐÐØ�NŠN˜8Ñ$Ô$Ð$Ø�HŠH�XÑÔÐøå,Kð &ð &Ñ(ˆ˜Ø˜dÐ"Ð"ØÝÐ@Ð@Ð@Ð@°Ð@Ñ@Ô@Ñ@Ô@ð 	&Ø�NŠN˜?Ñ+Ô+Ð+Ø�HŠH�_Ñ%Ô%Ð%øà€Nr"   Úaccess_tokenÚstrúOptional[str]c                óÆ  — 	 |                       d¦  «        }t          |¦  «        dk     rdS |d         dt          |d         ¦  «         dz  z  z   }t          j        t	          j        |¦  «        ¦  «        }t          |t          ¦  «        r)|                     di ¦  «                             d¦  «        nd}t          |t          ¦  «        r|r|ndS # t          $ r Y dS w xY w)	uÅ  Best-effort extraction of ``chatgpt_account_id`` from the OAuth JWT.

    The Codex backend requires the ``ChatGPT-Account-Id`` header for the
    per-account catalog. Without it, ``GET /backend-api/codex/models``
    returns ``{"models":[]}`` (HTTP 200) â€” which masquerades as "no
    models available" and silently degrades the picker to the curated
    fallback list. The request-side path in ``auxiliary_client.py``
    already extracts the same claim; this mirrors that logic here so the
    probe sees the same catalog the request path will actually use.

    Returns ``None`` on any parse error â€” the probe then degrades
    gracefully to the unauthenticated fallback list instead of crashing.
    ú.é   Né   Ú=é   zhttps://api.openai.com/authÚchatgpt_account_id)ÚsplitÚlenÚjsonÚloadsÚbase64Úurlsafe_b64decodeÚ
isinstanceÚdictÚgetr-   Ú	Exception)r,   ÚpartsÚpayload_b64ÚclaimsÚacct_ids        r    Ú_extract_chatgpt_account_idrD   a   sí   € ðØ×"Ò" 3Ñ'Ô'ˆÝˆu‰:Œ:˜Š>ˆ>Ø�4Ø˜A”h ­¨U°1¬X©¬¨¸Ñ(:Ñ!;Ñ;ˆÝ”�FÔ4°[ÑAÔAÑBÔBˆõ ˜&¥$Ñ'Ô'ðˆF�JŠJÐ4°bÑ9Ô9×=Ò=Ð>RÑSÔSÐSàð 	õ
 % W­cÑ2Ô2ÐH°wÐHˆwˆwÀDÐHøÝð ð ð Øˆtˆtðøøøs   ‚(C ¬B%C Ã
C ÃC c                ó  — 	 ddl }dd| › �i}t          | ¦  «        }|r||d<   |                     d|d¬¦  «        }|j        d	k    rg S |                     ¦   «         }t          |t          ¦  «        r|                     d
g ¦  «        ng }n4# t          $ r'}t           	                    d|¦  «         g cY d}~S d}~ww xY wg }|D �]}	t          |	t          ¦  «        sŒ|	                     d¦  «        }
t          |
t          ¦  «        r|
                     ¦   «         sŒX|
                     ¦   «         }
|	                     dd¦  «        }t          |t          ¦  «        r)|                     ¦   «                              ¦   «         dv rŒÀ|	                     d¦  «        }t          |t          t          f¦  «        rt          |¦  «        nd}|                     ||
f¦  «         �Œ|                     d„ ¬¦  «         t#          d„ |D ¦   «         ¦  «        S )zUFetch available models from the Codex API. Returns visible models sorted by priority.r   NÚAuthorizationzBearer zChatGPT-Account-IdzAhttps://chatgpt.com/backend-api/codex/models?client_version=1.0.0é
   )ÚheadersÚtimeoutéÈ   Úmodelsz)Failed to fetch Codex models from API: %sÚslugÚ
visibilityÚ >   ÚhideÚhiddenÚpriorityé'  c                ó"   — | d         | d         fS ©Nr   r2   r   )Úxs    r    ú<lambda>z(_fetch_models_from_api.<locals>.<lambda>§   s   €   1¤ q¨¤t € r"   ©Úkeyc                ó   — g | ]\  }}|‘ŒS r   r   )r   Ú_rL   s      r    ú
<listcomp>z*_fetch_models_from_api.<locals>.<listcomp>¨   s   € Ð&DÐ&DÐ&D±°°4 tÐ&DÐ&DÐ&Dr"   )ÚhttpxrD   r>   Ústatus_coder8   r<   r=   r?   ÚloggerÚdebugr-   ÚstripÚlowerÚintÚfloatr$   Úsortr+   )r,   r\   rH   rC   ÚrespÚdataÚentriesÚexcÚsortableÚitemrL   rM   rQ   Úranks                 r    Ú_fetch_models_from_apirl      s-  € ðØˆˆˆØ"Ð$<¨lÐ$<Ð$<Ð=ˆÝ-¨lÑ;Ô;ˆØð 	4Ø,3ˆGÐ(Ñ)Ø�yŠyØOØØð ñ 
ô 
ˆð
 Ô˜sÒ"Ð"ØˆIØ�yŠy‰{Œ{ˆÝ,6°t½TÑ,BÔ,BÐJ�$—(’(˜8 RÑ(Ô(Ð(ÈˆˆøÝð ð ð Ý�ŠÐ@À#ÑFÔFÐFØˆ	ˆ	ˆ	ˆ	ˆ	ˆ	øøøøðøøøð €HØð &ñ &ˆÝ˜$¥Ñ%Ô%ð 	ØØ�xŠx˜ÑÔˆÝ˜$¥Ñ$Ô$ð 	¨D¯JªJ©L¬Lð 	ØØ�zŠz‰|Œ|ˆð
 —X’X˜l¨BÑ/Ô/ˆ
Ý�j¥#Ñ&Ô&ð 	¨:×+;Ò+;Ñ+=Ô+=×+CÒ+CÑ+EÔ+EÐI[Ð+[Ð+[ØØ—8’8˜JÑ'Ô'ˆÝ *¨8µc½5°\Ñ BÔ BÐN�s�8‰}Œ}ˆ}ÈˆØ�Š˜˜t˜Ñ%Ô%Ð%Ñ%à‡M‚MÐ,Ð,€MÑ-Ô-Ð-Ý%Ð&DÐ&D¸8Ð&DÑ&DÔ&DÑEÔEÐEs%   ‚AB
 ÁAB
 Â

B;ÂB6Â0B;Â6B;Ú
codex_homer   c                ó´  — | dz  }|                      ¦   «         sd S 	 dd l}n# t          $ r Y d S w xY w	 |                     |                     d¬¦  «        ¦  «        }n# t          $ r Y d S w xY wt          |t          ¦  «        r|                     d¦  «        nd }t          |t          ¦  «        r(| 	                    ¦   «         r| 	                    ¦   «         S d S )Nzconfig.tomlr   úutf-8©ÚencodingÚmodel)
ÚexistsÚtomllibr?   r9   Ú	read_textr<   r=   r>   r-   r`   )rm   Úconfig_pathrt   Úpayloadrr   s        r    Ú_read_default_modelrx   «   sû   € Ø˜}Ñ,€KØ×ÒÑÔð ØˆtðØˆˆˆˆøÝð ð ð ØˆtˆtðøøøðØ—-’- × 5Ò 5¸wÐ 5Ñ GÔ GÑHÔHˆˆøÝð ð ð Øˆtˆtðøøøå$.¨w½Ñ$=Ô$=ÐGˆG�KŠK˜Ñ Ô Ð À4€EÝ�%�ÑÔð  %§+¢+¡-¤-ð Ø�{Š{‰}Œ}ÐØˆ4s   �" ¢
0¯0´)A Á
A,Á+A,c                óè  — | dz  }|                      ¦   «         sg S 	 t          j        |                     d¬¦  «        ¦  «        }n# t          $ r g cY S w xY wt          |t          ¦  «        r|                     d¦  «        nd }g }t          |t          ¦  «        �r|D �]}t          |t          ¦  «        sŒ|                     d¦  «        }t          |t          ¦  «        r| 
                    ¦   «         sŒX| 
                    ¦   «         }|                     d¦  «        }t          |t          ¦  «        r)| 
                    ¦   «                              ¦   «         dv rŒ¿|                     d¦  «        }t          |t          t          f¦  «        rt          |¦  «        nd	}	|                     |	|f¦  «         �Œ|                     d
„ ¬¦  «         g }
|D ]\  }}||
vr|
                     |¦  «         Œ|
S )Nzmodels_cache.jsonro   rp   rK   rL   rM   >   rO   rP   rQ   rR   c                ó"   — | d         | d         fS rT   r   )rj   s    r    rV   z$_read_cache_models.<locals>.<lambda>Ú   s   €  D¨¤G¨T°!¬WÐ#5€ r"   rW   )rs   r8   r9   ru   r?   r<   r=   r>   Úlistr-   r`   ra   rb   rc   r$   rd   )rm   Ú
cache_pathÚrawrg   ri   rj   rL   rM   rQ   rk   ÚdedupedrZ   s               r    Ú_read_cache_modelsr   ½   sÿ  € ØÐ1Ñ1€JØ×ÒÑÔð Øˆ	ðÝŒj˜×-Ò-°wÐ-Ñ?Ô?Ñ@Ô@ˆˆøÝð ð ð Øˆ	ˆ	ˆ	ðøøøõ $.¨cµ4Ñ#8Ô#8ÐBˆc�gŠg�hÑÔÐ¸d€GØ€HÝ�'�4Ñ Ô ñ *Øð 	*ñ 	*ˆDÝ˜d¥DÑ)Ô)ð ØØ—8’8˜FÑ#Ô#ˆDÝ˜d¥CÑ(Ô(ð °·
²
±´ð ØØ—:’:‘<”<ˆDð Ÿš ,Ñ/Ô/ˆJÝ˜*¥cÑ*Ô*ð ¨z×/?Ò/?Ñ/AÔ/A×/GÒ/GÑ/IÔ/IÐM_Ð/_Ð/_ØØ—x’x 
Ñ+Ô+ˆHÝ$.¨x½#½u¸Ñ$FÔ$FÐR•3�x‘=”=�=ÈFˆDØ�OŠO˜T 4˜LÑ)Ô)Ð)Ñ)à‡M‚MÐ5Ð5€MÑ6Ô6Ð6Ø€GØð !ð !‰ˆˆ4Ø�wÐÐØ�NŠN˜4Ñ Ô Ð øØ€Ns   �(A ÁAÁAc                ó&  — t          j        dd¦  «                             ¦   «         p"t          t	          j        ¦   «         dz  ¦  «        }t	          |¦  «                             ¦   «         }g }| r t          | ¦  «        }|rt          |¦  «        S t          |¦  «        }|r| 
                    |¦  «         t          |¦  «        D ]}||vr| 
                    |¦  «         Œt          D ]}||vr| 
                    |¦  «         Œt          |¦  «        S )zÃReturn available Codex model IDs, trying API first, then local sources.
    
    Resolution order: API (live, if token provided) > config.toml default >
    local cache > hardcoded defaults.
    Ú
CODEX_HOMErN   z.codex)ÚosÚgetenvr`   r-   r   ÚhomeÚ
expanduserrl   r+   rx   r$   r   r   )r,   Úcodex_home_strrm   r'   Ú
api_modelsÚdefault_modelr(   s          r    Úget_codex_model_idsr‰   â   s  € õ ”Y˜|¨RÑ0Ô0×6Ò6Ñ8Ô8ÐW½CÅÄ	ÁÄÈhÑ@VÑ<WÔ<W€NÝ�nÑ%Ô%×0Ò0Ñ2Ô2€JØ€Gð ð :Ý+¨LÑ9Ô9ˆ
Øð 	:Ý-¨jÑ9Ô9Ð9õ (¨
Ñ3Ô3€MØð &Ø�Š�}Ñ%Ô%Ð%å& zÑ2Ô2ð %ð %ˆØ˜7Ð"Ð"Ø�NŠN˜8Ñ$Ô$Ð$øå(ð %ð %ˆØ˜7Ð"Ð"Ø�NŠN˜8Ñ$Ô$Ð$øå% gÑ.Ô.Ð.r"   )r   r   r   r   )r,   r-   r   r.   )r,   r-   r   r   )rm   r   r   r.   )rm   r   r   r   r   )r,   r.   r   r   )Ú__doc__Ú
__future__r   r:   r8   ÚloggingÚpathlibr   Útypingr   r   r‚   Ú	getLoggerÚ__name__r^   r   Ú__annotations__r   r+   rD   rl   rx   r   r‰   r   r"   r    ú<module>r’      s]  ðØ >Ð >Ð >à "Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø !Ð !Ð !Ð !Ð !Ð !Ð !Ð !à 	€	€	€	à	ˆÔ	˜8Ñ	$Ô	$€ð&#ð &#ð &#Ð ð &ð &ð &ñ &ðPFð Fð FÐ ð ð ð ñ ð$ð ð ð ð0ð ð ð ð<)Fð )Fð )Fð )FðXð ð ð ð$"ð "ð "ð "ðJ/ð /ð /ð /ð /ð /ð /r"   