use std::path::PathBuf;
use serde::{Deserialize, Serialize};
pub const MAX_WAIT_SECONDS: u64 = 3_600;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SourceRange {
pub file: PathBuf,
pub start: u64,
pub end: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SubagentToolRequest {
pub request_id: String,
pub created_at_ms: i64,
pub action: SubagentToolAction,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(
tag = "action",
content = "params",
rename_all = "snake_case",
deny_unknown_fields
)]
pub enum SubagentToolAction {
ListProfiles,
Spawn {
task_name: String,
instructions: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
profile_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
model: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
effort: Option<String>,
#[serde(default)]
working_directory: PathBuf,
#[serde(default, skip_serializing_if = "Option::is_none")]
context: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
files: Vec<SourceRange>,
},
ListAgents,
SendInput {
child_session_id: String,
message: String,
},
WaitAgents {
child_session_ids: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
timeout_seconds: Option<u64>,
},
InterruptAgent {
child_session_id: String,
},
CloseAgent {
child_session_id: String,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SubagentToolResult {
pub request_id: String,
pub completed_at_ms: i64,
pub is_error: bool,
pub message: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SubagentRecord {
pub child_session_id: String,
pub parent_session_id: String,
pub task_name: String,
pub profile_id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub effort: Option<String>,
pub working_directory: PathBuf,
pub initial_prompt: String,
pub request_key: String,
pub created_at: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub delivered_turn: Option<u64>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SubagentStatus {
Preparing,
Running,
InputRequired,
Completed,
Failed,
Interrupted,
Stopped,
}
impl SubagentRecord {
#[must_use]
pub fn is_child(&self, session_id: &str) -> bool {
self.child_session_id == session_id
}
}