use super::wire::GeminiThinkingConfig;
use crate::services::ai::ModelLimits;
use crate::wire::canonical::CanonicalRequest;
pub(super) fn thinking_config(
request: &CanonicalRequest,
limits: Option<ModelLimits>,
) -> (Option<GeminiThinkingConfig>, u32) {
let cap = limits.map(|l| l.max_output_tokens);
let text = crate::wire::clamp_output_tokens(request.max_tokens, cap);
let max_budget = limits.and_then(|l| l.max_thinking_budget);
let Some(thinking) = request.thinking else {
return (None, headroom_ceiling(text, cap, max_budget));
};
if !thinking.enabled {
return (None, text);
}
let budget = match (thinking.budget_tokens, max_budget) {
(Some(want), Some(cap)) => Some(want.min(cap)),
(want, _) => want,
};
(Some(config(budget)), text)
}
fn headroom_ceiling(text: u32, cap: Option<u32>, max_budget: Option<u32>) -> u32 {
let ceiling = text.saturating_add(max_budget.unwrap_or(0));
crate::wire::clamp_output_tokens(ceiling, cap)
}
const fn config(thinking_budget: Option<u32>) -> GeminiThinkingConfig {
GeminiThinkingConfig {
thinking_budget,
include_thoughts: Some(true),
}
}