feat(agents): 3-layer recovery for agents stuck in summoning state

Add ResetStuckSummoning store method (PG + SQLite) + startup sweep to
flip ghost rows to summon_failed on boot. Drop 409 guards on resummon
and regenerate to allow retry. Add POST /v1/agents/{id}/cancel-summon
endpoint + audit event agent.summon_cancelled + i18n (en/vi/zh).
This commit is contained in:
viettranx committed 2026-04-17 19:02:53 +07:00
1 parent 7e2e66c095
commit d7342fbd6e
10 files changed
+91 -8

No files matched your search

+12
View File
@@ -327,3 +327,15 @@ func scanAgentRows(rows *sql.Rows) ([]store.AgentData, error) {
}
return result, rows.Err()
}
// ResetStuckSummoning flips rows with status='summoning' to 'summon_failed'.
// Called at startup to recover from crashes where summon goroutines died mid-flight.
func (s *SQLiteAgentStore) ResetStuckSummoning(ctx context.Context) (int64, error) {
const q = `UPDATE agents SET status = ? WHERE status = ?`
res, err := s.db.ExecContext(ctx, q, store.AgentStatusSummonFailed, store.AgentStatusSummoning)
if err != nil {
return 0, err
}
n, _ := res.RowsAffected()
return n, nil
}