praisonai-ts ships one on this machine and one in a Docker container, and lets you plug in remote providers by name.
Quick Start
1
Run a command on this machine
2
Run it in an isolated Docker container
3
Resolve a provider by name
How It Works
A provider is resolved by name, provisions an instance, runs commands against it, then tears it down.Configuration Options
Every provider accepts the sameComputeConfig on provision() and execute().
ComputeToolPlace — turning a provider into a tool place
ComputeToolPlace adapts a ComputeProvider to the place toolsRunOn selects, so a tool call can run on the provider instead of in the host process.
{{arg}} is single-quoted.
setCommand(toolName, template) declares a tool after construction.
Auto-registration on import
registerComputeToolPlaces() populates the placement registry with the built-in providers (local, docker). It is idempotent and called on import of praisonai/compute, so consumers never call it themselves. Registering a new compute provider with registerComputeProvider('e2b', …) also mirrors into the placement registry, so new Agent({ toolsRunOn: 'e2b' }) works after that one call.
LocalCompute
Runs commands in the host Node process — the honest baseline that does not isolate anything.
- Spawns a detached shell (
/bin/sh -con POSIX,%ComSpec% /d /s /con Windows) and kills the whole process group on timeout, so a backgrounded descendant ((sleep 3; touch marker) &) is terminated with the shell rather than orphaned. - Does not sandbox. Use
DockerComputeor a remote provider for untrusted code. - Unavailable in webviews / mobile / any runtime without
child_process.child_processis loaded through a computed specifier so bundlers cannot see it statically; there,isAvailable()returnsfalseand anyprovision()/execute()throwsComputeError.
DockerCompute
Real isolation via the docker CLI.
- Uses the
dockerCLI directly — no Docker SDK dependency, because this package ships to a webview. - Default image
python:3.11-slim, default workdir/workspace. - Checks
docker info, notdocker --version— the CLI can be installed while the daemon is down, so it surfaces “daemon down” honestly instead of promising availability and then failing on provision. - Timeouts fire inside the container (
timeout -k 5 <seconds>), so the process is actually killed — not just the host-sidedocker execclient, which would leave the command running. shutdown()runsdocker rm -f <id>; if that fails, the instance is markederrorandComputeErroris raised (“Could not remove container … It may still be running.”). A container reported stopped while still running is exactly the silent wrongness this guards against. A clean removal forgets the container.- Env vars, workdir, and image on
ComputeConfigare honoured; shell metacharacters in values are single-quoted, so a filename with a space cannot become two arguments.
The Registry
Providers resolve by name through an open registry.registerComputeProvider(name, factory)— add a provider. Names are lower-cased.listComputeProviders()— the names available in this build. Ships with['docker', 'local'].resolveComputeProvider(nameOrInstance)— returns a provider, ornullfor an empty target. An unknown name throws and lists what exists.
resolveComputeProvider handles each input shape:
An unknown name RAISES — deliberately
local for an unrecognised sandbox name would run on the host something the caller explicitly asked to isolate. That is a security property, not an inconvenience — the same reasoning as the Python contract.
Adding a remote provider
Any consumer can register one without touching the SDK.Timeouts and Exit Codes
A timeout is its own outcome, not a non-zero exit.DockerCompute maps the container-side timeout exit code 124 back to the same { timedOut: true, exitCode: null }, so both providers report timeouts identically. On POSIX, LocalCompute escalates the timeout SIGTERM → SIGKILL 2 s later, so a shell that ignores SIGTERM still goes.
Common Patterns
Try Docker for isolation, fall back to Local in development:Best Practices
Never trust LocalCompute for untrusted code
Never trust LocalCompute for untrusted code
LocalCompute runs in the host process without isolation. Anything the command can reach, your app can reach. Use DockerCompute or a remote provider for anything you did not write.Always shut instances down
Always shut instances down
Especially with Docker — an ungoverned container is not free. Pair every
provision() with a shutdown(), even on the error path.Check isAvailable() before you rely on a provider
Check isAvailable() before you rely on a provider
Fail loudly at boot rather than mid-run.
docker.isAvailable() checks the daemon; a remote provider checks its credentials.Let an unknown name raise
Let an unknown name raise
An unknown provider name raises on purpose. Silencing it — falling back to
local — defeats the point of asking for a sandbox.Related
Placement
The
toolsRunOn / runOn / backend axesCompute Providers (Python)
The Python counterpart of this contract

