talon-agent 5.26.6 → 5.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -406,3 +406,57 @@ CREATE TABLE IF NOT EXISTS backup_remotes (
406
406
  error TEXT,
407
407
  PRIMARY KEY (backup_id, target_id)
408
408
  );
409
+
410
+ -- Sub-agents, persisted so a daemon restart does not kill them. One row
411
+ -- per spawn, written at registration and kept current on every lifecycle
412
+ -- change (start, SDK session id, mailbox, report, settle). On boot, every
413
+ -- row still 'queued' or 'running' was interrupted by the restart and is
414
+ -- respawned — resuming its backend session when the backend can. See
415
+ -- resumeAgentsAfterRestart in core/agents/runner.ts.
416
+ CREATE TABLE IF NOT EXISTS agents (
417
+ id TEXT PRIMARY KEY,
418
+ label TEXT NOT NULL,
419
+ brief TEXT NOT NULL,
420
+ -- 'chat' | 'agent'; parent_id is the chat key or the parent agent id.
421
+ parent_kind TEXT NOT NULL,
422
+ parent_id TEXT NOT NULL,
423
+ -- The frontend's numeric chat id (chat parents only) — the dispatcher
424
+ -- needs it to wake the chat with the report.
425
+ parent_numeric INTEGER,
426
+ backend_id TEXT NOT NULL,
427
+ -- The model the run resolved to, and the one the caller asked for (null
428
+ -- = the backend default), so a resume can re-resolve if it vanished.
429
+ model TEXT,
430
+ requested_model TEXT,
431
+ effort TEXT,
432
+ timeout_ms INTEGER,
433
+ depth INTEGER NOT NULL DEFAULT 0,
434
+ cwd TEXT,
435
+ state TEXT NOT NULL,
436
+ created_at INTEGER NOT NULL,
437
+ started_at INTEGER,
438
+ ended_at INTEGER,
439
+ updated_at INTEGER NOT NULL,
440
+ -- Backend conversation handle (Claude SDK session id, Codex thread id),
441
+ -- recorded as soon as the backend reports it.
442
+ session_id TEXT,
443
+ -- Pending check_inbox messages, JSON array of {from,text,at}.
444
+ inbox_json TEXT NOT NULL DEFAULT '[]',
445
+ -- 1 once report_result landed; result_* hold what it said.
446
+ reported INTEGER NOT NULL DEFAULT 0,
447
+ result_summary TEXT,
448
+ result_details TEXT,
449
+ error TEXT,
450
+ -- Wall-clock the agent has already spent in earlier (interrupted) runs,
451
+ -- charged against its timeout when it is resumed.
452
+ elapsed_ms INTEGER NOT NULL DEFAULT 0,
453
+ -- How many times a restart has resumed it (bounded — a run that keeps
454
+ -- dying with the daemon eventually settles as failed).
455
+ resume_count INTEGER NOT NULL DEFAULT 0,
456
+ -- When the last restart interrupted it, if one did.
457
+ interrupted_at INTEGER,
458
+ -- 1 when the spawn asked for the pre-flight lane, so a re-briefed resume
459
+ -- keeps the instruction.
460
+ preflight INTEGER NOT NULL DEFAULT 0
461
+ );
462
+ CREATE INDEX IF NOT EXISTS idx_agents_state ON agents(state, depth, created_at);
@@ -410,7 +410,93 @@ CREATE TABLE IF NOT EXISTS backup_remotes (
410
410
  uploaded_at INTEGER,
411
411
  error TEXT,
412
412
  PRIMARY KEY (backup_id, target_id)
413
- );`;
413
+ );
414
+
415
+ -- Sub-agents, persisted so a daemon restart does not kill them. One row
416
+ -- per spawn, written at registration and kept current on every lifecycle
417
+ -- change (start, SDK session id, mailbox, report, settle). On boot, every
418
+ -- row still 'queued' or 'running' was interrupted by the restart and is
419
+ -- respawned — resuming its backend session when the backend can. See
420
+ -- resumeAgentsAfterRestart in core/agents/runner.ts.
421
+ CREATE TABLE IF NOT EXISTS agents (
422
+ id TEXT PRIMARY KEY,
423
+ label TEXT NOT NULL,
424
+ brief TEXT NOT NULL,
425
+ -- 'chat' | 'agent'; parent_id is the chat key or the parent agent id.
426
+ parent_kind TEXT NOT NULL,
427
+ parent_id TEXT NOT NULL,
428
+ -- The frontend's numeric chat id (chat parents only) — the dispatcher
429
+ -- needs it to wake the chat with the report.
430
+ parent_numeric INTEGER,
431
+ backend_id TEXT NOT NULL,
432
+ -- The model the run resolved to, and the one the caller asked for (null
433
+ -- = the backend default), so a resume can re-resolve if it vanished.
434
+ model TEXT,
435
+ requested_model TEXT,
436
+ effort TEXT,
437
+ timeout_ms INTEGER,
438
+ depth INTEGER NOT NULL DEFAULT 0,
439
+ cwd TEXT,
440
+ state TEXT NOT NULL,
441
+ created_at INTEGER NOT NULL,
442
+ started_at INTEGER,
443
+ ended_at INTEGER,
444
+ updated_at INTEGER NOT NULL,
445
+ -- Backend conversation handle (Claude SDK session id, Codex thread id),
446
+ -- recorded as soon as the backend reports it.
447
+ session_id TEXT,
448
+ -- Pending check_inbox messages, JSON array of {from,text,at}.
449
+ inbox_json TEXT NOT NULL DEFAULT '[]',
450
+ -- 1 once report_result landed; result_* hold what it said.
451
+ reported INTEGER NOT NULL DEFAULT 0,
452
+ result_summary TEXT,
453
+ result_details TEXT,
454
+ error TEXT,
455
+ -- Wall-clock the agent has already spent in earlier (interrupted) runs,
456
+ -- charged against its timeout when it is resumed.
457
+ elapsed_ms INTEGER NOT NULL DEFAULT 0,
458
+ -- How many times a restart has resumed it (bounded — a run that keeps
459
+ -- dying with the daemon eventually settles as failed).
460
+ resume_count INTEGER NOT NULL DEFAULT 0,
461
+ -- When the last restart interrupted it, if one did.
462
+ interrupted_at INTEGER,
463
+ -- 1 when the spawn asked for the pre-flight lane, so a re-briefed resume
464
+ -- keeps the instruction.
465
+ preflight INTEGER NOT NULL DEFAULT 0
466
+ );
467
+ CREATE INDEX IF NOT EXISTS idx_agents_state ON agents(state, depth, created_at);`;
468
+
469
+ export const agentsSql = {
470
+ upsert: `INSERT OR REPLACE INTO agents
471
+ (id, label, brief, parent_kind, parent_id, parent_numeric, backend_id,
472
+ model, requested_model, effort, timeout_ms, depth, cwd, state,
473
+ created_at, started_at, ended_at, updated_at, session_id, inbox_json,
474
+ reported, result_summary, result_details, error, elapsed_ms,
475
+ resume_count, interrupted_at, preflight)
476
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
477
+ get: `SELECT id, label, brief, parent_kind, parent_id, parent_numeric, backend_id,
478
+ model, requested_model, effort, timeout_ms, depth, cwd, state,
479
+ created_at, started_at, ended_at, updated_at, session_id, inbox_json,
480
+ reported, result_summary, result_details, error, elapsed_ms,
481
+ resume_count, interrupted_at, preflight
482
+ FROM agents WHERE id = ?
483
+
484
+ -- Rows a restart interrupted, parents before children (a child can only
485
+ -- be re-attached to a parent that is already back in the registry).`,
486
+ listInterrupted: `SELECT id, label, brief, parent_kind, parent_id, parent_numeric, backend_id,
487
+ model, requested_model, effort, timeout_ms, depth, cwd, state,
488
+ created_at, started_at, ended_at, updated_at, session_id, inbox_json,
489
+ reported, result_summary, result_details, error, elapsed_ms,
490
+ resume_count, interrupted_at, preflight
491
+ FROM agents WHERE state IN ('queued', 'running')
492
+ ORDER BY depth, created_at`,
493
+ remove: `DELETE FROM agents WHERE id = ?
494
+
495
+ -- Retention: settled rows past their window. Live rows are never pruned.`,
496
+ pruneSettled: `DELETE FROM agents
497
+ WHERE state NOT IN ('queued', 'running') AND updated_at < ?`,
498
+ removeAll: `DELETE FROM agents`,
499
+ } as const;
414
500
 
415
501
  export const backupsSql = {
416
502
  upsert: `INSERT OR REPLACE INTO backups