PyRepl
PyRepl is a persistent IPython REPL running in a subprocess. It gives the model a continuous execution environment where variables persist across calls and runtime primitives are accessible without imports. In 0.8.1,PyRepl remains the public facade while its internals are split into focused components: worker lifecycle (pyrepl_worker_client.py), execute/reset orchestration (pyrepl_execution.py), primitive host integration (pyrepl_primitive_host.py), tool factory/output formatting (pyrepl_tools.py), audit logging (pyrepl_audit.py), and input bridging (pyrepl_input_bridge.py / pyrepl_input_mixin.py). This is an internal architecture cleanup; user-facing usage stays the same.
Core Properties
- Persistent state — Variables defined in one
execute_codecall are available in the next - Isolated process — Runs in a separate subprocess (multiprocessing spawn). Crashes don’t kill the main process
- Runtime injection — The
runtimeobject is globally available. No imports needed - Streaming output — stdout/stderr stream in real-time via custom events
- Image artifacts — images produced by
display(Image(...))or image-rich last expressions are returned to the model as multimodal tool results - Timeout protection — Default 600s per execution. Configurable
Setup
Tools Provided
execute_code
Run arbitrary Python code in the persistent REPL:Image Output
When executed code produces image output,execute_code returns a multimodal tool result instead of flattening the image to text. The model receives the normal execution summary plus the image content.
Supported patterns include explicit display calls:
PyRepl.execute(...) calls expose captured images in the returned artifacts list. The execute_code tool converts those artifacts into ImgPath / ImgUrl multimodal returns for the agent loop.
reset_repl
Clear all user variables but keep runtime backends:Runtime Namespace
Insideexecute_code, the runtime object provides:
Streaming Output
PyRepl emits custom events for real-time output:| Event Name | Data | When |
|---|---|---|
kernel_stdout | {"text": "..."} | Each stdout flush |
kernel_stderr | {"text": "..."} | Each stderr flush |
Output Truncation
If a tool result exceeds ~20,000 tokens:- Full output is written to a temporary file
- Truncated version (first ~4,096 tokens) + file path is returned to the model
- The model can use
read_fileto access specific parts
_too_long_to_file=True.
Working Directory
os.getcwd() inside execute_code returns this path.
Installing Custom Primitive Packs
runtime.mytools.* is available in execute_code.
SelfRef Integration
When usingself_reference_key on the agent, the framework automatically:
- Creates a SelfReference backend
- Builds the selfref primitive pack
- Installs it in the PyRepl instance
- Makes
runtime.selfref.*available