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 .
Create a session
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 );
Send a prompt
const response = await session . prompt ([
{ type: "text" , text: "Summarize the repository structure." },
]);
console . log ( response . stopReason );
Subscribe to live events
const unsubscribe = session . onEvent (( event ) => {
console . log ( event . eventIndex , event . sender , event . payload );
});
await session . prompt ([
{ type: "text" , text: "Explain the main entrypoints." },
]);
unsubscribe ();
Event types
Each event’s payload contains a session update. The sessionUpdate field identifies the type.
Streamed text or content from the agent’s response. {
"sessionUpdate" : "agent_message_chunk" ,
"content" : { "type" : "text" , "text" : "Here's how the repository is structured..." }
}
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..." }
}
Echo of the user’s prompt being processed. {
"sessionUpdate" : "user_message_chunk" ,
"content" : { "type" : "text" , "text" : "Summarize the repository structure." }
}
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" }
]
}
Token usage metrics for the current turn. {
"sessionUpdate" : "usage_update"
}
Session metadata changed (e.g. agent-generated title). {
"sessionUpdate" : "session_info_update" ,
"title" : "Repository structure analysis"
}
Fetch persisted event history
const page = await sdk . getEvents ({
sessionId: session . id ,
limit: 50 ,
});
for ( const event of page . items ) {
console . log ( event . id , event . createdAt , event . sender );
}
List and load sessions
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 );
Advanced config options
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" );
Handle permission requests
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." },
]);
Auto-approving permissions
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.
Some agents like Claude allow configuring permission behavior through modes (e.g. bypassPermissions, acceptEdits). We recommend leaving the mode as default and handling permission decisions explicitly in onPermissionRequest instead.
Destroy a session
await sdk . destroySession ( session . id );