fix(supervisor): surface finished-but-uncollected tasks in turn-end guardrail
The turn-end guardrail only counted still-running agents, so an agent that finished before the turn ended was invisible: its uncollected result was silently dropped. Jobs were never counted at all. The guardrail now enumerates every registered task (running and finished, agents and jobs) via Supervisor::list_tasks and renders a kind-aware prompt with two sections: still-running tasks to reclaim, and completed-but-uncollected tasks with the exact collect command. At the force-terminate cap, finished-but-uncollected handles are explicitly discarded with a warning naming the lost ids, so the guardrail cannot loop forever on handles nobody will collect.
This commit is contained in:
+24
-1
@@ -101,6 +101,12 @@ pub enum TaskHandle {
|
||||
Job(JobHandle),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum TaskKind {
|
||||
Agent,
|
||||
Job,
|
||||
}
|
||||
|
||||
impl From<AgentHandle> for TaskHandle {
|
||||
fn from(handle: AgentHandle) -> Self {
|
||||
Self::Agent(handle)
|
||||
@@ -236,7 +242,6 @@ impl Supervisor {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn take_job(&mut self, id: &str) -> Option<JobHandle> {
|
||||
if !self.has_job(id) {
|
||||
return None;
|
||||
@@ -269,6 +274,24 @@ impl Supervisor {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn list_tasks(&self) -> Vec<(&str, TaskKind, bool)> {
|
||||
self.handles
|
||||
.values()
|
||||
.map(|handle| match handle {
|
||||
TaskHandle::Agent(agent) => (
|
||||
agent.id.as_str(),
|
||||
TaskKind::Agent,
|
||||
agent.join_handle.is_finished(),
|
||||
),
|
||||
TaskHandle::Job(job) => (
|
||||
job.id.as_str(),
|
||||
TaskKind::Job,
|
||||
job.join_handle.is_finished(),
|
||||
),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn cancel_all(&self) {
|
||||
for handle in self.handles.values() {
|
||||
match handle {
|
||||
|
||||
Reference in New Issue
Block a user