
    `gj#                    X   U d Z ddlmZ ddlmZ ddlmZmZmZm	Z	 dZ
dZdddd	dddd	dd
dd	dddd	dd
dd	dddd	dddd	dddd	dZded<    ed       G d d             ZddZddZddZddZddlZddlmZ ddlZ ed       G d d             Zd dZ	 d!	 	 	 	 	 	 	 d"dZy)#uO  Detect xAI models retired on May 15, 2026.

Source: https://docs.x.ai/developers/migration/may-15-retirement

Pure logic: walks a Hermes config dict, returns issues for any reference
to a retired xAI model. No I/O, no CLI dependencies — testable in isolation
and reusable from both `hermes doctor` and a future `hermes migrate xai`.
    )annotations)	dataclass)AnyDictListOptionalz8https://docs.x.ai/developers/migration/may-15-retirementzMay 15, 2026zgrok-4.3N)replacementreasoning_effortnotenonezgrok-imagine-image-quality)zgrok-4-0709zgrok-4-fast-reasoningzgrok-4-fast-non-reasoningzgrok-4-1-fast-reasoningzgrok-4-1-fast-non-reasoningzgrok-code-fast-1zgrok-3zgrok-imagine-image-proz#Dict[str, Dict[str, Optional[str]]]_RETIRED_MODELST)frozenc                  L    e Zd ZU dZded<   ded<   ded<   dZded<   dZded	<   y)
RetirementIssuez<A reference to a retired xAI model found in a Hermes config.strconfig_pathcurrent_modelr	   NOptional[str]r
   r   )__name__
__module____qualname____doc____annotations__r
   r        L/root/.hermes/venv/lib/python3.12/site-packages/hermes_cli/xai_retirement.pyr   r   #   s,    F&*m*D-r   r   c                    | j                         j                         }dD ]$  }|j                  |      s|t        |      d } |S  |S )uE   Strip provider prefix (``x-ai/grok-4`` → ``grok-4``) and lowercase.)zx-ai/zxai/N)striplower
startswithlen)model_idmprefixs      r   
_normalizer%   .   sP     A# <<#f+,AH	 Hr   c                x    t        | t              r| j                         syt        |       j	                  d      S )NFzgrok-)
isinstancer   r   r%   r    )r"   s    r   _looks_like_xair(   8   s.    h$HNN,<h**733r   c                   g dfd}t        | t              sS | j                  d      }t        |t              r |d|j                  d             | j                  d      }t        |t              rE|j                         D ]2  \  }}t        |t              s |d| d|j                  d             4 | j                  d      }t        |t              r |d	|j                  d             | j                  d
      }t        |t              r9|j                  d      }t        |t              r |d|j                  d             | j                  d      }	t        |	t              rZ|	j                  d      }
t        |
t              r9|
j                  d      }t        |t              r |d|j                  d             S )u'  Walk all model slots in a Hermes config and return retirement issues.

    Slots scanned:
      - ``principal.model``
      - ``auxiliary.<any>.model`` (introspective — covers future aux slots)
      - ``delegation.model``
      - ``tts.xai.model``
      - ``plugins.image_gen.xai.model``
    modelc                    t        |      sy t        |      }t        j                  |      }|y j	                  t        | ||d   |j                  d      |j                  d                   y )Nr	   r
   r   )r   r   r	   r
   r   )r(   r%   r   getappendr   )pathr*   normentryissuess       r   _checkz%find_retired_xai_refs.<locals>._checkJ   sj    u%% ##D)=om,"YY'9:6"
 	r   	principalzprincipal.model	auxiliaryz
auxiliary.z.model
delegationzdelegation.modelttsxaiztts.xai.modelplugins	image_genzplugins.image_gen.xai.model)r.   r   r*   r   returnNone)r'   dictr,   items)configr2   r3   aux	slot_nameslot_cfgr5   r6   tts_xair8   r9   ig_xair1   s               @r   find_retired_xai_refsrD   >   sw    %'F fd#

;'I)T" )--"89
**[
!C#t#&99; 	NIx(D)I;f5x||G7LM	N L)J*d#!:>>'#:;
**U
C#t''%.gt$?GKK$89jj#G'4 KK,	i&]]5)F&$'4fjj6IJMr   c                "   | j                    d| j                  d| j                  g}| j                  r|j	                  d| j                   d       | j
                  r|j	                  d| j
                   d       dj                  |      S )z8One-line human-readable rendering of a retirement issue.z: u	    → use z(set reasoning_effort: "z")z[note: ] )r   r   r	   r
   r-   r   join)issuepartss     r   format_issuerK   {   s     
R 3 36i@Q@Q?TUE /0F0F/GrJKzzwuzzl!,-88E?r   )Pathc                  :    e Zd ZU dZded<   ded<   ded<   ded	<   y
)ApplyResultz#Outcome of an apply_migration call.rL   	file_pathzOptional[Path]backup_pathList[RetirementIssue]issues_resolvedboolconfig_changedN)r   r   r   r   r   r   r   r   rN   rN      s    -O**r   rN   c                    |j                  d      }t        |      dk  rt        d|      | }|dd D ],  }t        |t              r||vrt        d|d|      ||   }. ||d   fS )zResolve a dotted slot path to (parent_mapping, leaf_key).

    Example: "auxiliary.vision.model" -> (yaml_doc["auxiliary"]["vision"], "model").
    Raises KeyError if any intermediate node is missing or not a mapping.
    .   z$Path must have at least one parent: NzPath segment z missing in )splitr!   
ValueErrorr'   r<   KeyError)yaml_docdotted_pathrJ   nodesegments        r   _walk_to_parentr`      s     c"E
5zA~?OPPD": $%)<]7+\+QRRG} r?r   c                   ddl m} t        |       } | j                         st	        |       |st        | dg d      S  |d      }d|_        | j                  d	d
      5 }|j                  |      }ddd       t        | dg d      S g }|D ]W  }	 t        ||j                        \  }	}
|j                  |	|
<   |j                  r|j                  |	d<   |j                  |       Y |st        | dg d      S d}|rct        j                   j#                         j%                  d      }| j'                  | j(                   d|       }t+        j,                  | |       ddlm}  ||        | j                  dd
      5 }|j3                  ||       ddd       t        | ||d      S # 1 sw Y   <xY w# t        $ r Y 6w xY w# 1 sw Y   5xY w)aX  Rewrite ``config_path`` in-place so each issue is resolved.

    For every issue, the model name is replaced by ``issue.replacement``. If the
    issue has ``reasoning_effort`` set (i.e. the migration is from a
    ``*-non-reasoning`` variant), a sibling ``reasoning_effort`` key is added
    or updated alongside the model.

    Uses ``ruamel.yaml`` round-trip mode so comments, key order, indentation,
    and type literals (booleans, ints) are preserved.

    A backup copy is written to
    ``<config_path>.bak-pre-migrate-xai-YYYYMMDD-HHMMSS`` before rewriting,
    unless ``backup=False``.
    r   )YAMLNF)rO   rP   rR   rT   rt)typTrzutf-8)encodingr
   z%Y%m%d-%H%M%Sz.bak-pre-migrate-xai-)$require_readable_config_before_writew)ruamel.yamlrb   rL   existsFileNotFoundErrorrN   preserve_quotesopenloadr`   r   r[   r	   r
   r-   _dtdatetimenowstrftime	with_namenameshutilcopy2hermes_cli.configrg   dump)r   r1   backuprb   yamlfhdocresolvedrI   parentleafrP   tsrg   s                 r   apply_migrationr      s   & !{#K,,! 	
 	
 D>DD			#		0 Biim {! 	
 	
 ')H 		*30A0ABLFD ((t!!).)?)?F%&	 ! 	
 	
 #'K\\((9!++  5bT:
 	[+.F(5			#		0 B		#r  	 [   		6 s*   !F-F:G
-F7:	GG
G)r"   r   r:   r   )r"   r   r:   rS   )r>   zDict[str, Any]r:   rQ   )rI   r   r:   r   )r\   r   r]   r   r:   z'tuple[Any, str]')T)r   rL   r1   rQ   ry   rS   r:   rN   )r   
__future__r   dataclassesr   typingr   r   r   r   MIGRATION_GUIDE_URLRETIREMENT_DATEr   r   r   r%   r(   rD   rK   rp   ro   pathlibrL   ru   rN   r`   r   r   r   r   <module>r      s+   # ! , , Q   5?TXcg$h4>TXcg$h4>TZdh$i4>TXcg$h4>TZdh$i4>TXcg$h4>TXcg$h4Pfjtx$y	84 	 $  4:z	     $  ( UU!U U 	Ur   