monty-go: Run LLM-Generated Python in Go via WASM, No Containers
Fugue Labs' monty-go wraps Pydantic's Monty Python interpreter in pure Go via WASM and wazero, letting agents execute LLM-written Python safely with sub-millisecond startup and pause/resume external calls.

Fugue Labs has released monty-go, a pure-Go wrapper around Pydantic's Monty Python interpreter, compiled to WebAssembly and loaded via wazero. It lets Go agents execute LLM-generated Python code in a sandboxed WASM instance—no containers, no CGO, no subprocess—with sub-millisecond startup. The interpreter pauses whenever the code calls an external function, letting your Go code handle it and resume.
Why code execution instead of tool calls?
The pitch: LLMs work faster and cheaper when they write code instead of making sequential tool calls. Instead of three round-trips for weather lookups and comparison, the model writes a short Python script that calls your Go functions. One model call, three tool invocations, all inside a 2.9MB WASM binary embedded in your Go binary.
Quick start and external functions
Basic execution is straightforward: pass an expression and input map, get a result. The real power is in external function calls. Monty pauses at each call to a declared function, your Go callback executes it, and Monty resumes with the return value. Multiple functions can be registered and dispatched by name.
Resource limits and safety
Runaway code is handled with configurable limits: max duration, memory, allocations, and recursion depth. Infinite loops and memory bombs terminate cleanly with a *MontyError. Go's context deadlines are respected. Filesystem and environment access routes through a callback—nothing happens unless your code allows it.
Gollem integration
monty-go is designed to power code-mode in Gollem, Fugue's Go agent framework. The LLM writes Python that calls your tools as functions; Monty executes it safely, and Gollem orchestrates the flow. The README claims three tool calls in one LLM round-trip, with lower latency and cost compared to traditional sequential tool calling.
One model call instead of three. The Python code calls your Go functions, Monty pauses at each call, your Go code executes it, and Monty resumes. No containers. No sandbox services. No exec(). Just a 2.9MB WASM binary embedded in your Go binary.
| Aspect | Traditional tool calling | Code-mode with monty-go |
|---|---|---|
| LLM calls | One per tool use | One for all tools |
| Latency | N × model round-trip | 1 × model round-trip + μs execution |
| Cost | N × input/output tokens | 1 × input/output tokens |
| Logic | LLM reasons step by step | LLM writes the logic once |
| Control flow | None (sequential only) | Loops, conditionals, variables |
| Error handling | LLM must react to each failure | try/except in Python |
| Security | ✅ (tools are Go functions) | ✅ (WASM sandbox + your callbacks) |
Source: GitHub
Discussion
0 Comments
Be the first to start the discussion.