| 173 | } |
| 174 | |
| 175 | func (rt *AgentTaskRuntime) ImportSnapshot(snapshot []map[string]any) { |
| 176 | rt.mu.Lock() |
| 177 | defer rt.mu.Unlock() |
| 178 | rt.cancelAllRecordCleanupLocked() |
| 179 | rt.cancelAllIdleTTLLocked() |
| 180 | rt.records = map[string]*AgentTaskRecord{} |
| 181 | rt.notifications = map[string][]TaskNotification{} |
| 182 | rt.waiters = map[string][]chan struct{}{} |
| 183 | rt.workers = map[string]context.CancelFunc{} |
| 184 | rt.workerSpecs = map[string]workerSpec{} |
| 185 | rt.scopes = map[string]struct{}{"main": {}} |
| 186 | rt.childCounts = map[string]int{} |
| 187 | rt.taskParentScopes = map[string]string{} |
| 188 | rt.expiredTaskParentScopes = map[string]string{} |
| 189 | rt.idleTTLCancels = map[string]context.CancelFunc{} |
| 190 | for _, raw := range snapshot { |
| 191 | record := taskRecordFromMap(raw) |
| 192 | resumedLive := record.Status == "queued" || record.Status == "running" || record.Status == "idle" |
| 193 | if resumedLive { |
| 194 | record.Status = "interrupted" |
| 195 | record.UpdatedAt = nowSeconds() |
| 196 | if record.TerminationReason == "" { |
| 197 | record.TerminationReason = "session_resumed" |
| 198 | } |
| 199 | } |
| 200 | rt.registerRecordLocked(record, false) |
| 201 | if resumedLive { |
| 202 | rt.enqueueLocked(record, "Worker was interrupted when the session resumed.", firstNonEmptyString(record.ErrorText, record.ResultText)) |
| 203 | } |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | func (rt *AgentTaskRuntime) EnsureScope(scopeID string) { |
| 208 | if scopeID == "" { |