use crate::agent::InlineAgentBaseWithFallbacksOrRemoteCommitOptional;
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
#[serde(tag = "by", rename_all = "snake_case")]
#[schemars(rename = "cli.command.agents.AgentSelector")]
pub enum AgentSelector {
#[schemars(title = "Ref")]
Ref { agent: AgentRef },
#[schemars(title = "Tag")]
Tag { agent_tag: String },
#[schemars(title = "Instance")]
Instance {
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(extend("omitempty" = true))]
parent_agent_instance_hierarchy: Option<String>,
agent_instance: String,
},
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
#[schemars(rename = "cli.command.agents.AgentRef")]
pub enum AgentRef {
#[schemars(title = "Resolved")]
Resolved(InlineAgentBaseWithFallbacksOrRemoteCommitOptional),
#[schemars(title = "File")]
File(std::path::PathBuf),
#[schemars(title = "PythonInline")]
PythonInline(String),
#[schemars(title = "PythonFile")]
PythonFile(std::path::PathBuf),
}
impl AgentSelector {
pub fn push_flags(&self, out: &mut Vec<String>) {
match self {
AgentSelector::Ref { agent } => match agent {
AgentRef::Resolved(spec) => {
out.push("--agent-inline".to_string());
out.push(
serde_json::to_string(spec)
.expect("agent spec serializes"),
);
}
AgentRef::File(p) => {
out.push("--agent-file".to_string());
out.push(p.to_string_lossy().into_owned());
}
AgentRef::PythonInline(code) => {
out.push("--agent-python-inline".to_string());
out.push(code.clone());
}
AgentRef::PythonFile(p) => {
out.push("--agent-python-file".to_string());
out.push(p.to_string_lossy().into_owned());
}
},
AgentSelector::Tag { agent_tag } => {
out.push("--agent-tag".to_string());
out.push(agent_tag.clone());
}
AgentSelector::Instance {
parent_agent_instance_hierarchy,
agent_instance,
} => {
out.push("--agent-instance".to_string());
out.push(agent_instance.clone());
if let Some(parent) = parent_agent_instance_hierarchy {
out.push("--parent-agent-instance-hierarchy".to_string());
out.push(parent.clone());
}
}
}
}
}
#[derive(clap::Args)]
#[command(group(
clap::ArgGroup::new("agent_selector")
.required(true)
.multiple(false)
.args([
"agent",
"agent_inline",
"agent_file",
"agent_python_inline",
"agent_python_file",
"agent_tag",
"agent_instance",
])
))]
pub struct AgentSelectorArgs {
#[arg(long)]
pub agent: Option<String>,
#[arg(long)]
pub agent_inline: Option<String>,
#[arg(long)]
pub agent_file: Option<std::path::PathBuf>,
#[arg(long)]
pub agent_python_inline: Option<String>,
#[arg(long)]
pub agent_python_file: Option<std::path::PathBuf>,
#[arg(long)]
pub agent_tag: Option<String>,
#[arg(long)]
pub agent_instance: Option<String>,
#[arg(long, requires = "agent_instance")]
pub parent_agent_instance_hierarchy: Option<String>,
}
impl TryFrom<AgentSelectorArgs> for AgentSelector {
type Error = crate::cli::command::FromArgsError;
fn try_from(args: AgentSelectorArgs) -> Result<Self, Self::Error> {
if let Some(s) = args.agent_inline {
let mut de = serde_json::Deserializer::from_str(&s);
let spec: InlineAgentBaseWithFallbacksOrRemoteCommitOptional =
serde_path_to_error::deserialize(&mut de).map_err(|source| {
crate::cli::command::FromArgsError {
field: "agent_inline",
source: source.into(),
}
})?;
Ok(AgentSelector::Ref {
agent: AgentRef::Resolved(spec),
})
} else if let Some(s) = args.agent {
let path: crate::RemotePathCommitOptional = s
.parse()
.map_err(|e| crate::cli::command::FromArgsError::path_parse("agent", e))?;
Ok(AgentSelector::Ref {
agent: AgentRef::Resolved(
InlineAgentBaseWithFallbacksOrRemoteCommitOptional::Remote(path),
),
})
} else if let Some(p) = args.agent_file {
Ok(AgentSelector::Ref {
agent: AgentRef::File(p),
})
} else if let Some(code) = args.agent_python_inline {
Ok(AgentSelector::Ref {
agent: AgentRef::PythonInline(code),
})
} else if let Some(p) = args.agent_python_file {
Ok(AgentSelector::Ref {
agent: AgentRef::PythonFile(p),
})
} else if let Some(agent_tag) = args.agent_tag {
Ok(AgentSelector::Tag { agent_tag })
} else {
Ok(AgentSelector::Instance {
parent_agent_instance_hierarchy: args.parent_agent_instance_hierarchy,
agent_instance: args.agent_instance.unwrap(),
})
}
}
}