mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-20 02:03:19 +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": {
|
"models": {
|
||||||
"currentValue": "default",
|
"currentValue": "default",
|
||||||
"values": [
|
"values": [
|
||||||
{ "value": "default", "name": "Default (recommended)" },
|
{ "value": "default", "name": "Default" },
|
||||||
{ "value": "opus", "name": "Opus" },
|
|
||||||
{ "value": "sonnet", "name": "Sonnet" },
|
{ "value": "sonnet", "name": "Sonnet" },
|
||||||
|
{ "value": "opus", "name": "Opus" },
|
||||||
{ "value": "haiku", "name": "Haiku" }
|
{ "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": [] }
|
"thoughtLevels": { "values": [] }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -679,6 +679,7 @@ export class SandboxAgent {
|
||||||
live.bindSession(record.id, record.agentSessionId);
|
live.bindSession(record.id, record.agentSessionId);
|
||||||
let session = this.upsertSessionHandle(record);
|
let session = this.upsertSessionHandle(record);
|
||||||
|
|
||||||
|
try {
|
||||||
if (request.mode) {
|
if (request.mode) {
|
||||||
session = (await this.setSessionMode(session.id, request.mode)).session;
|
session = (await this.setSessionMode(session.id, request.mode)).session;
|
||||||
}
|
}
|
||||||
|
|
@ -688,6 +689,14 @@ export class SandboxAgent {
|
||||||
if (request.thoughtLevel) {
|
if (request.thoughtLevel) {
|
||||||
session = (await this.setSessionThoughtLevel(session.id, request.thoughtLevel)).session;
|
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;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
@ -728,6 +737,7 @@ export class SandboxAgent {
|
||||||
const existing = await this.persist.getSession(request.id);
|
const existing = await this.persist.getSession(request.id);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
let session = await this.resumeSession(existing.id);
|
let session = await this.resumeSession(existing.id);
|
||||||
|
try {
|
||||||
if (request.mode) {
|
if (request.mode) {
|
||||||
session = (await this.setSessionMode(session.id, request.mode)).session;
|
session = (await this.setSessionMode(session.id, request.mode)).session;
|
||||||
}
|
}
|
||||||
|
|
@ -737,13 +747,25 @@ export class SandboxAgent {
|
||||||
if (request.thoughtLevel) {
|
if (request.thoughtLevel) {
|
||||||
session = (await this.setSessionThoughtLevel(session.id, request.thoughtLevel)).session;
|
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;
|
return session;
|
||||||
}
|
}
|
||||||
return this.createSession(request);
|
return this.createSession(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
async destroySession(id: string): Promise<Session> {
|
async destroySession(id: string): Promise<Session> {
|
||||||
|
try {
|
||||||
await this.sendSessionMethodInternal(id, SESSION_CANCEL_METHOD, {}, {}, true);
|
await this.sendSessionMethodInternal(id, SESSION_CANCEL_METHOD, {}, {}, true);
|
||||||
|
} catch {
|
||||||
|
// Best-effort: agent may already be gone
|
||||||
|
}
|
||||||
const existing = await this.requireSessionRecord(id);
|
const existing = await this.requireSessionRecord(id);
|
||||||
|
|
||||||
const updated: SessionRecord = {
|
const updated: SessionRecord = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue