Skip to content
Agent

Agent Sessions

Sessions are the unit of interaction with an agent. Create one session per task, send prompts, and consume event history.

For SDK-based flows, sessions can be restored after runtime/session loss when persistence is enabled. See Session Restoration.

import { SandboxAgent } from "sandbox-agent";
const sdk = await SandboxAgent.connect({
baseUrl: "http://127.0.0.1:2468",
});
const session = await sdk.createSession({
agent: "codex",
cwd: "/",
});
console.log(session.id, session.agentSessionId);
const response = await session.prompt([
{ type: "text", text: "Summarize the repository structure." },
]);
console.log(response.stopReason);
const unsubscribe = session.onEvent((event) => {
console.log(event.eventIndex, event.sender, event.payload);
});
await session.prompt([
{ type: "text", text: "Explain the main entrypoints." },
]);
unsubscribe();

Each event’s payload contains a session update. The sessionUpdate field identifies the type.

agent_message_chunk

Streamed text or content from the agent’s response.

{
"sessionUpdate": "agent_message_chunk",
"content": { "type": "text", "text": "Here's how the repository is structured..." }
}
agent_thought_chunk

Internal reasoning from the agent (chain-of-thought / extended thinking).

{
"sessionUpdate": "agent_thought_chunk",
"content": { "type": "text", "text": "I should start by looking at the project structure..." }
}
user_message_chunk

Echo of the user’s prompt being processed.

{
"sessionUpdate": "user_message_chunk",
"content": { "type": "text", "text": "Summarize the repository structure." }
}
tool_call

The agent invoked a tool (file edit, terminal command, etc.).

{
"sessionUpdate": "tool_call",
"toolCallId": "tc_abc123",
"title": "Read file",
"status": "in_progress",
"rawInput": { "path": "/src/index.ts" }
}
tool_call_update

Progress or result update for an in-progress tool call.

{
"sessionUpdate": "tool_call_update",
"toolCallId": "tc_abc123",
"status": "completed",
"content": [{ "type": "text", "text": "import express from 'express';\n..." }]
}
plan

The agent’s execution plan for the current task.

{
"sessionUpdate": "plan",
"entries": [
{ "content": "Read the project structure", "status": "completed" },
{ "content": "Identify main entrypoints", "status": "in_progress" },
{ "content": "Write summary", "status": "pending" }
]
}
usage_update

Token usage metrics for the current turn.

{
"sessionUpdate": "usage_update"
}
session_info_update

Session metadata changed (e.g. agent-generated title).

{
"sessionUpdate": "session_info_update",
"title": "Repository structure analysis"
}
const page = await sdk.getEvents({
sessionId: session.id,
limit: 50,
});
for (const event of page.items) {
console.log(event.id, event.createdAt, event.sender);
}
const sessions = await sdk.listSessions({ limit: 20 });
for (const item of sessions.items) {
console.log(item.id, item.agent, item.createdAt);
}
if (sessions.items.length > 0) {
const loaded = await sdk.resumeSession(sessions.items[0]!.id);
await loaded.prompt([{ type: "text", text: "Continue." }]);
}

Set the model, mode, or thought level on a session at creation time or after:

// At creation time
const session = await sdk.createSession({
agent: "codex",
model: "gpt-5.3-codex",
mode: "auto",
thoughtLevel: "high",
});
// After creation
await session.setModel("gpt-5.2-codex");
await session.setMode("full-access");
await session.setThoughtLevel("medium");

Query available modes:

const modes = await session.getModes();
console.log(modes?.currentModeId, modes?.availableModes);

For config options beyond model, mode, and thought level, use getConfigOptions to discover what the agent supports and setConfigOption to set any option by ID:

const options = await session.getConfigOptions();
for (const opt of options) {
console.log(opt.id, opt.category, opt.type);
}
await session.setConfigOption("some-agent-option", "value");

For agents that request tool-use permissions, register a permission listener and reply with once, always, or reject:

const session = await sdk.createSession({
agent: "claude",
mode: "default",
});
session.onPermissionRequest((request) => {
console.log(request.toolCall.title, request.availableReplies);
void session.respondPermission(request.id, "once");
});
await session.prompt([
{ type: "text", text: "Create ./permission-example.txt with the text hello." },
]);

To auto-approve all permission requests, respond with "once" or "always" in your listener:

session.onPermissionRequest((request) => {
void session.respondPermission(request.id, "always");
});

See examples/permissions/src/index.ts for a complete permissions example that works with Claude and Codex.

await sdk.destroySession(session.id);