
    ?ib                     @   d Z ddlZddlmZmZmZmZ ddlmZm	Z	m
Z
 dZg dZdd	gZd
ZdddZdedeeedf      fdZdedefdZ	 	 	 ddededee   deee      def
dZ	 	 	 ddededee   deee      def
dZ	 	 ddedeee      deee      deeee   f   fdZy)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.1zgpt-5zgpt-4.1zgpt-4ozgpt-5.1-codex-minir   zhttps://api.x.ai/v1/modelszgrok-4-1-fast)lateststablemodel_idreturn.c                     t        j                  d|       }|r0t        d |j                  d      j	                  d      D              S y)zParse 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   2   K   | ]  }t        |        y w)N)int).0xs     Q/home/ubuntu/.openclaw/workspace/skills/last30days-official/scripts/lib/models.py	<genexpr>z parse_version.<locals>.<genexpr>   s     ?SV?s   r   .N)researchtuplegroupsplit)r   matchs     r   parse_versionr      s?     II((3E?U[[^%9%9#%>???    c                 t    | j                         }t        j                  d|      syg d}|D ]  }||v s y y)zFCheck if model is a mainline GPT model (not mini/nano/chat/codex/pro).z^gpt-(?:4o|4\.1|5)(\.\d+)*$F)mininanochatcodexpropreviewturboT)lowerr   r   )r   model_lowerexcludesexcs       r   is_mainline_openai_modelr,   #   sI    .."K 882K@ LH + r   api_keypolicypinmock_modelsc           	         |dk(  r|r|S t        j                  d      }|r|S ||}n5	 dd|  i}t        j                  t        |      }|j                  dg       }|D cg c]   }t        |j                  dd	            s|" }	}|	s	t        d   S d
 }
|	j                  |
d       |	d   d   }t        j                  d|       |S # t        j
                  $ r t        d   cY S w xY wc c}w )a	  Select 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datar   id c                 l    t        | j                  dd            xs d}| j                  dd      }||fS )Nr7   r8   )r   createdr   )r   get)mversionr:   s      r   sort_keyz%select_openai_model.<locals>.sort_keya   s6    dB08D%%	1%!!r   T)keyreverse)
r   get_cached_modelr	   r;   OPENAI_MODELS_URL	HTTPErrorOPENAI_FALLBACK_MODELSr,   sortset_cached_model)r-   r.   r/   r0   cachedmodelsr5   responser<   
candidatesr>   selecteds               r   select_openai_modelrL   4   s   " c
 ##H-F 	-&''(;<Gxx 17CH\\&"-F $Q'?dB'P!QJQ%a(("
 OO$O/!}T"H 
8X.O/ ~~ 	-)!,,	-
 Rs   4C	 ! C+C+	C('C(c                     |dk(  r|r|S |t         v r:t         |   }t        j                  d      }|r|S t        j                  d|       |S t         d   S )a  Select 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
    r2   xair   )XAI_ALIASESr   rA   rF   )r-   r.   r/   r0   aliasrG   s         r   select_xai_modelrQ   o   se    " c
 F# ''.M 	ue, x  r   configmock_openai_modelsmock_xai_modelsc                    ddd}| j                  d      r| j                  d      t        j                  k(  r=| j                  dd      }| j                  d      }|dk(  r|r||d	<   n@t        d
   |d	<   n3t	        | d   | j                  dd      | j                  d      |      |d	<   | j                  d      r3t        | d   | j                  dd      | j                  d      |      |d<   |S )zdGet selected models for both providers.

    Returns:
        Dict with 'openai' and 'xai' keys
    N)r3   rN   OPENAI_API_KEYOPENAI_AUTH_SOURCEOPENAI_MODEL_POLICYautoOPENAI_MODEL_PINr2   r3   r   XAI_API_KEYXAI_MODEL_POLICYr   XAI_MODEL_PINrN   )r;   r
   AUTH_SOURCE_CODEXCODEX_FALLBACK_MODELSrL   rQ   )rR   rS   rT   resultr.   r/   s         r   
get_modelsra      s     T*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   )rY   NN)r   NN)NN)__doc__r   typingr   r   r   r   r8   r   r	   r
   rB   rD   r_   XAI_MODELS_URLrO   strr   r   boolr,   rL   rQ   ra    r   r   <module>rh      s`   0 	 . .   7 M -y9  .C HU38_$= s t & (,	888 
#8 $t*%	8
 	8z (,	"!"!"! 
#"! $t*%	"!
 	"!N 04,0%% d,% d4j)% 
#x}
	%r   