#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct PersistedPrimaryAgentResolution {
pub(crate) selected_id: Option<String>,
pub(crate) diagnostics: Vec<crate::primary_agents::PrimaryAgentProfileDiagnostic>,
}
pub(crate) fn resolve_persisted_primary_agent_selection(
selected_id: Option<&str>,
profiles: &std::collections::BTreeMap<String, crate::primary_agents::PrimaryAgentProfile>,
) -> PersistedPrimaryAgentResolution {
let Some(selected_id) = selected_id else {
return PersistedPrimaryAgentResolution {
selected_id: None,
diagnostics: Vec::new(),
};
};
match crate::primary_agents::validate_primary_agent_id(selected_id) {
Ok(id) if profiles.contains_key(&id) => PersistedPrimaryAgentResolution {
selected_id: Some(id),
diagnostics: Vec::new(),
},
Ok(id) => PersistedPrimaryAgentResolution {
selected_id: None,
diagnostics: vec![crate::primary_agents::PrimaryAgentProfileDiagnostic {
id: Some(id),
path: None,
message: "stored primary agent selection is unavailable; using None".to_string(),
}],
},
Err(error) => PersistedPrimaryAgentResolution {
selected_id: None,
diagnostics: vec![crate::primary_agents::PrimaryAgentProfileDiagnostic {
id: Some(sanitized_primary_agent_diagnostic_text(selected_id)),
path: None,
message: format!("stored primary agent selection is invalid; using None: {error}"),
}],
},
}
}
pub(crate) fn sanitized_primary_agent_diagnostic_text(text: &str) -> String {
let one_line = text.split_whitespace().collect::<Vec<_>>().join(" ");
let lower = one_line.to_ascii_lowercase();
let looks_secret = lower.contains("secret")
|| lower.contains("token")
|| lower.contains("password")
|| lower.contains("apikey")
|| lower.contains("api_key")
|| lower.contains("openai")
|| one_line.starts_with("sk-");
if looks_secret {
"<redacted>".to_string()
} else if one_line.chars().count() > 160 {
format!("{}…", one_line.chars().take(160).collect::<String>())
} else {
one_line
}
}