use super::{provider, runtime::effective_ai};
use crate::config::runtime::RuntimeConfig;
use crate::connection::ConnectionRegistry;
use saya_agent::ChatProvider;
use saya_config::ResolvedAi;
pub(crate) use super::runtime::AgentRuntimeError;
pub(crate) struct TurnInputs {
pub(crate) ai: ResolvedAi,
pub(crate) provider: Box<dyn ChatProvider>,
pub(crate) registry: ConnectionRegistry,
pub(crate) failures: Vec<(String, String)>,
}
pub(crate) async fn prepare_turn(
runtime: &RuntimeConfig,
overrides: &super::runtime::PromptOverrides,
can_prompt: bool,
) -> Result<TurnInputs, AgentRuntimeError> {
let ai = effective_ai(&runtime.resolved.ai, overrides);
let provider = provider::build(&ai, &runtime.secret_resolver())
.map_err(|error| AgentRuntimeError::Provider(error.to_string()))?;
let (profile_name, profile) = super::profile::selected(runtime, overrides.profile.as_ref())?;
let mut secondaries = Vec::new();
let mut seen = std::collections::HashSet::new();
for name in &overrides.included_profiles {
if name.is_empty() {
continue;
}
if profile_name.as_deref() == Some(name.as_str()) {
continue;
}
if !seen.insert(name) {
continue;
}
if let Ok(sec_profile) = runtime.named_profile(name) {
secondaries.push((name.clone(), sec_profile.clone()));
}
}
let (registry, failures) = match profile.as_ref() {
Some(primary_profile) => {
let primary_name = profile_name.as_deref().unwrap_or("");
crate::connection::build_registry(
&runtime.secret_resolver(),
&runtime.cache_scope,
runtime.resolved.query_timeout_seconds,
can_prompt,
primary_name,
primary_profile,
&secondaries,
)
.await?
}
None => (crate::connection::ConnectionRegistry::new(""), Vec::new()),
};
Ok(TurnInputs {
ai,
provider,
registry,
failures,
})
}