
    [j                       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	 ddl
mZ ddlmZ ddlmZ  e	d	
           G d d                      Z e	d	
           G d d                      ZddZddZ G d de          ZdS )an  Shared Hermes-side execution flow for Modal transports.

This module deliberately stops at the Hermes boundary:
- command preparation
- cwd/timeout normalization
- stdin/sudo shell wrapping
- common result shape
- interrupt/cancel polling

Direct Modal and managed Modal keep separate transport logic, persistence, and
trust-boundary decisions in their own modules.
    )annotationsN)abstractmethod)	dataclass)Any)BaseEnvironment)is_interruptedT)frozenc                  @    e Zd ZU dZded<   ded<   ded<   dZded	<   dS )
PreparedModalExeczCNormalized command data passed to a transport-specific exec runner.strcommandcwdinttimeoutN
str | None
stdin_data)__name__
__module____qualname____doc____annotations__r        @/home/ice/.hermes/hermes-agent/tools/environments/modal_utils.pyr   r      sD         MMLLLHHHLLL!J!!!!!!r   r   c                  0    e Zd ZU dZdZded<   dZded<   dS )ModalExecStartz*Transport response after starting an exec.Nz
Any | Nonehandledict | Noneimmediate_result)r   r   r   r   r   r   r   r   r   r   r   r   %   s;         44F$(((((((r   r   r   r   r   returnc                    dt          j                    j        dd          }||v r'dt          j                    j        dd          }||v '|  d| d| d| S )zDAppend stdin as a shell heredoc for transports without stdin piping.HERMES_EOF_N   z << 'z'

)uuiduuid4hex)r   r   markers      r   wrap_modal_stdin_heredocr)   -   s|    14:<<+BQB/11F
J

5tz||/355 J

==F==z==V===r   
sudo_stdinc                Z    dt          j        |                                           d|  S )zFFeed sudo via a shell pipe for transports without direct stdin piping.zprintf '%s\n' z | )shlexquoterstrip)r   r*   s     r   wrap_modal_sudo_piper/   5   s.    KU[):):)<)<==KK'KKKr   c                      e Zd ZU dZdZdZdZded<   dZdZ		 d-ddd
ddd.dZ
d/dZd	dddd0dZd1d"Zd2d#Zd3d$Zed4d'            Zed5d+            Zed6d,            ZdS )7BaseModalExecutionEnvironmentu  Execution flow for the *managed* Modal transport (gateway-owned sandbox).

    This deliberately overrides :meth:`BaseEnvironment.execute` because the
    tool-gateway handles command preparation, CWD tracking, and env-snapshot
    management on the server side.  The base class's ``_wrap_command`` /
    ``_wait_for_process`` / snapshot machinery does not apply here — the
    gateway owns that responsibility.  See ``ManagedModalEnvironment`` for the
    concrete subclass.
    payloadg      ?Nzfloat | None_client_timeout_grace_secondsz[Command interrupted]zModal execution error TF)r   r   rewrite_compound_backgroundbounded_capturer   r   r   r   
int | Noner   r   r5   boolr6   r    dictc               ~   |}|}|                                   |                     ||||          }	 |                     |          }	n6# t          $ r)}
|                     | j         d|
           cY d }
~
S d }
~
ww xY w|	j        |	j        S |	j        |                     | j         d          S d }| j        #t          j
                    |j        z   | j        z   }t          j
                    }||d}	 t                      rG	 |                     |	j                   n# t          $ r Y nw xY w|                     | j        d          S 	 |                     |	j                  }n6# t          $ r)}
|                     | j         d|
           cY d }
~
S d }
~
ww xY w||S |]t          j
                    |k    rF	 |                     |	j                   n# t          $ r Y nw xY w|                     |j                  S 	 ddlm}  ||d	           n# t          $ r Y nw xY wt          j        | j                   I)
Nr   r   r   z: z): transport did not return an exec handle)
last_touchstartT   r   )touch_activity_if_duezmodal command running)_before_execute_prepare_modal_exec_start_modal_exec	Exception_error_result_unexpected_error_prefixr   r   r3   time	monotonicr   r   _cancel_modal_exec_result_interrupt_output_poll_modal_exec_timeout_result_for_modaltools.environments.baser?   sleep_poll_interval_seconds)selfr   r   r   r   r5   r6   _preparedr=   excdeadline_now_activity_stateresultr?   s                   r   executez%BaseModalExecutionEnvironment.executeK   s    (
 ++!	 , 
 
	Q**844EE 	Q 	Q 	Q%%)F&O&O#&O&OPPPPPPPP	Q !-))<%%0[[[   -9~''(*::T=__H~
 

	4 A++EL9999    D||D$:C@@@U..u|<< U U U))T-J*S*Sc*S*STTTTTTTTU !#(8(8H(D(D++EL9999    D55h6FGGGIIIIII%%o7NOOOO    Jt2333=	4sq   A	 	
A<A71A<7A<D   
D-,D-E' '
F1FFF;G 
G#"G#H 
H! H!Nonec                    dS )z8Hook for backends that need pre-exec sync or validation.Nr   )rP   s    r   r@   z-BaseModalExecutionEnvironment._before_execute   s    r   r;   r   c                   |p| j         }|p| j        }|}| j        dk    r|nd }|| j        dk    rt          ||          }|                     |          \  }}	|	t          ||	          }t          ||||          S )Nr2   heredoc)r   r   r   r   )r   r   _stdin_moder)   _prepare_commandr/   r   )
rP   r   r   r   r   effective_cwdeffective_timeoutexec_command
exec_stdinr*   s
             r   rA   z1BaseModalExecutionEnvironment._prepare_modal_exec   s     tx#3t|#'#3y#@#@ZZd
!d&6)&C&C3L*MML#'#8#8#F#F j!/jIIL  %!	
 
 
 	
r   output
returncoder   c                    ||dS )N)rc   rd   r   )rP   rc   rd   s      r   rI   z%BaseModalExecutionEnvironment._result   s    $
 
 	
r   c                .    |                      |d          S )N   rI   )rP   rc   s     r   rD   z+BaseModalExecutionEnvironment._error_result   s    ||FA&&&r   c                6    |                      d| dd          S )NzCommand timed out after s|   rh   )rP   r   s     r   rL   z7BaseModalExecutionEnvironment._timeout_result_for_modal   s"    ||AwAAA3GGGr   rR   r   c                    dS )z Begin a transport-specific exec.Nr   )rP   rR   s     r   rB   z/BaseModalExecutionEnvironment._start_modal_exec         r   r   r   r   c                    dS )z8Return a final result dict when complete, else ``None``.Nr   rP   r   s     r   rK   z.BaseModalExecutionEnvironment._poll_modal_exec   rm   r   c                    dS )z.Cancel or terminate the active transport exec.Nr   ro   s     r   rH   z0BaseModalExecutionEnvironment._cancel_modal_exec   rm   r   )r4   )r   r   r   r   r   r7   r   r   r5   r8   r6   r8   r    r9   )r    rY   )
r   r   r   r   r   r7   r   r   r    r   )rc   r   rd   r   r    r9   )rc   r   r    r9   )r   r   r    r9   )rR   r   r    r   )r   r   r    r   )r   r   r    rY   )r   r   r   r   r]   rO   r3   r   rJ   rE   rX   r@   rA   rI   rD   rL   r   rB   rK   rH   r   r   r   r1   r1   :   sj          K!26!6666/6
 P4
 #!%,0 %P4 P4 P4 P4 P4 P4d    "!%
 
 
 
 
 
6
 
 
 
' ' ' 'H H H H / / / ^/ G G G ^G = = = ^= = =r   r1   )r   r   r   r   r    r   )r   r   r*   r   r    r   )r   
__future__r   r,   rF   r%   abcr   dataclassesr   typingr   rM   r   tools.interruptr   r   r   r)   r/   r1   r   r   r   <module>rv      s    # " " " " "          ! ! ! ! ! !       3 3 3 3 3 3 * * * * * * $" " " " " " " " $) ) ) ) ) ) ) )> > > >L L L L
X= X= X= X= X=O X= X= X= X= X=r   