JuliaInterpreterToolSet#

The JuliaInterpreterToolSet provides agents with the ability to execute Julia code in persistent interpreter sessions with automatic crash recovery and figure capture.

Overview#

Key features:

  • Process Isolation: Each interpreter runs in a separate Julia process

  • Session Management: State persists across multiple executions

  • Figure Support: Automatic plot capture and base64 encoding

  • Auto-Recovery: Automatically restarts crashed interpreters

  • Timeout Support: Configurable timeouts for long-running operations

Basic Usage#

from pantheon.agent import Agent
from pantheon.toolsets import JuliaInterpreterToolSet

# Create Julia interpreter toolset
julia_tools = JuliaInterpreterToolSet(
    name="julia",
    workdir="/path/to/workspace",
    julia_executable="julia"  # Path to Julia executable
)

# Create agent and add toolset at runtime
agent = Agent(
    name="scientist",
    instructions="You are a scientist who analyzes data using Julia."
)
await agent.toolset(julia_tools)

await agent.chat()

Constructor Parameters#

Parameter

Type

Description

name

str

Name of the toolset

julia_executable

str

Path to Julia executable. Default: “julia”

julia_args

list[str] | None

Arguments to pass to Julia executable

init_code

str | None

Julia code to run when initializing each interpreter

workdir

str | None

Working directory for Julia sessions. Defaults to current directory.

Tools Reference#

run_julia_code#

Execute Julia code with automatic session management.

result = await julia_tools.run_julia_code(
    code="x = 1:10; mean(x)",
    timeout=30  # Optional: timeout in seconds
)

Parameters:

  • code: The Julia code to run

  • timeout: Optional timeout in seconds. Use None for no timeout (long-running commands).

Returns:

{
    "result": None,
    "stdout": "5.5\n",
    "stderr": "",
    "code_executed": "x = 1:10; mean(x)"
}

Figure Output:

When code generates plots, they are automatically captured:

{
    "result": None,
    "stdout": "...",
    "stderr": "",
    "fig_storage_path": "/tmp/abc123.png",
    "base64_uri": ["data:image/png;base64,..."]
}

new_interpreter#

Create a new Julia interpreter session.

result = await julia_tools.new_interpreter()
# Returns: {"interpreter_id": "abc123", "initial_output": "Julia version..."}

run_code_in_interpreter#

Run Julia code in a specific interpreter session.

result = await julia_tools.run_code_in_interpreter(
    code="println(x * 2)",
    interpreter_id="abc123",
    timeout=60
)
# Returns: str (output from Julia)

delete_interpreter#

Delete a Julia interpreter session.

await julia_tools.delete_interpreter(interpreter_id="abc123")

get_interpreter_output#

Get remaining output from an interpreter (useful after timeout).

output = await julia_tools.get_interpreter_output(
    interpreter_id="abc123",
    timeout=10
)

Session Management#

State Persistence#

Variables persist across executions in the same session:

# First execution
await julia_tools.run_julia_code("data = rand(100)")

# Second execution - data is still available
result = await julia_tools.run_julia_code("mean(data)")

Auto-Recovery#

If an interpreter crashes, it automatically restarts and reinitializes:

{
    "result": None,
    "stdout": "[Info] Julia interpreter was restarted...\nOutput here",
    "stderr": "",
    "code_executed": "...",
    "interpreter_crashed": True  # Only on crash
}

Figure Saving#

Use the built-in save_figure function:

using Plots
plot(1:10, rand(10))
save_figure("my_plot.png")

Examples#

Statistical Analysis#

result = await julia_tools.run_julia_code("""
using Statistics

# Generate sample data
data = randn(1000)

# Compute statistics
println("Mean: ", mean(data))
println("Std: ", std(data))
println("Median: ", median(data))
""")

Data Visualization#

result = await julia_tools.run_julia_code("""
using Plots

x = 0:0.1:10
y = sin.(x)

plot(x, y,
    title="Sine Wave",
    xlabel="x",
    ylabel="sin(x)",
    legend=false)
save_figure("sine_wave.png")
""")
# result["base64_uri"] contains the plot image

Scientific Computing#

result = await julia_tools.run_julia_code("""
using LinearAlgebra
using DifferentialEquations

# Solve simple ODE: du/dt = -u
f(u, p, t) = -u
u0 = 1.0
tspan = (0.0, 5.0)

prob = ODEProblem(f, u0, tspan)
sol = solve(prob)

println("Solution at t=5: ", sol(5.0))
""")

Initialization Code#

Use init_code to pre-load packages:

julia_tools = JuliaInterpreterToolSet(
    name="julia",
    init_code="""
    using Statistics
    using LinearAlgebra
    using Plots
    gr()  # Use GR backend
    """
)

Best Practices#

  1. Use timeout for long operations: Prevents blocking on slow computations

  2. Pre-load packages with init_code: Faster subsequent executions

  3. Use run_julia_code for most cases: Handles session management automatically

  4. Set seeds for reproducibility: Random.seed!(123) before random operations

  5. Run in containers: The toolset executes arbitrary code - use isolated environments

Security Warning#

This toolset can execute arbitrary Julia code. Always:

  • Run in a sandboxed environment (Docker, VM)

  • Limit agent instructions to specific tasks

  • Monitor code execution

  • Avoid exposing to untrusted input