Skip to main content
The code-interpreter template is the standard execution target when your agent produces Python snippets and wants them run in isolation. It ships the libraries LLMs commonly importnumpy, pandas, matplotlib, plotly, scipy, scikit-learn, Pillow, SymPy, plus jupyter and ipython — so a freshly-generated snippet doesn’t stall on pip install every time. Think of it as the declaw-native backing for OpenAI’s code interpreter tool, Anthropic’s code execution tool, and similar agent primitives: feed it a string of Python, get back stdout / stderr / exit code.

What you’ll learn

  • Picking template="code-interpreter" so the common scientific imports work cold
  • Running several unrelated code snippets in the same sandbox, safely
  • Letting the agent generate code and only having the SDK execute it

Prerequisites

export DECLAW_API_KEY="your-api-key"
export DECLAW_DOMAIN="your-declaw-instance.example.com:8080"

Code

In the example below we skip calling a real LLM and just iterate over three hand-written snippets — each one stands in for whatever your agent decides to execute next.
import textwrap

from declaw import Sandbox


# Three snippets the "agent" wants to run. In a real pipeline these
# come from the model's tool-use response; we hard-code them here so
# the example has no LLM dependency.
SNIPPETS = [
    # 1. Numeric: SymPy solves a small system.
    textwrap.dedent("""
        from sympy import symbols, solve
        x, y = symbols('x y')
        eqs = [x + 2*y - 5, 3*x - y - 4]
        print("solution:", solve(eqs, [x, y]))
    """),

    # 2. Data shaping: pandas rollup from an in-memory CSV string.
    textwrap.dedent("""
        import io, pandas as pd
        csv = "region,sales\\nNA,120\\nEU,80\\nAPAC,150\\nNA,60"
        df = pd.read_csv(io.StringIO(csv))
        print(df.groupby('region')['sales'].sum().to_dict())
    """),

    # 3. Rendering: matplotlib — renders to a file, no display needed.
    textwrap.dedent("""
        import matplotlib
        matplotlib.use("Agg")
        import matplotlib.pyplot as plt
        plt.figure()
        plt.plot([0, 1, 2, 3], [1, 4, 2, 8], marker='o')
        plt.title("agent-generated chart")
        plt.savefig("/tmp/chart.png", dpi=120)
        print("wrote /tmp/chart.png")
    """),
]


def run_snippet(sbx: Sandbox, idx: int, code: str) -> None:
    # Every snippet is written to its own file so tracebacks point
    # at a real path, then executed with python3.
    path = f"/tmp/snip_{idx}.py"
    sbx.files.write(path, code)
    r = sbx.commands.run(f"python3 {path}", timeout=30)
    print(f"--- snippet {idx} (exit={r.exit_code}) ---")
    if r.stdout:
        print(r.stdout.rstrip())
    if r.stderr and r.exit_code != 0:
        print("stderr:", r.stderr.rstrip())


def main() -> None:
    sbx = Sandbox.create(template="code-interpreter", timeout=180)
    try:
        for i, code in enumerate(SNIPPETS, start=1):
            run_snippet(sbx, i, code)

        # Artefacts produced by one snippet survive for the next —
        # the sandbox is persistent until you kill it.
        info = sbx.files.get_info("/tmp/chart.png")
        print(f"\nchart.png exists: {info.size} bytes")
    finally:
        sbx.kill()


if __name__ == "__main__":
    main()

Expected output

--- snippet 1 (exit=0) ---
solution: {x: 13/7, y: 11/7}
--- snippet 2 (exit=0) ---
{'APAC': 150, 'EU': 80, 'NA': 180}
--- snippet 3 (exit=0) ---
wrote /tmp/chart.png

chart.png exists: 31824 bytes
A real agent loop typically does three things per tool call: generate the snippet with the model, pass it here for execution, then feed the stdout / exit code back to the model. Keep the same sandbox alive across turns so files and installed packages persist — kill it only when the task finishes.