+
    ib                         R t ^ RIt^ RIHtHtHtHt ^RIHtH	t	H
t
 Rt. ROtRR.tRtRR	R
R	/tR R ltR R ltRR R lltRR R lltRR R lltR# )z*Model auto-selection for last30days skill.N)DictListOptionalTuple)cachehttpenvz https://api.openai.com/v1/modelsgpt-5.2zgpt-5.1-codex-minizhttps://api.x.ai/v1/modelslatestzgrok-4-1-faststablec                `    V ^8  d   QhR\         R\        \        \        R3,          ,          /# )   model_idreturn.)strr   r   int)formats   "R/Users/bowang/.openclaw/workspace/skills/last30days-official/scripts/lib/models.py__annotate__r      s'      C HU38_$=     c                   \         P                  ! RV 4      pV'       di   \        ;QJ d2    . R VP                  ^4      P	                  R4       4       F  NK  	  5# ! R VP                  ^4      P	                  R4       4       4      # R# )ztParse semantic version from model ID.

Examples:
    gpt-5 -> (5,)
    gpt-5.2 -> (5, 2)
    gpt-5.2.1 -> (5, 2, 1)
z(\d+(?:\.\d+)*)c              3   8   "   T F  p\        V4      x  K  	  R # 5i)N)r   ).0xs   & r   	<genexpr> parse_version.<locals>.<genexpr>   s     ?%>SVV%>s   .N)researchtuplegroupsplit)r   matchs   & r   parse_versionr#      sc     II((3Eu?U[[^%9%9#%>?u?u?U[[^%9%9#%>???r   c                0    V ^8  d   QhR\         R\        /# )r   r   r   )r   bool)r   s   "r   r   r   #   s      s t r   c                    V P                  4       p\        P                  ! RV4      '       g   R# . ROpV F  pW19   g   K   R# 	  R# )zFCheck if model is a mainline GPT model (not mini/nano/chat/codex/pro).z^gpt-(?:4o|4\.1|5)(\.\d+)*$FT)mininanochatcodexpropreviewturbo)lowerr   r"   )r   model_lowerexcludesexcs   &   r   is_mainline_openai_modelr2   #   sE    .."K 882K@@ LH  r   c          
          V ^8  d   QhR\         R\         R\        \         ,          R\        \        \        ,          ,          R\         /# r   api_keypolicypinmock_modelsr   r   r   r   r   )r   s   "r   r   r   4   sG     8 888 
#8 $t*%	8
 	8r   c           	     H   VR8X  d   V'       d   V# \         P                  ! R4      pV'       d   V# Ve   TpM6 RRV  2/p\        P                  ! \        VR7      pVP                  R. 4      pV Uu. uF(  p\        VP                  RR4      4      '       g   K&  VNK*  	  p	pV	'       g   \        ^ ,          # R	 p
V	P                  V
R
R7       V	^ ,          R,          p\         P                  ! RV4       V#   \        P
                   d    \        ^ ,          u # i ; iu upi )zSelect the best OpenAI model based on policy.

Args:
    api_key: OpenAI API key
    policy: 'auto' or 'pinned'
    pin: Model to use if policy is 'pinned'
    mock_models: Mock model list for testing

Returns:
    Selected model ID
pinnedopenaiAuthorizationzBearer )headersdataid c                 v    \        V P                  R R4      4      ;'       g    RpV P                  R^ 4      pW3# )r@   rA   created)    )r#   get)mversionrC   s   &  r   sort_key%select_openai_model.<locals>.sort_keya   s7    dB088D%%	1%!!r   T)keyreverse)
r   get_cached_modelr   rE   OPENAI_MODELS_URL	HTTPErrorOPENAI_FALLBACK_MODELSr2   sortset_cached_model)r5   r6   r7   r8   cachedmodelsr>   responserF   
candidatesrH   selecteds   &&&&        r   select_openai_modelrW   4   s
   " c
 ##H-F 	-&''(;<Gxx 17CH\\&"-F $QV'?dB'P!!VJQ%a(("
 OO$O/!}T"H 
8X.O/ ~~ 	-)!,,	-
 Rs   5C7 3#DD7"DDc          
          V ^8  d   QhR\         R\         R\        \         ,          R\        \        \        ,          ,          R\         /# r4   r9   )r   s   "r   r   r   o   sG     "! "!"!"! 
#"! $t*%	"!
 	"!r   c                    VR8X  d   V'       d   V# V\         9   dG   \         V,          p\        P                  ! R4      pV'       d   V# \        P                  ! RV4       V# \         R,          # )zSelect the best xAI model based on policy.

Args:
    api_key: xAI API key
    policy: 'latest', 'stable', or 'pinned'
    pin: Model to use if policy is 'pinned'
    mock_models: Mock model list for testing

Returns:
    Selected model ID
r;   xair
   )XAI_ALIASESr   rL   rQ   )r5   r6   r7   r8   aliasrR   s   &&&&  r   select_xai_modelr]   o   se    " c
 F# ''.M 	ue, x  r   c                    V ^8  d   QhR\         R\        \        \         ,          ,          R\        \        \         ,          ,          R\         \        \        \        ,          3,          /# )r   configmock_openai_modelsmock_xai_modelsr   )r   r   r   r   )r   s   "r   r   r      sP     % %% d,% d4j)% 
#x}
	%r   c                "   RRRR/pV P                  R4      '       d   V P                  R4      \        P                  8X  dI   V P                  RR4      pV P                  R4      pVR	8X  d   V'       d   WSR&   MH\        ^ ,          VR&   M7\	        V R,          V P                  RR4      V P                  R4      V4      VR&   V P                  R
4      '       d8   \        V R
,          V P                  RR4      V P                  R4      V4      VR&   V# )zXGet selected models for both providers.

Returns:
    Dict with 'openai' and 'xai' keys
r<   NrZ   OPENAI_API_KEYOPENAI_AUTH_SOURCEOPENAI_MODEL_POLICYautoOPENAI_MODEL_PINr;   XAI_API_KEYXAI_MODEL_POLICYr
   XAI_MODEL_PIN)rE   r   AUTH_SOURCE_CODEXCODEX_FALLBACK_MODELSrW   r]   )r_   r`   ra   resultr6   r7   s   &&&   r   
get_modelsrn      s     eT*Fzz"##::*+s/D/DDZZ 5v>F**/0C!c#&x #8#;x 2'(

0&9

-."	 F8 zz-  (=!JJ)84JJ'	
u Mr   )r	   zgpt-5.1zgpt-5zgpt-4.1zgpt-4o)rf   NN)r
   NN)NN)__doc__r   typingr   r   r   r   rA   r   r   r   rM   rO   rl   XAI_MODELS_URLr[   r#   r2   rW   r]   rn    r   r   <module>rs      sh    0 	 . .   7 M -y9  .oo"8v"!J% %r   