When to use this
The contract
An agent loop that can touch a machine always has the same three moving parts. Only the middle one is BoxLite’s job:- Tool declaration — a JSON Schema describing what the model may ask for. Provider-specific wrapper, identical schema.
- Tool implementation — runs the command in a Box and returns a plain dict. 100% provider-independent.
- Result feedback — hand the dict back to the model. Provider-specific plumbing.
Prerequisites
- A working BoxLite install (Python
boxliteor Node@boxlite-ai/boxlite) and a machine with hardware virtualization — see Installation. - Any model endpoint that supports tool / function calling, plus that provider’s client library. The examples show two protocols; the requirement is the capability, not the vendor.
Step 1 — The box side (identical for every provider)
This is the only BoxLite code in an agent loop. Copy it as-is; it does not change when you switch models.
Verified end to end against a real
alpine:latest box, covering every path above: a normal command, a non-zero exit (exitCode: 3), a missing command (exitCode: -1 with the real spawn_failed message), and an invalid argv.
Step 2 — The model side (swappable)
Only this step is provider-specific. The schema from step 1 is reused verbatim; providers differ in how they wrap it and how tool results are fed back. === “OpenAI-compatible endpoints” Covers OpenAI itself and every gateway that speaks the same protocol — MiniMax, self-hosted vLLM, Ollama, and others. Switching among them means changingbase_url and model, nothing else.
input_schema instead of parameters) and an explicit message list instead of response chaining.
Full example
Ties both steps together. To move to another provider, change the import on the marked line — nothing else.Verified: the box side (sandbox_execagainst a realpython:slimBox) was run end to end, including the non-zero-exit and missing-command paths. The provider modules were checked against each SDK’s published call signature; the Anthropic tab was not exercised end to end here.
Parameters and returns
Only the BoxLite surface is listed — your provider SDK documents its own.SimpleBox(...) — the options that matter in an agent loop
await box.exec(cmd, *args, ...) -> ExecResult
Troubleshooting
Box side
Loop side (any provider)
Related pages
- Run Claude Code — the inverse arrangement: an agent CLI running inside the Box, and
SkillBox. - Run Python code in a box —
CodeBox.run(code)when the model returns Python source rather than a command line. - Error handling — which failures raise and which are returned.
- Running sandboxes at scale — concurrency, resource ceilings, and cleanup for many parallel agents.
Running several agents at once
BoxLite ships orchestration primitives (BoxRuntime / ManagedBox) behind an extra:
examples/python/07_advanced/multi_agent/ in the repository.
