
    `gj+                        d Z ddlmZ ddlZddlmZ ddlmZ  ej                  e	      Z
dZe G d d             Zdd	Zdd
ZddZddZdd	 	 	 	 	 ddZy)a  Shared logic for the /codex-runtime slash command.

Toggles `model.openai_runtime` between "auto" (= chat_completions, Hermes'
default) and "codex_app_server" (= hand turns to a codex subprocess).

Both CLI (cli.py) and gateway (gateway/run.py) call into this module so the
behavior stays identical across surfaces.

The actual runtime resolution happens in hermes_cli.runtime_provider's
_maybe_apply_codex_app_server_runtime() helper, which reads the persisted
config value. This module just persists the value and reports the change.
    )annotationsN)	dataclass)Optional)autocodex_app_serverc                  p    e Zd ZU dZded<   dZded<   dZded<   dZd	ed
<   dZded<   dZ	ded<   dZ
ded<   y)CodexRuntimeStatuszResult of a /codex-runtime invocation. Callers render this however
    suits their surface (CLI uses Rich panels, gateway sends a text message).boolsuccessNOptional[str]	new_value	old_value strmessageFrequires_new_sessionTcodex_binary_okcodex_version)__name__
__module____qualname____doc____annotations__r   r   r   r   r   r        R/root/.hermes/venv/lib/python3.12/site-packages/hermes_cli/codex_runtime_switch.pyr	   r	      sL    Q M#I}##I}#GS!&$& OT #'M='r   r	   c                    | xs dj                         j                         }|sdg fS |dv rdg fS |dv rdg fS |t        v r|g fS dd|dgfS )	u   Parse the slash-command argument string. Returns (value, errors).

    No args         → return current state (value=None)
    'auto' / 'codex_app_server' / 'on' / 'off' → return that value
    anything else   → error
    r   N>   oncodexenabler   >   offhermesdefaultdisabler   zUnknown runtime z-. Use one of: auto, codex_app_server, on, off)striplowerVALID_RUNTIMES)
arg_stringraws     r   
parse_argsr*   (   s     
"
"
$
*
*
,CRx
''!2%%
55rz
nBw
3'!NO  r   c                    t        | t              sy| j                  d      xs i }t        |t              syt        |j                  d      xs d      j	                         j                         }|t        v r|S y)z}Read the current `model.openai_runtime` value from a config dict.
    Returns 'auto' for unset / empty / unrecognized values.r   modelopenai_runtimer   )
isinstancedictgetr   r%   r&   r'   )config	model_cfgvalues      r   get_current_runtimer4   >   sl     fd#

7#)rIi&	./526<<>DDFEr   c                    |t         vrt        d|dt                t        |       }t        | j	                  d      t
              si | d<   || d   d<   |S )zMutate the config dict in place to persist the new runtime value.
    Returns the previous value for callers that want to report a delta.zinvalid runtime z; must be one of r,   r-   )r'   
ValueErrorr4   r.   r0   r/   )r1   r   olds      r   set_runtimer8   L   sg     &ym+<^<LM
 	
 f
%Cfjj)40w(1F7O$%Jr   c                 X    	 ddl m}   |        S # t        $ r}dd| fcY d}~S d}~ww xY w)zqBest-effort verification that codex CLI is installed at acceptable
    version. Returns (ok, version_or_message).r   )check_codex_binaryFzcodex check failed: N)!agent.transports.codex_app_serverr:   	Exception)r:   excs     r   check_codex_binary_okr>   Z   s6    3H!## 3,SE2223s    	)$)))persist_callbackc               ~   t        |       }dd,fd}|: |       \  }}d| d|rd|z   nd|xs dz    }t        d|||||r|	      S d	      S ||cxk(  xr d
k(  nc }||k(  r|st        d||d|       S |d
k(  r% |       \  }}	|st        dd|d|	xs d ddd	      S |st        | |       |		  ||        |rd| dg}n	d| d| g}|d
k(  r |       \  }}|r|j                  d|        	 ddlm}  ||       }|j                  D cg c]
  }|dk7  s	| }}|r/|j                  dt        |       ddj                  |              |j                  rD|j                  dt        |j                         ddj                  |j                                n*|j                  r|j                  d|j                          |j                  r|j                  d|j                   d       d|j                  v r"|j                  d        |j                  d!       |j                  d"|j                   d#       |j                   D ]  }|j                  d$|         	 |j                  d&       |j                  d'       n"|j                  d(       |j                  d)       t        d||d*j                  |      d+      S # t        $ r1}
t        j                  d       t        d||d|
       cY d}
~
S d}
~
ww xY wc c}w # t        $ r}
|j                  d%|
        Y d}
~
d}
~
ww xY w)-a  Top-level entry point used by both CLI and gateway handlers.

    Args:
        config: in-memory config dict (will be mutated when new_value is set)
        new_value: desired runtime; None means "show current state only"
        persist_callback: optional callable taking the mutated config dict
            and persisting it to disk. Skipped when None (used by tests).

    Returns: CodexRuntimeStatus describing the outcome.
    Nc                       
t                 S )N)r>   )_binary_checks   r   _check_binary_cachedz#apply.<locals>._check_binary_cached}   s     13Mr   zopenai_runtime: z
codex CLI: zOK u   not available — z%install with `npm i -g @openai/codex`T)r   r   r   r   r   r   r   zopenai_runtime already set to )r   r   r   r   Fz(Cannot enable codex_app_server runtime: zcodex CLI not availablez%
Install with: npm i -g @openai/codexz'failed to persist openai_runtime changez-updated config in memory but persist failed: u    — re-applying migrationu    → zcodex CLI: r   )migratezhermes-toolsz	Migrated z MCP server(s): z, z native Codex plugin(s): z Codex plugin discovery skipped: zDefault sandbox: z$ (no approval prompt on every write)zHermes tool callback registered: codex can now use web_search, web_extract, browser_*, vision_analyze, image_generate, skill_view, skills_list, text_to_speech, kanban_* (worker + orchestrator) via MCP.u|     (delegate_task, memory, session_search, todo run only on the default Hermes runtime — they need the agent loop context.)z  (config: )u   ⚠ MCP migration: u   ⚠ MCP migration skipped: zOpenAI/Codex turns now run through `codex app-server` (terminal/file ops/patching inside Codex; Hermes tools available via MCP callback).ud   Effective on next session — current cached agent keeps the prior runtime to preserve prompt cache.z7OpenAI/Codex turns will use the default Hermes runtime.zEffective on next session.
)r   r   r   r   r   returnztuple[bool, Optional[str]])r4   r	   r8   r<   logger	exceptionappend)hermes_cli.codex_runtime_plugin_migrationrD   migratedlenjoinmigrated_pluginsplugin_query_errorwrote_permissions_defaulttarget_patherrors)r1   r   r?   currentrC   okvermsgreapplying_enable
ver_or_msgr=   	msg_linesrD   
mig_reportsuser_serverserrrB   s                    @r   applyr`   e   s&     "&)G ;?M &(Cwi ()+%#+1EIwPw1xy{ 	 "!##
 	
 *.
 	
$ "WB0BBG$5!4WI>	
 	
 &&-/J%!>!>%>? @;; !&"  FI&'	 ( ,WI5OP
	 (yi[AB	&&&(C{3%01/	BI J &..!~2EL    L 122Byy./1
 **  J$?$? @A B((,		*2M2M(N'OQ ..  6!4457 33  '
(L(L'M N: ; !4!44  @   +
 {:+A+A*B!DE!(( >  #6se!<=> 	8	

 	:	

 	RS56		)$! i    !JK)!'%KC5Q	 :R  	B:3%@AA	BsO   5K 7L 
LL"EL 	L&LLLL 	L<L77L<)r(   r   rH   ztuple[Optional[str], list[str]])r1   r/   rH   r   )r1   r/   r   r   rH   r   rG   )r1   r/   r   r   rH   r	   )r   
__future__r   loggingdataclassesr   typingr   	getLoggerr   rI   r'   r	   r*   r4   r8   r>   r`   r   r   r   <module>rf      s    #  ! 			8	$ . 
( 
( 
(,3 	rrr
 rr   