fn build_ccs_config_from_flags(
alias_config: &CcsAliasConfig,
defaults: &CcsConfig,
cmd: String,
env_vars: HashMap<String, String>,
display_name: String,
) -> AgentConfig {
let output_flag = alias_config
.output_flag
.clone()
.unwrap_or_else(|| defaults.output_flag.clone());
let yolo_flag = alias_config
.yolo_flag
.clone()
.unwrap_or_else(|| defaults.yolo_flag.clone());
let verbose_flag = alias_config
.verbose_flag
.clone()
.unwrap_or_else(|| defaults.verbose_flag.clone());
let print_flag = alias_config.print_flag.clone().unwrap_or_else(|| {
let pf = defaults.print_flag.clone();
if pf.is_empty() {
"--print".to_string()
} else {
pf
}
});
let json_parser = alias_config
.json_parser
.as_deref()
.unwrap_or(&defaults.json_parser);
let can_commit = alias_config.can_commit.unwrap_or(defaults.can_commit);
let streaming_flag = alias_config
.streaming_flag
.clone()
.unwrap_or_else(|| defaults.streaming_flag.clone());
let session_flag = alias_config
.session_flag
.clone()
.unwrap_or_else(|| defaults.session_flag.clone());
AgentConfig {
cmd, output_flag,
yolo_flag,
verbose_flag,
can_commit,
json_parser: JsonParserType::parse(json_parser),
model_flag: alias_config.model_flag.clone(),
print_flag, streaming_flag, session_flag, env_vars, display_name: Some(display_name),
}
}
#[cfg(any(test, feature = "test-utils"))]
#[must_use]
pub fn build_ccs_agent_config(
alias_config: &CcsAliasConfig,
defaults: &CcsConfig,
display_name: String,
alias_name: &str,
) -> AgentConfig {
build_ccs_agent_config_impl(alias_config, defaults, display_name, alias_name, |key| {
crate::agents::runtime::get_env_var(key)
})
}
#[cfg(not(any(test, feature = "test-utils")))]
pub fn build_ccs_agent_config(
alias_config: &CcsAliasConfig,
defaults: &CcsConfig,
display_name: String,
alias_name: &str,
) -> AgentConfig {
build_ccs_agent_config_impl(alias_config, defaults, display_name, alias_name, |key| {
crate::agents::runtime::get_env_var(key)
})
}
#[expect(
clippy::print_stderr,
reason = "user-facing informative messages for CCS configuration"
)]
fn build_ccs_agent_config_impl(
alias_config: &CcsAliasConfig,
defaults: &CcsConfig,
display_name: String,
alias_name: &str,
get_env_var: impl Fn(&str) -> Option<String>,
) -> AgentConfig {
let debug_mode = get_env_var("RALPH_CCS_DEBUG").is_some();
let ((env_vars, env_vars_loaded), profile_used_for_env) = if alias_name.is_empty() {
((HashMap::new(), false), None)
} else if is_glm_alias(alias_name) {
let original_cmd = alias_config.cmd.as_str();
let profile =
ccs_profile_from_command(original_cmd).unwrap_or_else(|| alias_name.to_string());
let result = match load_ccs_env_vars_with_guess(&profile) {
Ok((vars, guessed)) => {
if let Some(guessed) = guessed {
eprintln!("Info: CCS profile '{profile}' not found; using '{guessed}'");
}
let loaded = !vars.is_empty();
(vars, loaded)
}
Err(err) => {
let suggestions = find_ccs_profile_suggestions(&profile);
eprintln!("Warning: failed to load CCS env vars for profile '{profile}': {err}");
if !suggestions.is_empty() {
eprintln!("Tip: available/nearby CCS profiles:");
suggestions.iter().for_each(|s| {
eprintln!(" - {s}");
});
}
(HashMap::new(), false)
}
};
(result, Some(profile))
} else {
((HashMap::new(), false), None)
};
let cmd = resolve_ccs_command(
alias_config,
alias_name,
env_vars_loaded,
profile_used_for_env.as_ref(),
debug_mode,
);
build_ccs_config_from_flags(alias_config, defaults, cmd.command, env_vars, display_name)
}
#[derive(Debug, Clone, Default)]
pub struct CcsAliasResolver {
aliases: HashMap<String, CcsAliasConfig>,
defaults: CcsConfig,
}
impl CcsAliasResolver {
#[must_use]
pub const fn new(aliases: HashMap<String, CcsAliasConfig>, defaults: CcsConfig) -> Self {
Self { aliases, defaults }
}
#[must_use]
pub fn empty() -> Self {
Self::default()
}
#[must_use]
pub fn try_resolve(&self, agent_name: &str) -> Option<AgentConfig> {
let alias = parse_ccs_ref(agent_name)?;
if let Some(config) = resolve_ccs_agent(alias, &self.aliases, &self.defaults) {
return Some(config);
}
let cmd = CcsAliasConfig {
cmd: format!("ccs {alias}"),
..CcsAliasConfig::default()
};
let display_name = format!("ccs-{alias}");
Some(build_ccs_agent_config(
&cmd,
&self.defaults,
display_name,
alias,
))
}
}