
    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        C/home/ubuntu/.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Z
d-dZd	dddd.dZd/d Zd0d!Zd1d"Zed2d%            Zed3d)            Zed4d*            ZdS )5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 T)r   r   rewrite_compound_backgroundr   r   r   r   
int | Noner   r   r5   boolr    dictc               z   |}|                                   |                     ||||          }	 |                     |          }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   _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:A5/A:5A:D 
D+*D+
E% %
F/FFF9G 
G! G!?H 
HHNonec                    dS )z8Hook for backends that need pre-exec sync or validation.Nr   )rO   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   )
rO   r   r   r   r   effective_cwdeffective_timeoutexec_command
exec_stdinr*   s
             r   r@   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)rb   rc   r   )rO   rb   rc   s      r   rH   z%BaseModalExecutionEnvironment._result   s    $
 
 	
r   c                .    |                      |d          S )N   rH   )rO   rb   s     r   rC   z+BaseModalExecutionEnvironment._error_result   s    ||FA&&&r   c                6    |                      d| dd          S )NzCommand timed out after s|   rg   )rO   r   s     r   rK   z7BaseModalExecutionEnvironment._timeout_result_for_modal   s"    ||AwAAA3GGGr   rQ   r   c                    dS )z Begin a transport-specific exec.Nr   )rO   rQ   s     r   rA   z/BaseModalExecutionEnvironment._start_modal_exec         r   r   r   r   c                    dS )z8Return a final result dict when complete, else ``None``.Nr   rO   r   s     r   rJ   z.BaseModalExecutionEnvironment._poll_modal_exec   rl   r   c                    dS )z.Cancel or terminate the active transport exec.Nr   rn   s     r   rG   z0BaseModalExecutionEnvironment._cancel_modal_exec   rl   r   )r4   )r   r   r   r   r   r6   r   r   r5   r7   r    r8   )r    rX   )
r   r   r   r   r   r6   r   r   r    r   )rb   r   rc   r   r    r8   )rb   r   r    r8   )r   r   r    r8   )rQ   r   r    r   )r   r   r    r   )r   r   r    rX   )r   r   r   r   r\   rN   r3   r   rI   rD   rW   r?   r@   rH   rC   rK   r   rA   rJ   rG   r   r   r   r1   r1   :   sg          K!26!6666/6
 J4
 #!%,0J4 J4 J4 J4 J4 J4X    "!%
 
 
 
 
 
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,   rE   r%   abcr   dataclassesr   typingr   rL   r   tools.interruptr   r   r   r)   r/   r1   r   r   r   <module>ru      s    # " " " " "          ! ! ! ! ! !       3 3 3 3 3 3 * * * * * * $" " " " " " " " $) ) ) ) ) ) ) )> > > >L L L L
R= R= R= R= R=O R= R= R= R= R=r   