use std::{collections::HashMap, ffi::OsString, path::PathBuf, sync::Arc, time::Duration};
use crate::{
builtin::{chat_attach, chat_history},
delegate::{
adapters::{OutputFormat, Resume, Transport},
background,
conversation::ConversationLimits,
records::DelegationRegistry,
},
};
#[derive(Debug, Clone)]
pub struct ToolsConfig {
pub command_timeout: Duration,
pub agent_timeout: Duration,
pub max_timeout: Duration,
pub output_limit_bytes: usize,
pub max_read_bytes: usize,
pub max_write_bytes: usize,
pub max_delegation_depth: u32,
pub prefer: Vec<String>,
pub conversations: ConversationLimits,
pub delegation: Option<DelegationContext>,
pub max_background: usize,
pub background: Option<Arc<background::BackgroundJobs>>,
pub chat_attach: Option<chat_attach::ChatAttachConfig>,
pub chat_history: Option<chat_history::ChatHistoryConfig>,
pub precheck_agent_models: bool,
}
impl Default for ToolsConfig {
fn default() -> Self {
Self {
command_timeout: Duration::from_secs(600),
agent_timeout: Duration::from_secs(3600),
max_timeout: Duration::from_secs(14400),
output_limit_bytes: 64 * 1024,
max_read_bytes: 256 * 1024,
max_write_bytes: 1024 * 1024,
max_delegation_depth: 2,
prefer: Vec::new(),
conversations: ConversationLimits {
max: 8,
idle: Duration::from_secs(86400),
},
delegation: None,
max_background: 2,
background: None,
chat_attach: None,
chat_history: None,
precheck_agent_models: true,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum BusyBehavior {
#[default]
Queue,
Wait,
Steer,
Fail,
}
impl BusyBehavior {
pub(crate) fn parse(value: &str) -> Result<Self, String> {
match value {
"queue" => Ok(Self::Queue),
"wait" => Ok(Self::Wait),
"steer" => Ok(Self::Steer),
"fail" => Ok(Self::Fail),
other => Err(format!(
"invalid busy behavior {other:?}; use queue, wait, steer, or fail"
)),
}
}
}
impl<'de> serde::Deserialize<'de> for BusyBehavior {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
Self::parse(&String::deserialize(d)?).map_err(serde::de::Error::custom)
}
}
impl serde::Serialize for BusyBehavior {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.serialize_str(match self {
Self::Queue => "queue",
Self::Wait => "wait",
Self::Steer => "steer",
Self::Fail => "fail",
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BusyConfig {
pub behavior: BusyBehavior,
pub steer_fallback: BusyBehavior,
pub max_queued_turns: usize,
}
impl BusyConfig {
pub(crate) fn fallback(self) -> BusyBehavior {
match self.steer_fallback {
BusyBehavior::Steer => BusyBehavior::Queue,
other => other,
}
}
}
impl Default for BusyConfig {
fn default() -> Self {
Self {
behavior: BusyBehavior::Queue,
steer_fallback: BusyBehavior::Queue,
max_queued_turns: 4,
}
}
}
#[derive(Debug, Clone)]
pub struct DelegationContext {
pub registry: Arc<DelegationRegistry>,
pub session: String,
pub depth: u32,
}
impl DelegationContext {
pub(crate) fn owner_depth(&self) -> u32 {
self.registry.depth().max(self.depth)
}
}
#[derive(Debug, Clone)]
pub struct AgentAdapterConfig {
pub command: String,
pub args: Vec<String>,
pub prompt_args: Vec<String>,
pub full_permission_args: Option<Vec<String>>,
pub model_args: Vec<String>,
pub effort_args: Vec<String>,
pub model_hint: String,
pub environment: Vec<(OsString, OsString)>,
pub search_dirs: Vec<PathBuf>,
pub output: OutputFormat,
pub resume: Resume,
pub home: Option<PathBuf>,
pub transport: Transport,
pub acp: Option<AcpAgentLaunch>,
pub use_for: Option<String>,
pub defaults: AgentDefaults,
pub options_file: Option<PathBuf>,
pub busy: BusyConfig,
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct AgentDefaults {
pub model: Option<String>,
pub effort: Option<String>,
pub hard_task_effort: Option<String>,
}
#[derive(Debug, Clone)]
pub struct AcpAgentLaunch {
pub command: String,
pub args: Vec<String>,
pub full_mode: Option<String>,
pub environment: Vec<(OsString, OsString)>,
pub required: bool,
pub session_options: bool,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Skill {
File(PathBuf),
Builtin(&'static str),
}
pub type SkillMap = HashMap<String, Skill>;