
    `gjf'                         d Z ddlZddlZddlZddlZddlZddlmZ ddlm	Z	m
Z
 ddlmZmZmZmZmZ  ej"                  e      Z G d de	      Zy)zDaytona cloud execution environment.

Uses the Daytona Python SDK to run commands in cloud sandboxes.
Supports persistent sandboxes: when enabled, sandboxes are stopped on cleanup
and resumed on next creation, preserving the filesystem across sessions.
    N)Path)BaseEnvironment_ThreadedProcessHandle)FileSyncManageriter_sync_filesquoted_mkdir_commandquoted_rm_commandunique_parent_dirsc                        e Zd ZdZdZ	 	 	 	 	 	 	 d!dedededededed	ed
ef fdZdededdfdZ	de
eeef      ddfdZdeddfdZde
e   ddfdZd"dZd"dZdddddededededz  fdZd  Z xZS )#DaytonaEnvironmentzDaytona cloud sandbox execution backend.

    Spawn-per-call via _ThreadedProcessHandle wrapping blocking SDK calls.
    cancel_fn wired to sandbox.stop() for interrupt support.
    Shell timeout wrapper preserved (SDK timeout unreliable).
    heredocimagecwdtimeoutcpumemorydiskpersistent_filesystemtask_idc	           	          |}	t            ||       	 ddlm}
  |
dd       ddlm}m	}m
}m}m} | _        | _        | _         |        _        d  _        t%        j&                          _        t+        dt-        j.                  |d	z              }t+        dt-        j.                  |d	z              }|d
kD  rt0        j3                  d|       d
} ||||      }d|i}d| } j                  r	  j                   j5                  |       _         j"                  j7                          t0        j9                  d j"                  j:                  |        j"                  	  j                   j=                  |d      }t?        tA        |      d       }|L| _         j"                  j7                          t0        j9                  d j"                  j:                  |        j"                  V j                   jE                   ||||d|             _        t0        j9                  d j"                  j:                  |       d _#        	  j"                  jH                  jK                  d      jL                  jO                         }|r| _#        |	dv r| _(        t0        j9                  d jF                   jP                         tS         fd jT                   jV                   jX                   jZ                         _.         j\                  j_                  d        ja                          y # t        $ r Y "t
        $ r}t	        t        |            d }~ww xY w# |$ r d  _        Y t
        $ r)}t0        j3                  d||       d  _        Y d }~Kd }~ww xY w# t
        $ r)}t0        jC                  d||       d  _        Y d }~d }~ww xY w# t
        $ r Y Lw xY w)N)r   r   r   )ensurezterminal.daytonaF)prompt)DaytonaCreateSandboxFromImageParamsDaytonaError	ResourcesSandboxState   i   
   zNDaytona: requested disk (%dGB) exceeds platform limit (10GB). Capping to 10GB.)r   r   r   hermes_task_idzhermes-z'Daytona: resumed sandbox %s for task %sz1Daytona: failed to resume sandbox for task %s: %s)labelslimitz.Daytona: resumed legacy sandbox %s for task %sz0Daytona: no legacy sandbox found for task %s: %s)r   namer!   auto_stop_interval	resourcesz'Daytona: created sandbox %s for task %sz/rootz
echo $HOME>   ~/home/daytonaz'Daytona: resolved home to %s, cwd to %sc                  4    t         j                   d      S )N/.hermes)r   _remote_homeselfs   M/root/.hermes/venv/lib/python3.12/site-packages/tools/environments/daytona.py<lambda>z-DaytonaEnvironment.__init__.<locals>.<lambda>   s    D4E4E3Fh1O!P     )get_files_fn	upload_fn	delete_fnbulk_upload_fnbulk_download_fnT)force)1super__init__tools.lazy_depsr   ImportError	Exceptionstrdaytonar   r   r   r   r   _persistent_task_id_SandboxState_daytona_sandbox	threadingLock_lockmaxmathceilloggerwarninggetstartinfoidlistnextiterdebugcreater*   processexecresultstripr   r   _daytona_upload_daytona_delete_daytona_bulk_upload_daytona_bulk_download_sync_managersyncinit_session)r,   r   r   r   r   r   r   r   r   requested_cwd_lazy_ensureer   r   r   r   r   
memory_gibdisk_gibr%   r!   sandbox_nameresultslegacyhome	__class__s   `                        r-   r7   zDaytonaEnvironment.__init__(   s    S'2	&>+E:
	
 	
 1)	^^%
DIIftm45
q$))D4K01b=NN#$, H#jxH	"G, 	*
% $ 1 1, ?##%E MM,,g7 }}$) #mm00a0HG!$w-6F)(.++-$T$(MM$4$4g? ==  MM00,%!'('DM KKA(('3 $	==((--l;BBHHJD$(! $::#DH 	=t?P?PRVRZRZ[,P****44!88
 	d+  	 	&c!f%%	&H   % $ %R&+ $%" ! )LL!S!(!-$(DMM)4  		sh   L= 8A%M- *B N0 AO% =	M*	M*M%%M*-N-<N-N((N-0	O"9OO"%	O21O2	host_pathremote_pathreturnNc                     t        t        |      j                        }| j                  j                  j                  t        |g             | j                  j                  j                  ||       y)z%Upload a single file via Daytona SDK.N)	r;   r   parentrA   rS   rT   r   fsupload_file)r,   rh   ri   rl   s       r-   rW   z"DaytonaEnvironment._daytona_upload   sQ    T+&--.""#7#AB$$Y<r/   filesc                    ddl m} |syt        |      }|r.| j                  j                  j                  t        |             |D cg c]  \  }} |||       }}}| j                  j                  j                  |       yc c}}w )zUpload many files in a single HTTP call via Daytona SDK.

        Uses ``sandbox.fs.upload_files()`` which batches all files into one
        multipart POST, avoiding per-file TLS/HTTP overhead (~580 files
        goes from ~5 min to <2 s).
        r   )
FileUploadN)sourcedestination)	daytona.common.filesystemrq   r
   rA   rS   rT   r   rm   upload_files)r,   ro   rq   parentsrh   ri   uploadss          r-   rY   z'DaytonaEnvironment._daytona_bulk_upload   s     	9$U+MM!!&&';G'DE +0
&	; i[A
 
 	%%g.	
s   
Bdestc                    | j                    dj                  d      }dt        j                          d}| j                  j
                  j                  dt        j                  |       dt        j                  |              | j                  j                  j                  |t        |             	 | j                  j
                  j                  dt        j                  |              y# t        $ r Y yw xY w)	z*Download remote .hermes/ as a tar archive.r)   /z/tmp/.hermes_sync.z.tarztar cf z -C / zrm -f N)r*   lstriposgetpidrA   rS   rT   shlexquoterm   download_filer;   r:   )r,   rx   rel_base
remote_tars       r-   rZ   z)DaytonaEnvironment._daytona_bulk_download   s    ''(188= *"))+d;
""ekk*-.fU[[5J4KL	
 	&&z3t9=	MM!!&&J0G/H'IJ 		s   8;C4 4	D ?D remote_pathsc                 `    | j                   j                  j                  t        |             y)z'Batch-delete remote files via SDK exec.N)rA   rS   rT   r	   )r,   r   s     r-   rX   z"DaytonaEnvironment._daytona_delete   s     ""#4\#BCr/   c                 F   | j                   j                          | j                   j                  | j                  j                  | j                  j
                  hv rE| j                   j                          t        j                  d| j                   j                         yy)zBRestart sandbox if it was stopped (e.g., by a previous interrupt).zDaytona: restarted sandbox %sN)
rA   refresh_datastater?   STOPPEDARCHIVEDrK   rH   rL   rM   r+   s    r-   _ensure_sandbox_readyz(DaytonaEnvironment._ensure_sandbox_ready   sp    ""$==4#5#5#=#=t?Q?Q?Z?Z"[[MM!KK79I9IJ \r/   c                     | j                   5  | j                          ddd       | j                  j                          y# 1 sw Y   $xY w)z=Ensure sandbox is ready, then sync files via FileSyncManager.N)rD   r   r[   r\   r+   s    r-   _before_executez"DaytonaEnvironment._before_execute   s<    ZZ 	)&&(	)!	) 	)s   AA
Fx   )loginr   
stdin_data
cmd_stringr   r   c                   	 | j                   | j                  fd}|rdt        j                  |       	ndt        j                  |       	dt        t
        t        f   f	fd}t        ||      S )zEReturn a _ThreadedProcessHandle wrapping a blocking Daytona SDK call.c                  t     5  	 j                          d d d        y # t        $ r Y w xY w# 1 sw Y   y xY w)N)stopr:   )locksandboxs   r-   cancelz,DaytonaEnvironment._run_bash.<locals>.cancel   sB     LLN  !  s   .	+.+.7zbash -l -c zbash -c rj   c                  v    j                   j                        } | j                  xs d| j                  fS )N)r    )rS   rT   rU   	exit_code)responser   	shell_cmdr   s    r-   exec_fnz-DaytonaEnvironment._run_bash.<locals>.exec_fn   s6    ++Iw+GHOO)r8+=+=>>r/   )	cancel_fn)rA   rD   r~   r   tupler;   intr   )
r,   r   r   r   r   r   r   r   r   r   s
      `   @@@r-   	_run_bashzDaytonaEnvironment._run_bash   sp     --zz	 %ekk*&=%>?I"5;;z#:";<I	?sCx 	? &g@@r/   c                    | j                   5  | j                  
	 d d d        y | j                  r0t        j	                  d       	 | j                  j                          	 | j                  rE| j                  j                          t        j	                  d| j                  j                         nO| j                  j                  | j                         t        j	                  d| j                  j                         d | _        d d d        y # t        $ r }t        j                  d|       Y d }~d }~ww xY w# t        $ r }t        j                  d|       Y d }~`d }~ww xY w# 1 sw Y   y xY w)Nz&Daytona: syncing files from sandbox...zDaytona: sync_back failed: %sz2Daytona: stopped sandbox %s (filesystem preserved)zDaytona: deleted sandbox %szDaytona: cleanup failed: %s)rD   rA   r[   rH   rL   	sync_backr:   rI   r=   r   rM   r@   delete)r,   r`   s     r-   cleanupzDaytonaEnvironment.cleanup   s*   ZZ 	!}}$	! 	! !!DEG&&002	A##MM&&(KK T $ 0 02 MM((7KK =t}}?O?OP !DM3	! 	! ! GNN#BAFFG  A<a@@A/	! 	!s_   E)!E)D!B D=E)	D:D50E)5D::E)=	E&E!E)!E&&E))E2)r'   <   r   i   i (  Tdefault)rj   N)__name__
__module____qualname____doc___stdin_moder;   r   boolr7   rW   rN   r   rY   r   rZ   rX   r   r   r   r   __classcell__)rg   s   @r-   r   r      s2    K
 #&* pp p 	p
 p p p  $p pd= =3 =4 =/$uS#X*? /D /,4 D  DDI D$ DK" ;@!$+/AC A4 AA!DjA2!r/   r   )r   loggingrF   r|   r~   rB   pathlibr   tools.environments.baser   r   tools.environments.file_syncr   r   r   r	   r
   	getLoggerr   rH   r    r/   r-   <module>r      sO      	     
		8	$p! p!r/   