use crate::Provider;
use crate::model_profile::catalog::ModelTier;
#[derive(Debug, Clone, Copy)]
pub struct ModelCapabilities {
pub id: &'static str,
pub provider: Provider,
pub display_name: &'static str,
pub tier: ModelTier,
pub model_family: &'static str,
pub context_window: u32,
pub max_output_tokens: u32,
pub context_window_beta: Option<BetaValue<u32>>,
pub max_output_tokens_beta: Option<BetaValue<u32>>,
pub vision: bool,
pub image_tool_results: bool,
pub inline_video: bool,
pub realtime: bool,
pub realtime_supports_provider_managed_turns: bool,
pub realtime_supports_explicit_commit: bool,
pub realtime_interrupt_supported: bool,
pub realtime_transcript_supported: bool,
pub transcription_companion_model: Option<&'static str>,
pub image_generation: bool,
pub supports_temperature: bool,
pub supports_top_p: bool,
pub supports_top_k: bool,
pub thinking: ThinkingSupport,
pub supports_reasoning: bool,
pub effort_levels: &'static [EffortLevel],
pub supports_web_search: bool,
pub supports_inference_geo: bool,
pub supports_compaction: bool,
pub supports_structured_output: bool,
pub supports_legacy_penalties: bool,
pub supports_thinking_budget_legacy: bool,
pub beta_headers: &'static [BetaHeader],
pub call_timeout_secs: Option<u64>,
}
#[derive(Debug, Clone, Copy)]
pub struct BetaValue<T: 'static> {
pub header: &'static str,
pub value: T,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BetaFeature {
Compaction,
StructuredOutput,
InterleavedThinking,
}
impl BetaFeature {
pub const fn as_wire_str(self) -> &'static str {
match self {
BetaFeature::Compaction => "compaction",
BetaFeature::StructuredOutput => "structured_output",
BetaFeature::InterleavedThinking => "interleaved_thinking",
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct BetaHeader {
pub feature: BetaFeature,
pub header_name: &'static str,
pub header_value: &'static str,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ThinkingSupport {
None,
AnthropicEnabledOnly,
AnthropicAdaptiveOnly,
AnthropicAdaptiveAndEnabled,
GeminiThinkingLevel,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum EffortLevel {
None,
Minimal,
Low,
Medium,
High,
Xhigh,
Max,
}
impl EffortLevel {
pub const fn as_wire_str(self) -> &'static str {
match self {
EffortLevel::None => "none",
EffortLevel::Minimal => "minimal",
EffortLevel::Low => "low",
EffortLevel::Medium => "medium",
EffortLevel::High => "high",
EffortLevel::Xhigh => "xhigh",
EffortLevel::Max => "max",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn beta_feature_wire_labels_are_pinned_projections() {
assert_eq!(BetaFeature::Compaction.as_wire_str(), "compaction");
assert_eq!(
BetaFeature::StructuredOutput.as_wire_str(),
"structured_output"
);
assert_eq!(
BetaFeature::InterleavedThinking.as_wire_str(),
"interleaved_thinking"
);
}
#[test]
fn effort_level_wire_values_are_pinned_projections() {
assert_eq!(EffortLevel::None.as_wire_str(), "none");
assert_eq!(EffortLevel::Minimal.as_wire_str(), "minimal");
assert_eq!(EffortLevel::Low.as_wire_str(), "low");
assert_eq!(EffortLevel::Medium.as_wire_str(), "medium");
assert_eq!(EffortLevel::High.as_wire_str(), "high");
assert_eq!(EffortLevel::Xhigh.as_wire_str(), "xhigh");
assert_eq!(EffortLevel::Max.as_wire_str(), "max");
}
}