Class PythonExecutionTools

java.lang.Object
com.tnsai.tools.code.PythonExecutionTools
All Implemented Interfaces:
AutoCloseable

public class PythonExecutionTools extends Object implements AutoCloseable
Function-shape Python tools — executes user code through the framework's Sandbox SPI using the process backend by default with ResourceLimits.standard() and a requested NetPolicy.denyAll() policy that the portable process backend cannot enforce. Replaces the legacy raw-ProcessBuilder implementation.

Two typed @Tool methods:

MethodBackendIdempotent
pythonExecute(java.lang.String, long)Sandbox SPIfalse
pythonVersion()Sandbox SPItrue

Isolation follows the SPI's defaults — env scrubbing, timeout enforcement, and (on stronger backends) filesystem isolation, network deny, and resource caps. ProcessSandbox (the portable default) provides env scrubbing, timeout/output limits, and a temporary working directory, but no filesystem or network isolation. ContainerSandbox adds real --network=none, cgroups, and bind-mount semantics.

Defaults to picking the system Python from the host's PATH (passed through to the sandbox env) using the PYTHON_PATH env var, falling back to literal python3. An optional venvPath (or PYTHON_VENV_PATH env var) routes through the venv's bin/python.

Implements AutoCloseable for forward-compat — sandbox lifetime is per-execute so close() is currently a no-op.

Since:
0.10.0 (TNS-343 — migration to Sandbox SPI)
  • Constructor Details

    • PythonExecutionTools

      public PythonExecutionTools()
      Default constructor — pins the "process" backend so the host's Python interpreter is used directly. Consumers who want stronger isolation pass an explicit factory + image-bearing spec via the full-control constructor — SandboxFactory.preferred() can pick a container backend that requires spec.image(), which has no sensible default for "run host python".
    • PythonExecutionTools

      public PythonExecutionTools(String pythonPath)
      Explicit interpreter; process sandbox backend.
    • PythonExecutionTools

      public PythonExecutionTools(String pythonPath, String venvPath)
      Explicit interpreter + venv; process sandbox backend.
    • PythonExecutionTools

      public PythonExecutionTools(com.tnsai.quality.sandbox.SandboxFactory factory, com.tnsai.quality.sandbox.SandboxSpec spec, String pythonPath, String venvPath)
      Full control: explicit sandbox backend + spec + interpreter paths. The spec's ResourceLimits.timeout() is used as the upper bound; pythonExecute(java.lang.String, long)'s timeoutSeconds parameter further clamps to MAX_TIMEOUT_SECONDS.
      Parameters:
      factory - backend selector (e.g. SandboxFactory.preferred() or byId("container"))
      spec - base spec — env / mounts / network policy / limits. Per-execute timeout is overridden from the user-supplied timeoutSeconds parameter.
  • Method Details

    • pythonExecute

      @Tool(name="python_execute", description="Run a Python snippet through the configured Sandbox backend with timeout and output caps. The default configuration uses the process backend with a scrubbed environment and temporary working directory; its filesystem access remains that of the host process, and its requested deny-all network policy is not enforced unless a stronger backend is configured. Returns stdout plus stderr/exit-code on failure. {timeoutSeconds} clamps to [0, 300]; 0 \u2192 default 30s. Output is capped at 100 KB.", keywords={"python","execute","run","script","sandbox","subprocess","numpy","pandas","data","science"}, idempotent=false) public String pythonExecute(@ToolParam(description="Python source code") String code, @ToolParam(description="Per-call timeout in seconds (clamped to 300); 0 \u2192 default 30",required=false,defaultValue="0") long timeoutSeconds) throws IOException, InterruptedException, TimeoutException
      Throws:
      IOException
      InterruptedException
      TimeoutException
    • pythonVersion

      @Tool(name="python_version", description="Probe the configured Python interpreter (via the same Sandbox SPI as python_execute) and return its version banner (e.g. \"Python 3.11.7\"). Useful when the agent needs to decide whether to call python_execute. Returns the empty string when no interpreter is reachable.", keywords={"python","version","probe","check","available"}, idempotent=true) public String pythonVersion()
    • close

      public void close()
      No persistent resources held — sandbox lifetime is per-execute.
      Specified by:
      close in interface AutoCloseable