Skip to content

Destroy

How a worker winds down when the agent no longer needs it. The orchestrator owns the lifecycle — not the LLM — so teardown is deterministic and nothing leaks.

Lifecycle: DeployUseDestroy.

Session states

A row in Postgres — AgentRuntimeSession — tracks the live runtime; the pod holds no durable state:

pending → starting → running → idle → stopping → stopped
                       ▲          │
                       └──────────┘  a follow-up turn reuses the session, resets the idle timer

AgentRuntimeSession { agentId, taskId?, status, runtimeType, cpu/mem/storageLimit, ttlSeconds, k8sJobName, namespace, workerUrl, logsUrl, started/lastActivity/stoppedAt }.

Two ways out

TriggerWhoWhat happens
End of turn → idleorchestratorthe session is marked idle and kept warm, not killed, so the next turn of the same conversation reuses it (no cold start)
Explicit releasebrain (LLM)when there's clearly no more work (one-shot task, user said goodbye) the brain sends release over the control channel immediately

The LLM may emit a done hint for early release, but the default is automatic via the reaper.

The idle reaper

Implemented as BullMQ delayed jobs keyed by sessionId, rescheduled on every heartbeat:

  • Light idle 60–120s → stop · Heavy 30–60s · Browser alive until browser idle · Warm/premium 10–30 min.
  • A follow-up turn within the window reuses the session and resets the timer.
  • Missing heartbeats → Core marks the session failed and reaps it (zombie protection).

Cleanup on stop (the order matters)

On expiry or release, before the Job is gone:

  1. Ensure outputs are uploaded from the workspace to system/file (object storage).
  2. Wipe the emptyDir workspace.
  3. Delete the Job; set AgentRuntimeSession.status = stopped.

ttlSecondsAfterFinished is the backstop for normally-finished Jobs; the reaper handles idle and zombie sessions that never finished cleanly.

Hard caps (so nothing leaks)

  • activeDeadlineSeconds — hard max execution time (RuntimeProfile.maxExecSeconds); a runaway runtime is killed by k8s.
  • Max-idle ceiling — even the Warm profile only extends the idle window; it never disables the cap.
  • Audit — every session logs start/stop/tools/artifacts via admin/audit.

And the agent lives on

Destroying the worker does not end the agent. The mind stays up: it keeps streaming to the user, handles agent/cron and follow-ups, and can summon a fresh worker later. The worker was only a temporary appendage; the agent (a row in the DB + the api loop) persists.

See also

  • Deploy — provisioning, the Job, runtime profiles.
  • Tool channel — the release frame, its grace window, and what silence means.
  • Use — the session model and the control channel that carries release.
  • Implementation — the build prompt for this subsystem.
  • Runtime model — the per-turn flow end to end.