#Contexts (Process Runtime)
Contexts are execution units within a sandbox. Each context runs a process and can be either a REPL (stateful) or Cmd (stateless) type.
Context Types#
| Type | Description | Use Case |
|---|---|---|
| REPL | Stateful, interactive process | Code evaluation, interactive shells, persistent sessions |
| Cmd | Stateless, one-shot command | Single commands, scripts, non-interactive execution |
REPL vs Cmd#
REPL contexts preserve state between calls - variables, environment, and working directory persist. Cmd contexts are stateless - each execution starts fresh.
python# REPL: State preserved between calls _S0_> x = 2 _S0_> print(x) 2 # Cmd: Each command is independent $ x=2 $ echo $x # Empty - variable not preserved
High-Level: Run and Cmd#
For common use cases, use the convenience methods Run (REPL) and Cmd (command).
Run (REPL)#
Execute code in a REPL context. State is preserved between calls.
go// First call - set variable result, err := sandbox.Run(ctx, "python", "x = 2") if err != nil { log.Fatal(err) } fmt.Print(result.OutputRaw) // Second call - variable preserved result, err = sandbox.Run(ctx, "python", "print(x)") if err != nil { log.Fatal(err) } fmt.Print(result.OutputRaw)
Run with Options#
go// Create a custom context with specific cwd, env vars, and TTL customCtx, err := sandbox.CreateContext(ctx, apispec.CreateContextRequest{ Type: apispec.NewOptProcessType(apispec.ProcessTypeRepl), Repl: apispec.NewOptCreateREPLContextRequest(apispec.CreateREPLContextRequest{ Alias: apispec.NewOptString("python"), }), Cwd: apispec.NewOptString("/workspace"), EnvVars: apispec.NewOptCreateContextRequestEnvVars(map[string]string{"GREETING": "hello from workspace"}), TTLSec: apispec.NewOptInt32(120), IdleTimeoutSec: apispec.NewOptInt32(60), }) if err != nil { log.Fatal(err) } fmt.Printf("Custom context ID: %s\n", customCtx.ID) // Run using the custom context result, err = sandbox.Run( ctx, "python", `import os, pathlib; print(pathlib.Path.cwd()); print(os.getenv("GREETING"))`, sandbox0.WithContextID(customCtx.ID), ) if err != nil { log.Fatal(err) } fmt.Print(result.OutputRaw)
Cmd (One-shot Command)#
Execute a stateless command.
go// One-shot command - stateless result2, err := sandbox.Cmd(ctx, `/bin/sh -c "echo hi"`) if err != nil { log.Fatal(err) } fmt.Print(result2.OutputRaw) // Variables NOT preserved between Cmd calls sandbox.Cmd(ctx, `/bin/sh -c "x=3"`) result2, err = sandbox.Cmd(ctx, `/bin/sh -c "echo $x"`) if err != nil { log.Fatal(err) } fmt.Print(result2.OutputRaw)
Cmd with Options#
goresult2, err = sandbox.Cmd( ctx, "bash -c 'echo $GREETING && pwd'", sandbox0.WithCmdCWD("/tmp"), sandbox0.WithCmdEnvVars(map[string]string{"GREETING": "hello"}), sandbox0.WithCmdTTL(120), sandbox0.WithCmdIdleTimeout(60), ) if err != nil { log.Fatal(err) } fmt.Print(result2.OutputRaw)
Create Context#
Create a new context in a sandbox.
/api/v1/sandboxes/{id}/contexts
Request Body#
| Field | Type | Description |
|---|---|---|
type | string | Context type: repl or cmd |
repl | object | REPL configuration (optional for type=repl; defaults to Python when omitted) |
cmd | object | Command configuration (cmd.command required if type=cmd) |
cwd | string | Working directory |
env_vars | object | Environment variables |
pty_size | object | Terminal size {rows, cols} |
ttl_sec | integer | Context time-to-live in seconds |
idle_timeout_sec | integer | Idle timeout in seconds |
wait_until_done | boolean | Wait for completion (default: false) |
REPL Configuration#
| Field | Type | Description |
|---|---|---|
alias | string | REPL alias/language (python, bash, node, etc.) |
input | string | Initial input to send |
repl_config | object | Custom REPL config (optional; advanced use) |
Cmd Configuration#
| Field | Type | Description |
|---|---|---|
command | array | Command and arguments |
go// Create REPL context ctxResp, err := sandbox.CreateContext(ctx, apispec.CreateContextRequest{ Type: apispec.NewOptProcessType(apispec.ProcessTypeRepl), Repl: apispec.NewOptCreateREPLContextRequest(apispec.CreateREPLContextRequest{ Alias: apispec.NewOptString("python"), }), Cwd: apispec.NewOptString("/workspace"), EnvVars: apispec.NewOptCreateContextRequestEnvVars(map[string]string{"DEBUG": "true"}), TTLSec: apispec.NewOptInt32(120), }) if err != nil { log.Fatal(err) } fmt.Printf("Context ID: %s\n", ctxResp.ID)
Custom REPL (repl_config)#
Use repl_config when you need to run a non-built-in REPL, customize startup arguments, or tune readiness detection.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | REPL identifier. If alias is also set, it must match repl_config.name. |
display_name | string | No | Human-readable name. |
description | string | No | Description for this REPL config. |
candidates | array | Yes | Ordered executable candidates. Each item: { name, args }. |
env | array | No | Environment variables. Each item: { name, value } or { name, value_from }. |
default_term | string | No | Default TERM value when no terminal value is provided. |
prompt.custom_prompt | string | No | Custom prompt string used by REPLs that support prompt env injection. |
ready.mode | string | No | Readiness strategy: prompt_token or startup_delay. |
ready.token | string | Cond. | Required when ready.mode=prompt_token. |
ready.startup_delay_ms | integer | Cond. | Used when ready.mode=startup_delay (must be >= 0). |
Notes:
candidatesmust contain at least one executable.- If
ready.modeis omitted, runtime picks a default strategy based on whetherready.tokenis provided. - Common
env.value_fromvalues aretermandprompt.
Example request:
json{ "type": "repl", "repl": { "alias": "myrepl", "repl_config": { "name": "myrepl", "display_name": "My REPL", "candidates": [ { "name": "myrepl", "args": ["--interactive"] }, { "name": "python3", "args": ["-q", "-i"] } ], "env": [ { "name": "TERM", "value_from": "term" } ], "ready": { "mode": "startup_delay", "startup_delay_ms": 300 } } } }
List Contexts#
List all contexts in a sandbox.
/api/v1/sandboxes/{id}/contexts
gocontexts, err := sandbox.ListContext(ctx) if err != nil { log.Fatal(err) } for _, ctx := range contexts { fmt.Printf("- %s (type: %s, running: %v)\n", ctx.ID, ctx.Type, ctx.Running) }
Get Context#
Get details of a specific context.
/api/v1/sandboxes/{id}/contexts/{ctx_id}
goctxResp, err = sandbox.GetContext(ctx, ctxResp.ID) if err != nil { log.Fatal(err) } fmt.Printf("Type: %s\n", ctxResp.Type) fmt.Printf("Running: %v\n", ctxResp.Running)
Context Control Operations#
Restart Context#
Restart a context process.
/api/v1/sandboxes/{id}/contexts/{ctx_id}/restart
go_, err = sandbox.RestartContext(ctx, ctxResp.ID) if err != nil { log.Fatal(err) }
Send Input#
Send input to a context's stdin.
/api/v1/sandboxes/{id}/contexts/{ctx_id}/input
go_, err = sandbox.ContextInput(ctx, ctxResp.ID, "print('hello')") if err != nil { log.Fatal(err) }
Resize PTY#
Resize the terminal dimensions.
/api/v1/sandboxes/{id}/contexts/{ctx_id}/resize
go_, err = sandbox.ContextResize(ctx, ctxResp.ID, 24, 80) if err != nil { log.Fatal(err) }
Send Signal#
Send a signal to the context process.
/api/v1/sandboxes/{id}/contexts/{ctx_id}/signal
go// Send SIGTERM _, err = sandbox.ContextSignal(ctx, ctxResp.ID, "TERM") if err != nil { log.Fatal(err) }
Get Context Stats#
Get resource usage statistics for a context.
/api/v1/sandboxes/{id}/contexts/{ctx_id}/stats
gostats, err := sandbox.ContextStats(ctx, ctxResp.ID) if err != nil { log.Fatal(err) } fmt.Printf("Memory: %d bytes\n", stats.Usage.Value.MemoryRss.Value) fmt.Printf("CPU: %.2f%%\n", stats.Usage.Value.CPUPercent.Value)
Delete Context#
Delete a context.
/api/v1/sandboxes/{id}/contexts/{ctx_id}
go_, err = sandbox.DeleteContext(ctx, ctxResp.ID) if err != nil { log.Fatal(err) } fmt.Println("Context deleted")
WebSocket Streaming#
For real-time I/O, connect to a context via WebSocket.
/api/v1/sandboxes/{id}/contexts/{ctx_id}/ws
WebSocket Protocol#
Client Messages:
| Type | Description | Example |
|---|---|---|
input | Send input to stdin | {"type": "input", "data": "ls\n", "request_id": "req-1"} |
resize | Resize terminal | {"type": "resize", "rows": 24, "cols": 80} |
signal | Send signal | {"type": "signal", "signal": "INT"} |
Server Messages:
| Type | Description | Example |
|---|---|---|
output | Process output (stdout / stderr / pty) | {"source": "stdout", "data": "hello\n"} |
go// Create context first ctxResp, err = sandbox.CreateContext(ctx, apispec.CreateContextRequest{ Type: apispec.NewOptProcessType(apispec.ProcessTypeRepl), Repl: apispec.NewOptCreateREPLContextRequest(apispec.CreateREPLContextRequest{ Alias: apispec.NewOptString("python"), }), }) if err != nil { log.Fatal(err) } // Connect WebSocket conn, _, err := sandbox.ConnectWSContext(ctx, ctxResp.ID) if err != nil { log.Fatal(err) } defer conn.Close() // Send input msg := map[string]any{ "type": "input", "data": "print('hello')\n", "request_id": "req-1", } conn.WriteJSON(msg) conn.SetReadDeadline(time.Now().Add(3 * time.Second)) // Read output for { _, message, err := conn.ReadMessage() if err != nil { break } var msg struct { Source string `json:"source"` Data string `json:"data"` } json.Unmarshal(message, &msg) fmt.Print(msg.Data) }
Exec (Synchronous Execution)#
Execute input and wait for completion.
/api/v1/sandboxes/{id}/contexts/{ctx_id}/exec
goexecResult, err := sandbox.ContextExec(ctx, ctxResp.ID, "print(1 + 2)") if err != nil { log.Fatal(err) } fmt.Print(execResult.OutputRaw)
Next Steps#
Files
Read, write, and manage files in sandboxes
Network Policy
Control network access and egress rules
Port Exposure
Expose sandbox ports publicly