use serde_json::Value;
use crate::core::providers::unified_provider::ProviderError;
use crate::core::types::thinking::{
ThinkingCapabilities, ThinkingConfig, ThinkingContent, ThinkingEffort, ThinkingUsage,
};
pub trait ThinkingProvider {
fn supports_thinking(&self, model: &str) -> bool;
fn thinking_capabilities(&self, model: &str) -> ThinkingCapabilities;
fn transform_thinking_config(
&self,
config: &ThinkingConfig,
model: &str,
) -> Result<Value, ProviderError>;
fn extract_thinking(&self, response: &Value) -> Option<ThinkingContent>;
fn extract_thinking_usage(&self, response: &Value) -> Option<ThinkingUsage>;
fn default_thinking_effort(&self) -> ThinkingEffort {
ThinkingEffort::Medium
}
fn max_thinking_tokens(&self, model: &str) -> Option<u32> {
self.thinking_capabilities(model).max_thinking_tokens
}
fn supports_streaming_thinking(&self, model: &str) -> bool {
self.thinking_capabilities(model)
.supports_streaming_thinking
}
}
pub struct NoThinkingSupport;
impl ThinkingProvider for NoThinkingSupport {
fn supports_thinking(&self, _model: &str) -> bool {
false
}
fn thinking_capabilities(&self, _model: &str) -> ThinkingCapabilities {
ThinkingCapabilities::unsupported()
}
fn transform_thinking_config(
&self,
_config: &ThinkingConfig,
_model: &str,
) -> Result<Value, ProviderError> {
Ok(Value::Object(serde_json::Map::new()))
}
fn extract_thinking(&self, _response: &Value) -> Option<ThinkingContent> {
None
}
fn extract_thinking_usage(&self, _response: &Value) -> Option<ThinkingUsage> {
None
}
}