| 357 | } |
| 358 | |
| 359 | func (rt *AgentTaskRuntime) StopTask(taskID, scopeID string) any { |
| 360 | rt.mu.Lock() |
| 361 | defer rt.mu.Unlock() |
| 362 | record := rt.getTaskLocked(taskID, scopeID, scopeID != "") |
| 363 | if record == nil { |
| 364 | return "Error: Task not found." |
| 365 | } |
| 366 | if _, terminal := terminalTaskStatuses[record.Status]; terminal { |
| 367 | cp := *record |
| 368 | return &cp |
| 369 | } |
| 370 | rt.cancelIdleTTLLocked(taskID) |
| 371 | summary := "Worker was stopped after its live session disappeared." |
| 372 | resultText := firstNonEmptyString(record.ResultText, record.ErrorText) |
| 373 | switch record.Status { |
| 374 | case "queued": |
| 375 | summary = "Queued worker was stopped." |
| 376 | resultText = "" |
| 377 | case "idle": |
| 378 | summary = "Idle worker was stopped." |
| 379 | resultText = record.ResultText |
| 380 | case "running": |
| 381 | summary = "Running worker was stopped." |
| 382 | resultText = firstNonEmptyString(record.ResultText, record.ErrorText) |
| 383 | } |
| 384 | if cancel := rt.workers[taskID]; cancel != nil { |
| 385 | cancel() |
| 386 | } |
| 387 | record.Status = "killed" |
| 388 | record.TerminationReason = "stopped" |
| 389 | record.UpdatedAt = nowSeconds() |
| 390 | rt.enqueueLocked(record, summary, resultText) |
| 391 | delete(rt.workerSpecs, taskID) |
| 392 | rt.scheduleTerminalRecordCleanupLocked(taskID) |
| 393 | cp := *record |
| 394 | return &cp |
| 395 | } |
| 396 | |
| 397 | func (rt *AgentTaskRuntime) runWorker(ctx context.Context, taskID, prompt string) { |
| 398 | rt.setStatus(taskID, "running") |