@@ -288,33 +288,43 @@ impl Model {
}
pub fn mode(&self) -> AnthropicModelMode {
- if self.supports_adaptive_thinking() {
- AnthropicModelMode::AdaptiveThinking
- } else if self.supports_thinking() {
- AnthropicModelMode::Thinking {
+ match self {
+ Self::Custom { mode, .. } => mode.clone(),
+ _ if self.supports_adaptive_thinking() => AnthropicModelMode::AdaptiveThinking,
+ _ if self.supports_thinking() => AnthropicModelMode::Thinking {
budget_tokens: Some(4_096),
- }
- } else {
- AnthropicModelMode::Default
+ },
+ _ => AnthropicModelMode::Default,
}
}
pub fn supports_thinking(&self) -> bool {
- matches!(
- self,
- Self::ClaudeOpus4
- | Self::ClaudeOpus4_1
- | Self::ClaudeOpus4_5
- | Self::ClaudeOpus4_6
- | Self::ClaudeSonnet4
- | Self::ClaudeSonnet4_5
- | Self::ClaudeSonnet4_6
- | Self::ClaudeHaiku4_5
- )
+ match self {
+ Self::Custom { mode, .. } => {
+ matches!(
+ mode,
+ AnthropicModelMode::Thinking { .. } | AnthropicModelMode::AdaptiveThinking
+ )
+ }
+ _ => matches!(
+ self,
+ Self::ClaudeOpus4
+ | Self::ClaudeOpus4_1
+ | Self::ClaudeOpus4_5
+ | Self::ClaudeOpus4_6
+ | Self::ClaudeSonnet4
+ | Self::ClaudeSonnet4_5
+ | Self::ClaudeSonnet4_6
+ | Self::ClaudeHaiku4_5
+ ),
+ }
}
pub fn supports_adaptive_thinking(&self) -> bool {
- matches!(self, Self::ClaudeOpus4_6 | Self::ClaudeSonnet4_6)
+ match self {
+ Self::Custom { mode, .. } => matches!(mode, AnthropicModelMode::AdaptiveThinking),
+ _ => matches!(self, Self::ClaudeOpus4_6 | Self::ClaudeSonnet4_6),
+ }
}
pub fn beta_headers(&self) -> Option<String> {
@@ -1110,6 +1120,65 @@ impl From<ApiError> for language_model_core::LanguageModelCompletionError {
}
}
+#[test]
+fn custom_mode_thinking_is_preserved() {
+ let model = Model::Custom {
+ name: "my-custom-model".to_string(),
+ max_tokens: 8192,
+ display_name: None,
+ tool_override: None,
+ cache_configuration: None,
+ max_output_tokens: None,
+ default_temperature: None,
+ extra_beta_headers: vec![],
+ mode: AnthropicModelMode::Thinking {
+ budget_tokens: Some(2048),
+ },
+ };
+ assert_eq!(
+ model.mode(),
+ AnthropicModelMode::Thinking {
+ budget_tokens: Some(2048)
+ }
+ );
+ assert!(model.supports_thinking());
+}
+
+#[test]
+fn custom_mode_adaptive_is_preserved() {
+ let model = Model::Custom {
+ name: "my-custom-model".to_string(),
+ max_tokens: 8192,
+ display_name: None,
+ tool_override: None,
+ cache_configuration: None,
+ max_output_tokens: None,
+ default_temperature: None,
+ extra_beta_headers: vec![],
+ mode: AnthropicModelMode::AdaptiveThinking,
+ };
+ assert_eq!(model.mode(), AnthropicModelMode::AdaptiveThinking);
+ assert!(model.supports_adaptive_thinking());
+ assert!(model.supports_thinking());
+}
+
+#[test]
+fn custom_mode_default_disables_thinking() {
+ let model = Model::Custom {
+ name: "my-custom-model".to_string(),
+ max_tokens: 8192,
+ display_name: None,
+ tool_override: None,
+ cache_configuration: None,
+ max_output_tokens: None,
+ default_temperature: None,
+ extra_beta_headers: vec![],
+ mode: AnthropicModelMode::Default,
+ };
+ assert!(!model.supports_thinking());
+ assert!(!model.supports_adaptive_thinking());
+}
+
#[test]
fn test_match_window_exceeded() {
let error = ApiError {