Example · Agents in sandboxes

Give Hermes a shell.
Keep everything else.

This demo shows Hermes Agent, from Nous Research, writing code, running it, and fixing what breaks. On Chalk it does that inside a sandbox that can reach only its model endpoint, using an API key it never sees. One Python file sets it up, runs the task, and hands you the diff.

CHALK SANDBOX · 2 CPU · 4 GI☤ hermes chat--oneshot --yolo$ python test_roman.py✓ all tests passed✍ roman.py · test_roman.py/root/projectgit diff → 2 new filesshell, files, git: all localenvOPENROUTER_API_KEY=__chalk-secret-7f3a…EGRESS PROXYopenrouter.aikey injected heregithub.comonly with --repoeverything elseno route, no DNS

Inspect the task, files, and test result from one run

This recorded transcript shows Hermes writing a Roman-numeral module inside a restricted sandbox.

Try this experiment · expected results

  1. 1Read the requested task

    Compare the request with the two file writes and the test command in the transcript.

    Expected: The recorded agent creates both the module and its tests.

  2. 2Check the outcome

    Read the test report and changed-file list at the end.

    Expected: The run reports five passing tests, two added files, and sandbox termination.

hermes v2026.9.24
$ ./examples/hermes/hermes.py --model anthropic/claude-sonnet-4-6
Starting sandbox (the first run builds the Hermes image)...
Running Hermes with anthropic/claude-sonnet-4-6...
Query: Create a small, standard-library-only Python module roman.py with to_roman(int) and from_roman(str) for 1-3999, and a test_roman.py that checks a round trip over the whole range plus invalid inputs…
Initializing agent...
┊ ✍️ write /root/project/roman.py 8.2s
┊ review diff a/roman.py → b/roman.py +57
┊ ✍️ write /root/project/test_roman.py 0.1s
┊ review diff a/test_roman.py → b/test_roman.py
┊ 💻 $ python test_roman.py 0.2s
☤ Hermes
All five tests pass, zero failures.
roman.py converts with a greedy table of 13 value/symbol pairs and rejects malformed input like IIII or IM with a canonical round-trip check. test_roman.py covers 21 known values, all 3999 round trips, and 16 invalid inputs, with plain asserts.
Duration: 1m 2s · Messages: 8 (1 user, 6 tool calls)
--- Changes made by Hermes ---
A roman.py
A test_roman.py
Terminated sandbox da132ad3-2fdf-4b75-b120-f2b0f9f6a6fa.

Built on Chalk

Hermes brings the agent. Chalk brings the place it's safe to let it work.

  • A real shell, safely

    Hermes runs with --yolo: no approval prompts for each command. The sandbox, not a human clicking yes, is what bounds what it can do.

  • Nothing to exfiltrate

    A prompt-injected agent that dumps its environment finds a placeholder, and has nowhere to send it except your model provider.

  • Images from Python

    Image.debian_slim().run_commands(...) builds the container. No Dockerfile, no registry, and the first build is the only slow one.

  • Bounded lifetimes

    Each sandbox is terminated when the run ends and carries a server-side lifetime, so a killed laptop never leaves compute running.

Deploy your own

Run it with one command

Clone the SDK, log in, set a model key, and run the example. The first run builds the Hermes image, which takes a few minutes; after that a sandbox is ready in seconds and a typical task finishes in about a minute.

Pass --repo to work on your own code and --prompt to change the task. Swap the model endpoint without touching anything else.

Hermes source on GitHub

chalk-sandbox-sdk/examples/hermes
git clone https://github.com/chalk-ai/chalk-sandbox-sdk
cd chalk-sandbox-sdk

# Or export CHALK_CLIENT_ID and CHALK_CLIENT_SECRET.
chalk login
export OPENROUTER_API_KEY=...

# Builds the image, starts a sandbox, runs one task, prints the diff.
./examples/hermes/hermes.py
Implementation details

How the example works

  • A pinned image

    Hermes' own installer runs once, at a pinned release, inside an image Chalk builds and caches. Every later sandbox starts from the same bytes in seconds.

  • An allowlisted network

    The sandbox's network policy lists the model endpoint and, if you ask for one, the git host. Every other connection fails before it leaves the sandbox: no route, no DNS.

  • A key the agent never sees

    Hermes' environment holds a random placeholder. The egress proxy replaces it with the real API key, and only on requests bound for the model host.

More capabilities

  • Any OpenAI-compatible model

    OpenRouter by default. Point --base-url at OpenAI, a gateway, or a vLLM server in your own cloud without touching the sandbox code.

  • Reviewable output

    The project is a git repository, so every run ends with git status and a full diff of exactly what the agent changed.

Put your agents in a sandbox

Coding agents, evaluation harnesses, or anything that runs model-written code. Talk to an engineer about running them next to your data.