#![allow(dead_code)]
use std::collections::HashMap;
use std::sync::Arc;
use crate::tasks::guards::{LocalShellTaskState, is_local_shell_task_from_value};
use crate::types::ids::AgentId;
type SetAppStateFn = Box<dyn Fn(Box<dyn Fn(&serde_json::Value) -> serde_json::Value>)>;
type GetAppStateFn = Box<dyn Fn() -> serde_json::Value>;
pub fn kill_task(task_id: &str, set_app_state: &SetAppStateFn) {
let task_id_owned = task_id.to_string();
set_app_state(Box::new(move |prev: &serde_json::Value| {
let mut prev = prev.clone();
let tasks = prev.get("tasks").and_then(|t| t.as_object());
if tasks.is_none() {
return prev;
}
let tasks = tasks.unwrap();
let task = tasks.get(task_id_owned.as_str());
if task.is_none() {
return prev;
}
let task = task.unwrap();
if !is_local_shell_task_from_value(task) {
return prev;
}
let status = task.get("status").and_then(|s| s.as_str()).unwrap_or("");
if status != "running" {
return prev;
}
log_for_debugging(&format!("LocalShellTask {} kill requested", task_id_owned));
if let Some(shell_cmd) = task.get("shellCommand") {
if !shell_cmd.is_null() {
}
}
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_millis() as u64)
.unwrap_or(0);
let mut updated_task = task.clone();
if let Some(obj) = updated_task.as_object_mut() {
obj.insert("status".to_string(), serde_json::json!("killed"));
obj.insert("notified".to_string(), serde_json::json!(true));
obj.insert("shellCommand".to_string(), serde_json::json!(null));
obj.insert("endTime".to_string(), serde_json::json!(now));
}
let mut new_tasks = tasks.clone();
new_tasks.insert(task_id_owned.clone(), updated_task);
if let Some(obj) = prev.as_object_mut() {
obj.insert("tasks".to_string(), serde_json::json!(new_tasks));
}
prev
}));
let task_id = task_id.to_string();
tokio::spawn(async move {
let _ = evict_task_output(&task_id).await;
});
}
pub fn kill_shell_tasks_for_agent(
agent_id: &AgentId,
get_app_state: &GetAppStateFn,
set_app_state: &SetAppStateFn,
) {
let app_state = get_app_state();
let tasks = app_state.get("tasks").and_then(|t| t.as_object());
if let Some(tasks) = tasks {
for (task_id, task) in tasks {
if is_local_shell_task_from_value(task) {
let task_agent_id = task
.get("agentId")
.and_then(|v| v.as_str())
.map(|s| s.to_string());
let status = task.get("status").and_then(|s| s.as_str()).unwrap_or("");
if task_agent_id.as_deref() == Some(agent_id.as_str()) && status == "running" {
log_for_debugging(&format!(
"kill_shell_tasks_for_agent: killing orphaned shell task {} (agent {} exiting)",
task_id, agent_id
));
kill_task(task_id, set_app_state);
}
}
}
}
dequeue_all_matching(|cmd: &serde_json::Value| {
cmd.get("agentId")
.and_then(|v| v.as_str())
.map(|s| s == agent_id.as_str())
.unwrap_or(false)
});
}
fn log_for_debugging(msg: &str) {
eprintln!("[DEBUG] {}", msg);
}
async fn evict_task_output(_task_id: &str) -> std::io::Result<()> {
Ok(())
}
fn dequeue_all_matching<F>(_filter: F)
where
F: Fn(&serde_json::Value) -> bool,
{
}