
    ~ht                     Z   d dl Z d dlZd dl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 d dlmZ d dlm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 dd
lmZmZ ddlmZ g dZ	 d dl m!Z!  e!         G d de      Z# G d de#      Z$ G d de#      Z% G d de#      Z&y# e"$ r Y 4w xY w)    N)BytesIO)Path)dedent)Any   )FinalAnswerTool)
CodeOutputPythonExecutor)LogLevel)Toolget_tools_definition_code)
AgentError)E2BExecutorDockerExecutorWasmExecutor)load_dotenvc                       e Zd ZdZdee   fdZdedefdZde	ee
f   fdZd	e	fd
ZdedefdZdee   fdZdefdZy)RemotePythonExecutorFinalAnswerExceptionadditional_importsc                 d    || _         || _        | j                  j                  d       g | _        y )Nz!Initializing executor, hold on...)r   loggerloginstalled_packages)selfr   r   s      W/opt/mcp/mcp-sentiment/venv/lib/python3.12/site-packages/smolagents/remote_executors.py__init__zRemotePythonExecutor.__init__6   s*    "4;<"$    codereturnc                     t         )zy
        Execute code, return the result and output, also determining if
        the result is the final answer.
        )NotImplementedError)r   r   s     r   run_code_raise_errorsz*RemotePythonExecutor.run_code_raise_errors<   s
    
 "!r   toolsc                    d|v r| j                  |d          |j                         D ch c].  }|j                         d   D ]  }|| j                  dgz   vr| 0 }}}|r-| xj                  | j	                  t        |            z  c_        t        |      }|r7| j                  |      }| j                  j                  |j                         y y c c}}w )Nfinal_answerrequirements
smolagents)"_patch_final_answer_with_exceptionvaluesto_dictr   install_packageslistr   r#   r   r   logs)r   r$   toolpkgpackages_to_installr   code_outputs          r   
send_toolszRemotePythonExecutor.send_toolsC   s    U"33E.4IJ 
||~n5
 $11\NBB 

 
 ##t'<'<TBU=V'WW#(/44T:KKKOOK,,- 
s   3C	variablesc                     t        j                  t        j                  |            j	                         }d| d}| j                  |       y)zF
        Send variables to the kernel namespace using pickle.
        zB
import pickle, base64
vars_dict = pickle.loads(base64.b64decode('z'))
locals().update(vars_dict)
N)base64	b64encodepickledumpsdecoder#   )r   r4   pickled_varsr   s       r   send_variablesz#RemotePythonExecutor.send_variablesU   sL     ''Y(?@GGI,,8> :
 	""4(r   code_actionc                 $    | j                  |      S )z5Run the code and determine if it is the final answer.)r#   )r   r=   s     r   __call__zRemotePythonExecutor.__call__a   s    ))+66r   c                     |rH| j                  ddj                  |             }| j                  j                  |j                         |S )Nz!pip install  )r#   joinr   r   r.   )r   r   r2   s      r   r,   z%RemotePythonExecutor.install_packagese   sC    44}SXXN`EaDb5cdKKKOOK,,-!!r   final_answer_toolc                      G d d|j                         }dt        fd}||_        |j                  j                  }||_        t        j                  |      j                  dd      |j                  _        ||_         y)a   Patch the FinalAnswerTool to raise an exception.

        This is necessary because the remote executors
        rely on the FinalAnswerTool to detect the final answer.
        It modifies the `forward` method of the FinalAnswerTool to raise
        a `FinalAnswerException` with the final answer as a pickled value.
        This allows the executor to catch this exception and return the final answer.

        Args:
            final_answer_tool (`FinalAnswerTool`): FinalAnswerTool instance to patch.
        c                       e Zd Zy)QRemotePythonExecutor._patch_final_answer_with_exception.<locals>._FinalAnswerToolN)__name__
__module____qualname__ r   r   _FinalAnswerToolrF   y   s    r   rK   r    c                     dd l }dd l} G d dt              } | |j                   |j                   | j
                  |i |            j                               )Nr   c                       e Zd Zd Zy)fRemotePythonExecutor._patch_final_answer_with_exception.<locals>.forward.<locals>.FinalAnswerExceptionc                     || _         y )N)value)r   rP   s     r   r   zoRemotePythonExecutor._patch_final_answer_with_exception.<locals>.forward.<locals>.FinalAnswerException.__init__   s	    !&DJr   N)rG   rH   rI   r   rJ   r   r   r   rN      s    'r   r   )r6   r8   	Exceptionr7   r9   _forwardr:   )r   argskwargsr6   r8   r   s         r   forwardzHRemotePythonExecutor._patch_final_answer_with_exception.<locals>.forward~   sU    'y ' ''7v'7'7]T]]TXEc\bEc8d'e'l'l'noor   zdef forward(zdef _forward(N)		__class__r   rU   __func__rR   inspect	getsourcereplace
__source__)r   rC   rK   rU   original_forward_functions        r   r)   z7RemotePythonExecutor._patch_final_answer_with_exceptionk   s    	0:: 	
	pc 	p $+  %6$=$=$F$F!$=!/6/@/@AZ/[/c/cO0
!!,
 '7#r   N)rG   rH   rI   FINAL_ANSWER_EXCEPTIONr-   strr   r	   r#   dictr   r3   r<   r?   r,   r   r)   rJ   r   r   r   r   3   sz    3%49 %"# "* ".S$Y .$
) 
)7C 7J 7"49 "+7O +7r   r   c                   D     e Zd ZdZdee   f fdZdedefdZd Z	 xZ
S )r   z
    Executes Python code using E2B.

    Args:
        additional_imports (`list[str]`): Additional imports to install.
        logger (`Logger`): Logger to use.
        **kwargs: Additional arguments to pass to the E2B Sandbox.
    r   c                     t         |   ||       	 ddlm}  |di || _        | j                  |      | _        | j                  j                  dt        j                         y # t        $ r t	        d      w xY w)Nr   )SandboxzNPlease install 'e2b' extra to use E2BExecutor: `pip install 'smolagents[e2b]'`zE2B is runninglevelrJ   )superr   e2b_code_interpreterrb   ModuleNotFoundErrorsandboxr,   r   r   r   r   INFO)r   r   r   rT   rb   rV   s        r   r   zE2BExecutor.__init__   sz    +V4	4
 (("&"7"78J"K(> # 	%d 	s   A( (A=r   r    c           	      2   | j                   j                  |      }dj                  |j                  j                  D cg c]  }t        |       c}      }|j                  r|j                  j                  t        j                  k(  rJt        j                  t        j                  |j                  j                              }t        ||d      S | d|j                  j                   d|j                  j                   d|j                  j                    }t#        || j$                        |j&                  st        d |d      S |j&                  D ]  }|j(                  sdD ]m  }t+        ||d       }	|	t        j                  |	j-                  d            }
t        t.        j0                  j3                  t5        |
            |d      c c S  dD ]#  }t+        ||d       }|t        ||d      c c S   t        d |d      S c c}w )	N
Toutputr.   is_final_answerz"
Executing code yielded an error:
F)jpegpngutf-8)
chartdatahtml
javascriptjsonlatexmarkdownpdfsvgtext)rh   run_coderB   r.   stdoutr^   errornamer   r]   r8   loadsr6   	b64decoderP   r	   	tracebackr   r   resultsis_main_resultgetattrencodePILImageopenr   )r   r   	executionr   execution_logsr&   error_messageresultattribute_nameimg_datadecoded_bytesrs   s               r   r#   z!E2BExecutor.run_code_raise_errors   s   LL))$/		8M8M#NCH#NO ??##';'R'RR%||F,<,<Y__=R=R,ST!N\`aa "" #5??''(??(()??,,-	/  ]DKK88   TPUVV'' 	_F(("1 "6>4@'$*$4$4X__W5M$NM%"yy~~gm.DENlq 	# _ v~t<#%TX]^^_	_8 NERRg $Os   Hc                 l   	 t        | d      rs| j                  j                  dt        j                         | j
                  j                          | j                  j                  dt        j                         | `yy# t        $ r(}| j                  j                  d|        Y d}~yd}~ww xY w)z'Clean up the E2B sandbox and resources.rh   zShutting down sandbox...rc   zSandbox cleanup completedError during cleanup: N)	hasattrr   r   r   ri   rh   killrQ   	log_errorr   es     r   cleanupzE2BExecutor.cleanup   s    	@tY' :(--P!!# ;8==QL	 (
  	@KK!!$:1#">??	@s   A>B 	B3B..B3)rG   rH   rI   __doc__r-   r^   r   r	   r#   r   __classcell__rV   s   @r   r   r      s5    
?49 
?5S# 5S* 5Sn	@r   r   c                        e Zd ZdZ	 	 	 	 	 ddee   dededededeee	f   dz  f fd	Z
d
edefdZdedefdZd Zd Z xZS )r   zR
    Executes Python code using Jupyter Kernel Gateway in a Docker container.
    Nr   hostport
image_namebuild_new_imagecontainer_run_kwargsc                    t         |   ||       	 ddl}ddlm}	 || _        || _        || _        	 |j                         | _
        	 |sh	 | j                  j                  j                  | j                         | j                   j#                  d| j                   t$        j&                         |r:| j                   j#                  d| j                   dt$        j&                         t+        t,              j.                  dz  }|j1                         s/t3        |d      5 }|j5                  t7        d             ddd       | j                  j                  j9                  t;        |j.                        t;        |      | j                        \  }}|D ]P  }|j                  dd      j=                         x}s&| j                   j#                  |t$        j>                         R | j                   j#                  d| d| dt$        j&                         i }|r|jA                  |       tC        |j                  d      tD              si |d<   ||f|d   d<   d
|d<    | j                  jF                  jH                  | j                  fi || _%        d}| jJ                  jL                  dk7  r|dk  r| j                   j#                  d| jJ                  jL                   dt$        j&                         tO        jP                  d       | jJ                  jS                          |dz  }| jJ                  jL                  dk7  r|dk  rd| d| | _*        tW        jX                  | jT                   d      }|jZ                  dk7  r|jZ                  tE        |j\                        |j^                  |j`                  |jb                  jd                  tE        |jb                  j\                        |jb                  jf                  d }| j                   ji                  d!tk        jl                  |d"#              t        d$|jZ                   d%|j`                         d|jk                         d&   | _7        d'| d| d(| jn                   d)} |	|      | _8        | js                  |      | _:        | j                   j#                  d*| jJ                  jv                   d+| jn                   t$        j&                         y# t
        $ r t        d      w xY w# |j                  j                  $ r}
t        d      |
d}
~
ww xY w# |j                  j(                  $ r? | j                   j#                  d| j                   d	t$        j&                         d
}Y w xY w# 1 sw Y   nxY w# tx        $ r$}
| j{                          t        d,|
       |
d}
~
ww xY w)-a3  
        Initialize the Docker-based Jupyter Kernel Gateway executor.

        Args:
            additional_imports: Additional imports to install.
            logger: Logger to use.
            host: Host to bind to.
            port: Port to bind to.
            image_name: Name of the Docker image to use. If the image doesn't exist, it will be built.
            build_new_image: If True, the image will be rebuilt even if it already exists.
            container_run_kwargs: Additional keyword arguments to pass to the Docker container run command.
        r   N)create_connectionzWPlease install 'docker' extra to use DockerExecutor: `pip install 'smolagents[docker]'`z@Could not connect to Docker daemon: make sure Docker is running.zUsing existing Docker image: rc   zImage z not found, building...TzBuilding Docker image ...
Dockerfilewa                                  FROM python:3.12-slim

                                RUN pip install jupyter_kernel_gateway jupyter_client

                                EXPOSE 8888
                                CMD ["jupyter", "kernelgateway", "--KernelGatewayApp.ip='0.0.0.0'", "--KernelGatewayApp.port=8888", "--KernelGatewayApp.allow_origin='*'"]
                                )path
dockerfiletagstream zStarting container on :portsz8888/tcpdetachrunning   zContainer status: z, waiting...r   zhttp://z/api/kernels   )status_codeheadersurlbodyrequest_methodrequest_headersrequest_bodyz"Failed to create kernel. Details:    )indentz Failed to create kernel: Status z
Response: idzws://z/api/kernels/z	/channelsz
Container z is running with kernel z%Failed to initialize Jupyter kernel: )>re   r   docker	websocketr   rg   r   r   r   from_envclienterrorsDockerExceptionRuntimeErrorimagesgetr   r   r   ri   ImageNotFoundr   __file__parentexistsr   writer   buildr^   rstripDEBUGupdate
isinstancer_   
containersrun	containerstatustimesleepreloadbase_urlrequestspostr   r   r   r{   requestmethodr   r   rv   r9   	kernel_idwsr,   r   short_idrQ   r   )r   r   r   r   r   r   r   r   r   r   r   dockerfile_pathf_
build_logs	log_chunklog_messagecontainer_kwargsretriesrerror_detailsws_urlrV   s                         r   r   zDockerExecutor.__init__   s%   , 	+V4	3
 		$	j //+DK
U	S"+KK&&**4??;KKOO&CDOOCT$U]e]j]jOk
 "88I MU]UbUbc"&x."7"7,"F&--/os3 q"!$	 !% 2 2 8 8_334_AU[_[j[j !9 !: ", KI&/mmHb&A&H&H&JJ{J8>>JK
 KKOO4TF!D6EX]]O[!# ''(<= .227;TB,. )594LW%j1)-X&7T[[3377\K[\DNG..''941"4T^^5J5J4K< X`h`m`mn

1%%'1	 ..''941 &dV1TF3DM |<=A}}##$==#AII55FF&'ii&6&6'+AII,=,='>$%IINN! %%(J4::VclmKnJo&pq"%Eamm_T`abagag`h#ijpttVVXd^DNTF!D6t~~6FiPF'/DG&*&;&;<N&OD#KKOOT^^4455MdnnM]^fnfsfs  } # 	%i 	 }},, 	jabhii	j }}22 +KKOOfT__,==T$U]e]j]jOk&*O+ J  	SLLN!FqcJKQRR	Ss   
T T& 	V; A'U 3A4V; 'V.B V; FV; F7V; T#&U?UUAV+'V; *V++V; .V83V; ;	W(W##W(r=   r    c                 x   	 | j                  |      }g }d }d}	 t        j                  | j                  j	                               }|j                  di       j                  d      }||k7  rU|j                  dd      }|j                  di       }	|dk(  r|j                  |	d	          n|d
k(  r|	d   j                  dd       }n|dk(  r|	j                  dd      t        j                  k(  r;t        j                  t        j                  |	j                  dd                  }d}nCt        dj                  |	j                  dg             | j                        |dk(  r	|	d   dk(  rnUt        |dj                  |      |      S # t         $ r$}
| j                  j#                  d|
         d }
~
ww xY w)NFTparent_headermsg_idmsg_typer   contentr   r{   execute_resultrs   z
text/plainr~   enameevaluerk   r   r   execution_stateidlerl   zCode execution failed: )_send_execute_requestrv   r   r   recvr   appendr   r]   r8   r6   r   r   rB   r   r	   rQ   r   )r   r=   r   outputsr   rn   msgparent_msg_idr   msg_contentr   s              r   r#   z$DockerExecutor.run_code_raise_errorsw  s   "	//<F GF#Ojj0 # < @ @ J F*77:r2!ggi4x'NN;v#67!11(044\4HF("w37K7b7bb!'f.>.>{xY[?\.]!^*.(;??;PR3S)TVZVaVabb)k:K.LPV.V' * V"'''2BTcdd 	KK!!$;A3"?@	s   F	F 	F9F44F9r   c           	          ddl }t        |j                               }|dt        |j                               dddi i |ddi dd	d
}| j                  j	                  t        j                  |             |S )z&Send code execution request to kernel.r   N	anonymousexecute_requestz5.0)r   usernamesessionr   versionFT)r   silentstore_historyuser_expressionsallow_stdin)headerr   metadatar   )uuidr^   uuid4r   sendrv   r9   )r   r   r  r   r   s        r   r   z$DockerExecutor._send_execute_request  s{     TZZ\"
 !'tzz|,-   !%$&$
& 	TZZ01r   c                    	 t        | d      r| j                  j                  d| j                  j                   dt
        j                         | j                  j                          | j                  j                          | j                  j                  dt
        j                         | `yy# t        $ r(}| j                  j                  d|        Y d}~yd}~ww xY w)z,Clean up the Docker container and resources.r   z Stopping and removing container r   rc   zContainer cleanup completedr   N)r   r   r   r   r   r   ri   stopremoverQ   r   r   s     r   r   zDockerExecutor.cleanup  s    	@t[)"B4>>CZCZB[[^ _gogtgtu##%%%' =X]]SN *  	@KK!!$:1#">??	@s   B0B4 4	C%=C  C%c                 $    | j                          yzEnsure cleanup on deletion.Nr   r   s    r   deletezDockerExecutor.delete      r   )z	127.0.0.1i"  zjupyter-kernelTN)rG   rH   rI   r   r-   r^   intboolr_   r   r   r	   r#   r   r   r  r   r   s   @r   r   r      s      * $6:~S I~S 	~S
 ~S ~S ~S #38nt3~S@# # #J# # <
@r   r   c            	            e Zd ZdZ	 	 	 ddee   dedee   dz  def fdZd Zd	 Z	d
ede
fdZdee   dee   fdZd Zd Z ed      Z xZS )r   uQ  
    Remote Python code executor in a sandboxed WebAssembly environment powered by Pyodide and Deno.

    This executor combines Deno's secure runtime with Pyodide's WebAssembly‑compiled Python interpreter to deliver s
    trong isolation guarantees while enabling full Python execution.

    Args:
        additional_imports (`list[str]`): Additional Python packages to install in the Pyodide environment.
        logger (`Logger`): Logger to use for output and errors.
        deno_path (`str`, optional): Path to the Deno executable. If not provided, will use "deno" from PATH.
        deno_permissions (`list[str]`, optional): List of permissions to grant to the Deno runtime.
            Default is minimal permissions needed for execution.
        timeout (`int`, optional): Timeout in seconds for code execution. Default is 60 seconds.
    Nr   	deno_pathdeno_permissionstimeoutc                    t         |   ||       	 t        j                  |dgdd       || _        || _        |6t        j                  d      }ddj                  g d      z   d	| d
d| d
g}|D cg c]  }d| 	 c}| _        | j                          | j                  |      | _        | j                   j#                  dt$        j&                         y # t        j                  t
        f$ r t        d      w xY wc c}w )Nz	--versionT)capture_outputcheckzWDeno is not installed or not found in PATH. Please install Deno from https://deno.land/HOMEz
allow-net=,)z0.0.0.0:8000zcdn.jsdelivr.net:443z'pypi.org:443,files.pythonhosted.org:443zallow-read=z/.cache/denozallow-write=z--zWasmExecutor is runningrc   )re   r   
subprocessr   SubprocessErrorFileNotFoundErrorr   r  r  osgetenvrB   r  _create_deno_runnerr,   r   r   r   r   ri   )	r   r   r   r  r  r  home_dirpermrV   s	           r   r   zWasmExecutor.__init__  s    	+V4	NNI{3DPTU # #yy(H(( hZ|4xj5  :J J2dV J 	  " #'"7"78J"K1G? **,=> 	i 	0 !Ks   C 7D%Dc                 D   t        j                  d      | _        t        j                  j                  | j                  d      | _        t        | j                  d      5 }|j                  | j                         ddd       | j                          y# 1 sw Y   xY w)zNCreate the Deno JavaScript file that will run Pyodide and execute Python code.pyodide_deno_)prefixzpyodide_runner.jsr   N)tempfilemkdtemp
runner_dirr   r   rB   runner_pathr   r   JS_CODE_start_deno_server)r   r   s     r   r"  z WasmExecutor._create_deno_runner	  sw    "**/B77<<9LM $""C( 	"AGGDLL!	" 	!		" 	"s   !BBc                    | j                   dg| j                  z   | j                  gz   }t        j                  |t        j
                  t        j
                  d      | _        t        j                  d       | j                  j                         2| j                  j                  j                         }t        d|       d| _        	 t        j                  | j                        }|j                   dk7  r%t        d	|j                    d
|j"                         y# t        j$                  $ r}t        d|       d}~ww xY w)z8Start the Deno server that will run our JavaScript code.r   T)r}   stderrr{   r   NzFailed to start Deno server: zhttp://localhost:8000   z"Server responded with status code : z"Failed to connect to Deno server: )r  r  r+  r  PopenPIPEserver_processr   r   pollr/  readr   
server_urlr   r   r   r{   RequestException)r   cmdr/  responser   s        r   r-  zWasmExecutor._start_deno_server  s)   ~~u%(=(==AQAQ@RR )..????	
 	

1 ##%1((//446F!>vhGHH1	I||DOO4H##s*"%GH\H\G]]_`h`m`m_n#opp +(( 	I!CA3GHH	Is   AD! !E4EEr   r    c                 h   	 || j                   d}t        j                  | j                  || j                        }|j
                  dk7  r#t        d|j                   | j                        d}d}|j                         }|j                  d      r|j                  d      }n|j                  d      r|d   }|j                  d	      t        j                  k(  r2d
|v r.t        j                  t        j                   |d
               }d}nL|j                  dd       d|j                  dd       }d|v r|d|d    z  }t        || j                        |j                  dd      }	t#        |t$              rt|j                  d      dk(  r`|j                  dd      }
t        j                   |
j'                  d            }t(        j*                  j-                  t/        |            |	fS t1        ||	|      S # t        j2                  $ r}t        d| | j                        d}~ww xY w)a  
        Execute Python code in the Pyodide environment and return the result.

        Args:
            code (`str`): Python code to execute.

        Returns:
            `CodeOutput`: Code output containing the result, logs, and whether it is the final answer.
        )r   packages)rv   r  r0  zServer error: NFr   r~   pythonExceptionTypepythonExceptionValueTr   Errorr1  messagezUnknown errorstackrk   r}   r   typeimagers   rq   rl   z(Failed to communicate with Deno server: )r   r   r   r7  r  r   r   r{   r   rv   r   r   r]   r8   r   r6   r   r   r_   r   r   r   r   r   r	   r8  )r   r   payloadr:  r   rn   result_datar~   r   r   
image_datar   r   s                r   r#   z"WasmExecutor.run_code_raise_errors3  s    1	Z  33G  }}T__7DLLYH##s* >(--!A4;;OOF#O #--/K x($2)#G,II348L8c8cc.%7#\\&*:*:5AW;X*YZF&*O',yy'A&B"UYYyZiEjDk$lM%'%2eGn-=)>>$]DKK@@ )__Xr:N &$'FJJv,>',I#ZZ3
 & 0 01B1B71K Lyy~~gm&<=~MMV.Rabb(( 	ZGsKT[[YY	Zs   G/H  2H   H1H,,H1c                     | j                   j                  ddj                  |       t        j                         |S )z
        Install additional Python packages in the Pyodide environment.

        Args:
            additional_imports (`list[str]`): Package names to install.

        Returns:
            list[str]: Installed packages.
        zAdding packages to load: z, rc   )r   r   rB   r   ri   )r   r   s     r   r,   zWasmExecutor.install_packagesp  s8     	3DII>P4Q3RS[c[h[hi!!r   c                 
   t        | d      rn| j                  rb| j                  j                  dt        j
                         | j                  j                          	 | j                  j                  d       t        | d      rJt        j                  j                  | j                        r ddl}|j!                  | j                         yyy# t        j                  $ r | j                  j                          Y w xY w)	z(Clean up resources used by the executor.r4  zStopping Deno server...rc   r   )r  r*  r   N)r   r4  r   r   r   ri   	terminatewaitr  TimeoutExpiredr   r   r   r   r*  shutilrmtree)r   rL  s     r   r   zWasmExecutor.cleanup  s    4)*t/B/BKKOO5X]]OK))++##(((3
 4&277>>$//+JMM$//* ,K&	 ,, +##((*+s   C -DDc                 $    | j                          yr  r  r  s    r   r  zWasmExecutor.delete  r  r   aE          // pyodide_runner.js - Runs Python code in Pyodide within Deno
        import { serve } from "https://deno.land/std/http/server.ts";
        import { loadPyodide } from "npm:pyodide";

        // Initialize Pyodide instance
        const pyodidePromise = loadPyodide();

        // Function to execute Python code and return the result
        async function executePythonCode(code) {
          const pyodide = await pyodidePromise;

          // Create a capture for stdout
          pyodide.runPython(`
            import sys
            import io
            sys.stdout = io.StringIO()
          `);

          // Execute the code and capture any errors
          let result = null;
          let error = null;
          let stdout = "";

          try {
            // Execute the code
            result = await pyodide.runPythonAsync(code);

            // Get captured stdout
            stdout = pyodide.runPython("sys.stdout.getvalue()");
          } catch (e) {
            error = {
              name: e.constructor.name,
              message: e.message,
              stack: e.stack
            };

            // Extract Python exception details
            if (e.constructor.name === "PythonError") {
              // Get the Python exception type from the error message: at the end of the traceback
              const errorMatch = e.message.match(/\n([^:]+Exception): /);
              if (errorMatch) {
                error.pythonExceptionType = errorMatch[1].split(".").pop();
              }

              // If the error is a FinalAnswerException, extract its the encoded value
              if (error.pythonExceptionType === "FinalAnswerException") {
                // Extract the base64 encoded value from the error message
                const valueMatch = e.message.match(/FinalAnswerException: (.*?)(?:\n|$)/);
                if (valueMatch) {
                  error.pythonExceptionValue = valueMatch[1];
                }
              }
            }
          }

          return {
            result,
            stdout,
            error
          };
        }

        // Start a simple HTTP server to receive code execution requests
        //const port = 8765;
        //console.log(`Starting Pyodide server on port ${port}`);

        serve(async (req) => {
          if (req.method === "POST") {
            try {
              const body = await req.json();
              const { code, packages = [] } = body;

              // Load any requested packages
              if (packages && packages.length > 0) {
                const pyodide = await pyodidePromise;
                //await pyodide.loadPackagesFromImports(code);
                await pyodide.loadPackage("micropip");
                const micropip = pyodide.pyimport("micropip");
                try {
                  await micropip.install(packages);
                } catch (e) {
                  console.error(`Failed to load package ${pkg}: ${e.message}`);
                }
              }

              const result = await executePythonCode(code);
              return new Response(JSON.stringify(result), {
                headers: { "Content-Type": "application/json" }
              });
            } catch (e) {
              return new Response(JSON.stringify({ error: e.message }), {
                status: 500,
                headers: { "Content-Type": "application/json" }
              });
            }
          }

          return new Response("Pyodide-Deno Executor is running. Send POST requests with code to execute.", {
            headers: { "Content-Type": "text/plain" }
          });
        });
        )denoN<   )rG   rH   rI   r   r-   r^   r  r   r"  r-  r	   r#   r,   r   r  r   r,  r   r   s   @r   r   r     s    &  -1,H I,H 	,H
 s)d*,H ,H\
"I<;Z# ;Z* ;Zz"49 "c " +   f fGr   r   )'r6   rX   rv   r   r8   r  r(  r   ior   pathlibr   textwrapr   typingr   	PIL.Imager   r   default_toolsr   local_python_executorr	   r
   
monitoringr   r$   r   r   utilsr   __all__dotenvr   rg   r   r   r   r   rJ   r   r   <module>r\     s   "    	           * =   2  <	"M
c7> c7LV@& V@rV) Vro' oy  		s   (B" "B*)B*