Kill Switch
session.kill() is an emergency stop for your AI agent. It blocks all subsequent tool calls immediately — no negotiation, no retries, no "one more call."
Why you need this
A Meta AI safety director's personal assistant agent started deleting every email older than one week. She said "STOP" multiple times. The agent ignored her. She had to physically run to her machine and kill the process.
There was no kill switch. There is now.
How it works
// Something's going wrong — stop immediately
session.kill();
// All subsequent calls throw ReplayKillError
try {
await session.client.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Continue processing" }],
tools,
});
} catch (e) {
if (e instanceof ReplayKillError) {
console.log("Session killed — no more tool calls");
}
}
After kill():
- Every call through
session.client.create()throwsReplayKillError - Session state is frozen — no further state changes
- Pending captures are flushed
- The session cannot be resumed
- In Govern mode, the kill is propagated to the server
What kill can and can't do
What it does
- Blocks all future calls through the wrapper
- Freezes session state (
stateVersion,forbiddenToolsstop changing) - Sets
killed: truepermanently - Flushes any pending captures
- In Govern mode, marks the server-side session as
KILLED
What it can't do
- Can't stop in-flight calls. If a tool executor is currently running (e.g., a database write),
kill()doesn't interrupt it. The executor completes — its side effects have already occurred. After it returns, the SDK detects the kill, discards the result, and throws on the next call. - Can't stop server-side agent loops. If you're using OpenAI Assistants or another hosted agent platform where the execution loop runs server-side,
kill()only affects your SDK client — it can't reach the server-side thread. - Can't undo what already happened. If the agent already issued a refund or deleted a file,
kill()doesn't reverse that. It prevents the next action.
Automatic kill: circuit breaker
You don't always need to call kill() manually. The circuit breaker auto-kills the session after too many consecutive failures.
# session.yaml
session_limits:
circuit_breaker:
consecutive_blocks: 5 # Auto-kill after 5 consecutive blocked calls
consecutive_errors: 3 # Auto-kill after 3 consecutive internal errors
When the circuit breaker triggers, it calls kill() internally. Same behavior — all subsequent calls throw ReplayKillError.
After killing: recovery
A killed session is permanently dead. To continue, create a new session:
// Kill the broken session
session.kill();
// Restore the original client
session.restore();
// Start a new session (optionally in log-only mode for recovery)
const recoverySession = replay(client, {
contractsDir: "./contracts",
agent: "my-agent",
mode: "enforce", // or "log-only" for recovery actions
});
restore() releases the wrapper and returns the original client to its normal state. You must call restore() before creating a new replay() session on the same client.
Checking kill status
const state = session.getState();
console.log(state.killed); // true after kill()
const health = session.getHealth();
console.log(health.killed); // true
console.log(health.authorityState); // "killed"
console.log(health.status); // "inactive"
Kill in Govern mode
When connected to the Vesanor server, kill() propagates durably:
- SDK marks local session as killed
- Kill request sent to server
- Server marks session status as
KILLED - Future preflight/proposal/receipt requests are rejected
- Server-side session cannot be resumed
// Verify kill propagated
const health = session.getHealth();
console.log(health.durability); // "server" — kill is durable
When to use kill
| Scenario | Use kill? |
|---|---|
| Agent is in a loop | Yes — or let circuit breaker handle it |
| Agent called a destructive tool it shouldn't have | Yes — prevent further damage |
| Agent exceeded budget | Automatic — max_cost_per_session triggers kill |
| User requests stop | Yes — wire to your UI's stop button |
| Debugging complete | No — use session.restore() to cleanly end |
| Normal session end | No — just stop calling session.client |
Next steps
- Session Limits — automatic budget and loop protection
- Govern Mode — server-backed kill propagation
- Protection Levels — understand enforcement levels