Files
nanoclaw/container/agent-runner/src/db/session-state.ts
gavrielc b59216c299 fix(v2): persist SDK session ID across container restarts
The v2 poll loop held the session ID in a local variable, so every
container restart started a fresh SDK session even though the .jsonl
transcript was still sitting in the shared .claude mount. Store it in
outbound.db (container-owned, already per channel/thread), seed the
loop on startup, clear on /clear, and recover from stale-session
errors the same way v1 did.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 01:17:42 +03:00

42 lines
1.2 KiB
TypeScript

/**
* Persistent key/value state for the container. Lives in outbound.db
* (container-owned, already scoped per channel/thread).
*
* Primary use: remember the SDK session ID so the agent's conversation
* resumes across container restarts. Cleared by /clear.
*/
import { getOutboundDb } from './connection.js';
const SDK_SESSION_KEY = 'sdk_session_id';
function getValue(key: string): string | undefined {
const row = getOutboundDb()
.prepare('SELECT value FROM session_state WHERE key = ?')
.get(key) as { value: string } | undefined;
return row?.value;
}
function setValue(key: string, value: string): void {
getOutboundDb()
.prepare(
'INSERT OR REPLACE INTO session_state (key, value, updated_at) VALUES (?, ?, ?)',
)
.run(key, value, new Date().toISOString());
}
function deleteValue(key: string): void {
getOutboundDb().prepare('DELETE FROM session_state WHERE key = ?').run(key);
}
export function getStoredSessionId(): string | undefined {
return getValue(SDK_SESSION_KEY);
}
export function setStoredSessionId(sessionId: string): void {
setValue(SDK_SESSION_KEY, sessionId);
}
export function clearStoredSessionId(): void {
deleteValue(SDK_SESSION_KEY);
}