v2: fix agent-runner lifecycle and session DB reliability
- Use DELETE journal mode for session DBs instead of WAL. WAL doesn't sync reliably across Docker volume mounts (VirtioFS), causing dropped writes and duplicate deliveries. - Add 20s idle detection to end the query stream. The concurrent poll tracks SDK activity via a new 'activity' provider event. When no SDK events arrive for 20s and no messages are pending, the stream ends and the poll loop continues. - Add touchProcessing heartbeat so the host can distinguish active agents from idle ones by checking status_changed recency. - Catch query errors in the poll loop and write error responses to messages_out instead of crashing the process. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@ let _db: Database.Database | null = null;
|
||||
export function getSessionDb(): Database.Database {
|
||||
if (!_db) {
|
||||
_db = new Database(process.env.SESSION_DB_PATH || SESSION_DB_PATH);
|
||||
_db.pragma('journal_mode = WAL');
|
||||
_db.pragma('journal_mode = DELETE');
|
||||
_db.pragma('foreign_keys = ON');
|
||||
}
|
||||
return _db;
|
||||
|
||||
@@ -47,6 +47,14 @@ export function markCompleted(ids: string[]): void {
|
||||
})();
|
||||
}
|
||||
|
||||
/** Update status_changed on processing messages (heartbeat for host idle detection). */
|
||||
export function touchProcessing(ids: string[]): void {
|
||||
if (ids.length === 0) return;
|
||||
const db = getSessionDb();
|
||||
const stmt = db.prepare("UPDATE messages_in SET status_changed = datetime('now') WHERE id = ? AND status = 'processing'");
|
||||
for (const id of ids) stmt.run(id);
|
||||
}
|
||||
|
||||
/** Mark a single message as failed. */
|
||||
export function markFailed(id: string): void {
|
||||
getSessionDb().prepare("UPDATE messages_in SET status = 'failed', status_changed = datetime('now') WHERE id = ?").run(id);
|
||||
|
||||
Reference in New Issue
Block a user