Core platform

Sessions & environments

A one-shot /v1/exec runs in a throwaway VM and keeps nothing. An RL environment is driven over many steps, with state carrying forward. A session is one live VM held alive across calls: files and the working tree persist between steps, so an agent can search, edit, test, and repeat against the same machine. This is the shape an environment's step() loop needs, and it is the primary way to run Collimate in production.

Stateless exec vs. a session

/v1/execSession
LifetimeOne throwaway VM per callOne live VM, many calls
State between callsNone, fresh each timePersists (files, working tree)
Per-call spawn costA new VM each callSpawned once, then ~0
Best forIndependent samples, batch fan-outMulti-step agents, RL step() loops

Between calls a session's vCPUs are descheduled, so the VM sits idle until you drive the next step, then resumes in microseconds.

Lifecycle at a glance

  POST /v1/sessions            create one live VM from a template      -> session_id
       │
       ▼  (repeat, state persists)
  POST /v1/sessions/{id}/exec  run code · run commands · write files
       │
       ▼
  GET  /v1/sessions/{id}       status (age, idle, exec_count)
  GET  /v1/sessions            list live sessions
       │
       ▼
  DELETE /v1/sessions/{id}     destroy the VM, reclaim memory

Create a session

POST/v1/sessions

Spawns one live VM from a template and holds it open. template_id is required.

http
POST /v1/sessions
Authorization: Bearer col_live_...
Content-Type: application/json

{ "template_id": "my-env" }

201 Created
{
  "session_id": "sess_019cf68f0a1c7e2b...",
  "template_id": "my-env",
  "fork_time_ms": 1.3,
  "create_time_ms": 64.2
}
template_id
string, required · the template to spawn the VM from. 400 if absent.
session_id
Opaque handle (sess_…) used for every later call on this VM.
create_time_ms
Total bring-up time, including the readiness probe.

Run a step

POST/v1/sessions/{id}/exec

Drive the live VM. Send one of three payloads (or combine files with commands). State from previous steps is always visible. The response shape matches /v1/exec, except there is no per-call spawn, so fork_time_ms is 0.

Run code

http
POST /v1/sessions/{id}/exec
{ "code": "import os; print(os.listdir('/app'))", "timeout_seconds": 30 }

200 OK
{ "id": "...", "stdout": "['src', 'tests']\n", "stderr": "", "exit_code": 0,
  "fork_time_ms": 0, "exec_time_ms": 12.4, "total_time_ms": 12.4 }

Run commands

Each command is an argv array, run from the working directory.

http
POST /v1/sessions/{id}/exec
{ "commands": [ ["grep", "-rn", "bug", "src/"], ["python", "-m", "pytest", "-x"] ] }

Write files

Write or overwrite files in the live VM, for example applying an edit before re-running tests.

http
POST /v1/sessions/{id}/exec
{ "files": [ { "path": "/app/src/handler.py", "content": "def handle(): ..." } ] }
__ICO_book__

Each command runs fresh from the working directory, so file edits persist but shell-process state (a bare cd, exported vars) does not, exactly like docker exec. Use absolute paths, or wrap in bash -lc '…'.

code
string · source to run in the VM.
commands
array of argv arrays · run in order; the response reflects the last.
files
array of {path, content} · written before any commands run.
timeout_seconds
int, optional · default 30.

Inspect & list

GET/v1/sessions/{id}
GET/v1/sessions
http
GET /v1/sessions/{id}
200 OK
{ "session_id": "sess_...", "template_id": "my-env",
  "age_secs": 184, "idle_secs": 12, "exec_count": 7 }

GET /v1/sessions
200 OK
{ "sessions": [ { "session_id": "sess_...", "idle_secs": 12, "exec_count": 7 }, ... ] }

Destroy a session

DELETE/v1/sessions/{id}

Destroys the VM and reclaims its memory. By default an in-flight exec is allowed to finish first; pass ?force=true to abort it immediately.

bash
curl -X DELETE 'https://api.collimate.ai/v1/sessions/'$SID'?force=true' \
  -H 'Authorization: Bearer col_live_...'   # -> 204 No Content

End-to-end example

A full step loop over one session: search, edit, test, then reclaim the VM.

bash
# 1. open one live VM
SID=$(curl -s -X POST https://api.collimate.ai/v1/sessions \
  -H 'Authorization: Bearer col_live_...' \
  -d '{"template_id":"my-env"}' | jq -r .session_id)

# 2. step through it, state carries over
curl -X POST https://api.collimate.ai/v1/sessions/$SID/exec \
  -d '{"commands":[["grep","-rn","TODO","src/"]]}'

curl -X POST https://api.collimate.ai/v1/sessions/$SID/exec \
  -d '{"files":[{"path":"/app/src/fix.py","content":"# patched"}]}'

curl -X POST https://api.collimate.ai/v1/sessions/$SID/exec \
  -d '{"commands":[["python","-m","pytest","-x"]]}'

# 3. reclaim the VM
curl -X DELETE https://api.collimate.ai/v1/sessions/$SID

An RL environment in a few lines

Wrap the lifecycle in a Gym-style environment: reset() opens a session, step() drives it, close() reclaims it.

python
class SandboxEnv:
    def __init__(self, client, template_id):
        self.client, self.template_id, self.sid = client, template_id, None

    def reset(self):
        self.sid = self.client.open_session(self.template_id)   # one VM
        return self.observe()

    def step(self, action):
        result = self.client.session_exec(self.sid, action)     # state persists
        return self.observe(), self.score(result), self.is_done(result), {}

    def close(self):
        if self.sid:
            self.client.close_session(self.sid)                 # reclaim VM

Each environment instance is a real, isolated VM. Run hundreds concurrently on one host; the memory cost is only the pages each one changes.

Lifecycle, limits & status codes

Idle reaping
Sessions idle past their TTL are reclaimed automatically. Send any exec to keep one warm.
Capacity
Creating past the live-session cap returns 429.
Pausing
A session uses no scheduled CPU between calls; it resumes on the next exec.
Auth & rate limit
Bearer col_live_… token; 100 requests/second per key.

BYOC deployments can tune the live-session cap, idle TTL, reaper interval, and bring-up timeouts; ask us for the tuning reference.

400
Missing template_id on create.
404 / 410
Unknown session · the session's VM has been reclaimed.
409
Template not ready (still building).
429
Rate limit or live-session capacity exceeded.
503 / 504
VM spawn failed · bring-up timed out.

Related