mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-15 08:03:46 +00:00
fix: harden session lifecycle and align cli.mdx example with claude.json
- destroySession: wrap session/cancel RPC in try/catch so local cleanup always succeeds even when the agent is unreachable - createSession/resumeOrCreateSession: clean up the remote session if post-creation config calls (setMode/setModel/setThoughtLevel) fail, preventing leaked orphan sessions - cli.mdx: fix example output to match current claude.json (model name, model order, and populated modes) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5c7a0ac761
commit
bdbd1d46a9
2 changed files with 51 additions and 20 deletions
15
docs/cli.mdx
15
docs/cli.mdx
|
|
@ -200,13 +200,22 @@ Example output:
|
|||
"models": {
|
||||
"currentValue": "default",
|
||||
"values": [
|
||||
{ "value": "default", "name": "Default (recommended)" },
|
||||
{ "value": "opus", "name": "Opus" },
|
||||
{ "value": "default", "name": "Default" },
|
||||
{ "value": "sonnet", "name": "Sonnet" },
|
||||
{ "value": "opus", "name": "Opus" },
|
||||
{ "value": "haiku", "name": "Haiku" }
|
||||
]
|
||||
},
|
||||
"modes": { "values": [] },
|
||||
"modes": {
|
||||
"currentValue": "default",
|
||||
"values": [
|
||||
{ "value": "default", "name": "Default" },
|
||||
{ "value": "acceptEdits", "name": "Accept Edits" },
|
||||
{ "value": "plan", "name": "Plan" },
|
||||
{ "value": "dontAsk", "name": "Don't Ask" },
|
||||
{ "value": "bypassPermissions", "name": "Bypass Permissions" }
|
||||
]
|
||||
},
|
||||
"thoughtLevels": { "values": [] }
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -679,14 +679,23 @@ export class SandboxAgent {
|
|||
live.bindSession(record.id, record.agentSessionId);
|
||||
let session = this.upsertSessionHandle(record);
|
||||
|
||||
if (request.mode) {
|
||||
session = (await this.setSessionMode(session.id, request.mode)).session;
|
||||
}
|
||||
if (request.model) {
|
||||
session = (await this.setSessionModel(session.id, request.model)).session;
|
||||
}
|
||||
if (request.thoughtLevel) {
|
||||
session = (await this.setSessionThoughtLevel(session.id, request.thoughtLevel)).session;
|
||||
try {
|
||||
if (request.mode) {
|
||||
session = (await this.setSessionMode(session.id, request.mode)).session;
|
||||
}
|
||||
if (request.model) {
|
||||
session = (await this.setSessionModel(session.id, request.model)).session;
|
||||
}
|
||||
if (request.thoughtLevel) {
|
||||
session = (await this.setSessionThoughtLevel(session.id, request.thoughtLevel)).session;
|
||||
}
|
||||
} catch (err) {
|
||||
try {
|
||||
await this.destroySession(session.id);
|
||||
} catch {
|
||||
// Best-effort cleanup
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
return session;
|
||||
|
|
@ -728,14 +737,23 @@ export class SandboxAgent {
|
|||
const existing = await this.persist.getSession(request.id);
|
||||
if (existing) {
|
||||
let session = await this.resumeSession(existing.id);
|
||||
if (request.mode) {
|
||||
session = (await this.setSessionMode(session.id, request.mode)).session;
|
||||
}
|
||||
if (request.model) {
|
||||
session = (await this.setSessionModel(session.id, request.model)).session;
|
||||
}
|
||||
if (request.thoughtLevel) {
|
||||
session = (await this.setSessionThoughtLevel(session.id, request.thoughtLevel)).session;
|
||||
try {
|
||||
if (request.mode) {
|
||||
session = (await this.setSessionMode(session.id, request.mode)).session;
|
||||
}
|
||||
if (request.model) {
|
||||
session = (await this.setSessionModel(session.id, request.model)).session;
|
||||
}
|
||||
if (request.thoughtLevel) {
|
||||
session = (await this.setSessionThoughtLevel(session.id, request.thoughtLevel)).session;
|
||||
}
|
||||
} catch (err) {
|
||||
try {
|
||||
await this.destroySession(session.id);
|
||||
} catch {
|
||||
// Best-effort cleanup
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
|
@ -743,7 +761,11 @@ export class SandboxAgent {
|
|||
}
|
||||
|
||||
async destroySession(id: string): Promise<Session> {
|
||||
await this.sendSessionMethodInternal(id, SESSION_CANCEL_METHOD, {}, {}, true);
|
||||
try {
|
||||
await this.sendSessionMethodInternal(id, SESSION_CANCEL_METHOD, {}, {}, true);
|
||||
} catch {
|
||||
// Best-effort: agent may already be gone
|
||||
}
|
||||
const existing = await this.requireSessionRecord(id);
|
||||
|
||||
const updated: SessionRecord = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue