Overview
Callbacks let you hook into the SmolVM command lifecycle. You subclassCallback, override the hooks you care about, and pass instances to SmolVM(callbacks=[...]). Every other hook is a no-op by default.
For a task-oriented walkthrough, see Run callbacks and safety hooks.
Callback
Base class for SmolVM command-lifecycle callbacks. Subclass it and override only the hooks you need.Hooks
Each hook receives a singleRunContext argument.
on_pre_run
run(). Raise CommandBlockedError for an explicit, typed block.
A blocked command keeps the SSH or vsock connection open, so the next allowed run() call reuses it.
on_post_run
ctx.result is populated. Observer hook — exceptions are logged and swallowed so a faulty observer cannot break a command that already ran.
on_run_error
ctx.error is populated. Observer hook — exceptions are logged and swallowed, and the original transport error still propagates from run().
RunContext
Dataclass passed to every hook for a singleSmolVM.run() call. Using one object means new fields can be added later without changing any callback’s method signature.
The VM the command targets.
The shell command as passed to
run().Execution mode —
"login" or "raw".Per-command timeout in seconds.
The command result.
None until on_post_run. See CommandResult.The transport error raised during execution.
None unless the hook is on_run_error.CommandBlockedError
Exception type for vetoing a command fromon_pre_run. Inherits from SmolVMError.
Human-readable reason for the block.
ID of the VM the command targeted. Stored on the exception and in
details.The blocked command string. Stored on the exception and in
details.vm_id(str | None): The VM the command targeted.command(str | None): The blocked command string.message(str): Reason passed to the constructor.details(dict): Containsvm_idandcommand.
