Features
Persistent Context
Variables persist across calls, which is useful for iterative analysis and coding tasks.
Async, Non-blocking
Execution runs off the main event loop so UI and event streaming stay responsive.
Real-time Event Output
Receive stdout, stderr, and input requests via
event_emitter.Session Isolation
Different
PyRepl instances do not share state.Long Output Truncation
Large outputs can be stored to a temporary file and returned in truncated form.
Runtime Primitives
Expose controlled runtime capabilities through
runtime.selfref.* and related primitives.Quick Start
Multiple isolated sessions
Tool Details
execute_code
Execute Python code and return the execution result.execute_code has a default 600-second active execution timeout. Time spent waiting for input() does not count toward that limit. Each input() request also has its own default 300-second idle timeout.When output exceeds 20,000 tokens,
execute_code stores the full result in a temporary file and returns only a truncated preview plus a <system-reminder> note with the file path.The guidance sent to the model encourages it to inspect runtime primitives with
runtime.list_primitives() and runtime.get_primitive_spec(...), and reminds it that reset_repl clears REPL variables but keeps registered runtime backends.| Parameter | Type | Description |
|---|---|---|
code | str | Python code to execute |
timeout_seconds | float | Optional per-call timeout override |
event_emitter | ToolEventEmitter | Optional emitter for realtime output |
PyRepl.execute() directly.
Python API return value
Improved error localization
execute_code tries to return information about the actual user code location rather than only the internal framework stack.
Typical error_details fields:
error_typemessageline/columnsnippetpointersummaryuser_traceback
reset_repl
Reset the REPL state and clear all variables.Model-facing tool descriptions make it explicit that
reset_repl clears REPL variables but keeps the registered runtime backend.Streaming Events
Whenenable_event=True, execute_code can emit these realtime events:
| Event name | Data shape | Description |
|---|---|---|
kernel_stdout | {text: str} | Standard output |
kernel_stderr | {text: str} | Standard error |
kernel_input_request | {request_id: str, prompt: str, idle_timeout_seconds: float} | An input() request waiting for user input |
Consuming streaming events
kernel_input_request, you can reply by calling PyRepl.submit_input(request_id, value).
When you consume event streams from @llm_chat(enable_event=True), output.origin can also be used to distinguish the main chain from forked sub-chains.
Usage Example
Data analysis assistant
Persistent programming context
Configuration Options
Runtime and Self-Reference
PyRepl installs the built-inselfref pack by default.
runtime.selfref.context.inspect()runtime.selfref.context.remember(...)runtime.selfref.context.forget(...)runtime.selfref.context.compact(...)runtime.selfref.fork.spawn(...)runtime.selfref.fork.gather_all(...)
- Child forks inherit the pre-fork context snapshot, not the parent’s pending fork tool-call scene.
runtime.selfref.fork.gather_all(...)returnsdict[fork_id -> ForkResult].- Compact results expose
status,response,result,memory_key,history_count, andhistory_included. - Check
statusfirst, then readresponseorresult. Useinclude_history=Trueonly when full child history is actually needed.
Best Practices
- Use different PyRepl instances for different task scopes
- Keep execution snippets small and inspect output between steps
- Use event streaming for better UX in TUI or custom interfaces
- Reset the REPL when you want a clean state without removing runtime backends