use super::{JsonObject, Knob, ReasoningEfforts, SendReject, ToolResultMedia};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AnthropicThinkingFormat {
Anthropic,
Deepseek,
Adaptive,
Effort,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AnthropicThinkingReplay {
Signed,
Unsigned,
}
pub type AnthropicSamplingParams = SendReject;
pub type AnthropicStructuredOutput = SendReject;
pub type AnthropicParallelToolCalls = SendReject;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AnthropicCacheControl {
Anthropic,
None,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct AnthropicCompat {
pub thinking_format: Option<Knob<AnthropicThinkingFormat>>,
pub thinking_replay: Option<Knob<AnthropicThinkingReplay>>,
pub cache_control: Option<Knob<AnthropicCacheControl>>,
pub structured_output: Option<Knob<AnthropicStructuredOutput>>,
pub parallel_tool_calls: Option<Knob<AnthropicParallelToolCalls>>,
pub sampling_params: Option<Knob<AnthropicSamplingParams>>,
pub tool_result_media: Option<Knob<ToolResultMedia>>,
pub reasoning_efforts: Option<ReasoningEfforts>,
pub model_prefixes: Option<&'static [&'static str]>,
pub extensions: Option<JsonObject>,
}
impl AnthropicCompat {
pub const EMPTY: AnthropicCompat = AnthropicCompat {
thinking_format: None,
thinking_replay: None,
cache_control: None,
structured_output: None,
parallel_tool_calls: None,
sampling_params: None,
tool_result_media: None,
reasoning_efforts: None,
model_prefixes: None,
extensions: None,
};
pub fn preset(name: &str) -> Option<&'static AnthropicCompat> {
super::find(ANTHROPIC_PRESETS, name)
}
pub fn resolve(&self) -> ResolvedAnthropicCompat {
ResolvedAnthropicCompat {
thinking_format: Knob::resolve(
self.thinking_format,
AnthropicThinkingFormat::Anthropic,
),
thinking_replay: Knob::resolve(self.thinking_replay, AnthropicThinkingReplay::Signed),
cache_control: Knob::resolve(self.cache_control, AnthropicCacheControl::Anthropic),
structured_output: Knob::resolve(self.structured_output, SendReject::Send),
parallel_tool_calls: Knob::resolve(self.parallel_tool_calls, SendReject::Send),
sampling_params: Knob::resolve(self.sampling_params, SendReject::Send),
tool_result_media: Knob::resolve(self.tool_result_media, ToolResultMedia::Native),
reasoning_efforts: self.reasoning_efforts,
model_prefixes: self.model_prefixes,
extensions: self.extensions.clone(),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct ResolvedAnthropicCompat {
pub thinking_format: AnthropicThinkingFormat,
pub thinking_replay: AnthropicThinkingReplay,
pub cache_control: AnthropicCacheControl,
pub structured_output: AnthropicStructuredOutput,
pub parallel_tool_calls: AnthropicParallelToolCalls,
pub sampling_params: AnthropicSamplingParams,
pub tool_result_media: ToolResultMedia,
pub reasoning_efforts: Option<ReasoningEfforts>,
pub model_prefixes: Option<&'static [&'static str]>,
pub extensions: Option<JsonObject>,
}
impl Default for ResolvedAnthropicCompat {
fn default() -> Self {
AnthropicCompat::EMPTY.resolve()
}
}
pub const ANTHROPIC_PRESETS: &[(&str, AnthropicCompat)] =
crate::generated::tables::ANTHROPIC_PRESETS;
pub const ANTHROPIC_PRESET_BASE_URLS: &[(&str, &str)] =
crate::generated::tables::ANTHROPIC_PRESET_BASE_URLS;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_resolves_to_the_dialect_defaults() {
let resolved = AnthropicCompat::EMPTY.resolve();
assert_eq!(resolved.thinking_format, AnthropicThinkingFormat::Anthropic);
assert_eq!(resolved.thinking_replay, AnthropicThinkingReplay::Signed);
assert_eq!(resolved.cache_control, AnthropicCacheControl::Anthropic);
assert_eq!(resolved.structured_output, SendReject::Send);
assert_eq!(resolved.sampling_params, SendReject::Send);
assert!(resolved.model_prefixes.is_none());
}
#[test]
fn presets_resolve_as_the_reference_table_says() {
let deepseek = AnthropicCompat::preset("deepseek").unwrap().resolve();
assert_eq!(deepseek.thinking_format, AnthropicThinkingFormat::Deepseek);
assert_eq!(deepseek.structured_output, SendReject::Reject);
assert_eq!(deepseek.model_prefixes, Some(&["deepseek-"][..]));
let moonshot = AnthropicCompat::preset("moonshotai").unwrap().resolve();
assert_eq!(moonshot.thinking_replay, AnthropicThinkingReplay::Unsigned);
assert_eq!(moonshot.reasoning_efforts.unwrap().len(), 3);
assert!(AnthropicCompat::preset("groq").is_none());
}
}