use super::input::Envelope;
use super::types::{AppliedCaps, SystemPolicy};
#[derive(Debug, Clone)]
pub struct ConfigDefaults {
pub model: String,
pub provider: String,
pub max_tool_calls: Option<u32>,
pub consult: Option<bool>,
pub system: String,
}
#[derive(Debug, Clone, Default)]
pub struct CliOverrides {
pub model: Option<String>,
pub provider: Option<String>,
pub max_tool_calls: Option<u32>,
pub consult: Option<bool>,
}
#[derive(Debug, Clone)]
pub struct Resolved {
pub model: String,
pub provider: String,
pub system: SystemPolicy,
pub max_tool_calls: u32,
pub consult: Option<bool>,
pub applied_caps: AppliedCaps,
}
pub fn resolve(
env: Envelope,
defaults: &ConfigDefaults,
overrides: &CliOverrides,
operator_ceiling: u32,
allow_system_override: bool,
) -> Resolved {
let model = overrides
.model
.clone()
.or(env.model)
.unwrap_or_else(|| defaults.model.clone());
let provider = overrides
.provider
.clone()
.or(env.provider)
.unwrap_or_else(|| defaults.provider.clone());
let consult = overrides.consult.or(env.consult).or(defaults.consult);
let requested_max = overrides
.max_tool_calls
.or(env.max_tool_calls)
.or(defaults.max_tool_calls);
let (max_tool_calls, max_tool_calls_clamped) = match requested_max {
Some(requested) => (
requested.min(operator_ceiling),
requested > operator_ceiling,
),
None => (operator_ceiling, false),
};
let (system, system_override_applied) = match (allow_system_override, env.system) {
(true, Some(caller)) => (SystemPolicy::CallerOverride(caller), true),
_ => (SystemPolicy::Operator(defaults.system.clone()), false),
};
Resolved {
model,
provider,
system,
max_tool_calls,
consult,
applied_caps: AppliedCaps {
max_tool_calls,
max_tool_calls_clamped,
timeout_secs: None,
system_override_applied,
},
}
}
#[cfg(test)]
mod tests {
use super::*;
fn base_env() -> Envelope {
Envelope {
prompt: "p".to_string(),
system: None,
model: None,
provider: None,
max_tool_calls: None,
consult: None,
}
}
fn base_defaults() -> ConfigDefaults {
ConfigDefaults {
model: "def-model".to_string(),
provider: "def-provider".to_string(),
max_tool_calls: None,
consult: None,
system: "operator-system".to_string(),
}
}
#[test]
fn test_envelope_max_tool_calls_clamped_to_operator_ceiling() {
let mut env = base_env();
env.max_tool_calls = Some(999);
let r = resolve(env, &base_defaults(), &CliOverrides::default(), 15, false);
assert_eq!(r.max_tool_calls, 15);
assert!(r.applied_caps.max_tool_calls_clamped);
assert_eq!(r.applied_caps.max_tool_calls, 15);
}
#[test]
fn test_cli_flag_wins_over_envelope() {
let mut env = base_env();
env.model = Some("A".to_string());
env.provider = Some("prov-env".to_string());
env.consult = Some(false);
let overrides = CliOverrides {
model: Some("B".to_string()),
provider: Some("prov-flag".to_string()),
consult: Some(true),
..CliOverrides::default()
};
let r = resolve(env, &base_defaults(), &overrides, 15, false);
assert_eq!(r.model, "B");
assert_eq!(r.provider, "prov-flag");
assert_eq!(r.consult, Some(true));
}
#[test]
fn test_precedence_envelope_over_defaults_and_fallthrough() {
let r = resolve(
base_env(),
&base_defaults(),
&CliOverrides::default(),
15,
false,
);
assert_eq!(r.model, "def-model");
assert_eq!(r.provider, "def-provider");
assert_eq!(r.consult, None);
let mut env = base_env();
env.model = Some("env-model".to_string());
let r2 = resolve(env, &base_defaults(), &CliOverrides::default(), 15, false);
assert_eq!(r2.model, "env-model");
}
#[test]
fn test_envelope_system_ignored_without_override_flag() {
let mut env = base_env();
env.system = Some("caller-sys".to_string());
let r = resolve(env, &base_defaults(), &CliOverrides::default(), 15, false);
assert!(matches!(r.system, SystemPolicy::Operator(ref s) if s == "operator-system"));
assert!(!r.applied_caps.system_override_applied);
}
#[test]
fn test_envelope_system_honored_with_override_flag() {
let mut env = base_env();
env.system = Some("caller-sys".to_string());
let r = resolve(env, &base_defaults(), &CliOverrides::default(), 15, true);
assert!(matches!(r.system, SystemPolicy::CallerOverride(ref s) if s == "caller-sys"));
assert!(r.applied_caps.system_override_applied);
}
#[test]
fn test_override_flag_without_envelope_system_uses_operator() {
let r = resolve(
base_env(),
&base_defaults(),
&CliOverrides::default(),
15,
true,
);
assert!(matches!(r.system, SystemPolicy::Operator(ref s) if s == "operator-system"));
assert!(!r.applied_caps.system_override_applied);
}
#[test]
fn test_envelope_max_tool_calls_below_ceiling_not_clamped() {
let mut env = base_env();
env.max_tool_calls = Some(5);
let r = resolve(env, &base_defaults(), &CliOverrides::default(), 15, false);
assert_eq!(r.max_tool_calls, 5);
assert!(!r.applied_caps.max_tool_calls_clamped);
}
#[test]
fn test_max_tool_calls_falls_through_to_operator_ceiling() {
let r = resolve(
base_env(),
&base_defaults(),
&CliOverrides::default(),
15,
false,
);
assert_eq!(r.max_tool_calls, 15);
assert!(!r.applied_caps.max_tool_calls_clamped);
assert_eq!(r.applied_caps.timeout_secs, None);
}
#[test]
fn test_max_tool_calls_equal_to_ceiling_not_clamped() {
let mut env = base_env();
env.max_tool_calls = Some(15);
let r = resolve(env, &base_defaults(), &CliOverrides::default(), 15, false);
assert_eq!(r.max_tool_calls, 15);
assert!(!r.applied_caps.max_tool_calls_clamped);
}
}