use crate::types::ReasoningEffort;
pub const API_VERSION: &str = "2023-06-01";
pub const BETA_HEADER: &str = "anthropic-beta";
pub const BUILTIN_TOOL_TYPES: &[(&str, &str)] = &[
("web_search", "web_search_20250305"),
("code_execution", "code_execution_20250522"),
];
pub const CODE_EXECUTION_BETA: &str = "code-execution-2025-05-22";
pub const DEFAULT_VISIBLE_TOKENS: u64 = 16384;
pub const CLAUDE_OUTPUT_CEILINGS: &[(&str, u64)] = &[
("claude-3-haiku", 4096),
("claude-3-opus", 4096),
("claude-3-sonnet", 4096),
("claude-3-5-", 8192),
("claude-3.5-", 8192),
("claude-haiku-4-5", 64000),
("claude-sonnet-4-5", 64000),
("claude-opus-4-5", 64000),
("claude", 128000),
];
pub fn claude_output_ceiling(model: &str) -> Option<u64> {
let lowered = model.to_ascii_lowercase();
CLAUDE_OUTPUT_CEILINGS
.iter()
.find(|(marker, _)| lowered.contains(marker))
.map(|(_, ceiling)| *ceiling)
}
pub const ADAPTIVE_CLASS_MARKERS: &[&str] = &[
"sonnet-5",
"opus-5",
"sonnet-4-6",
"opus-4-6",
"opus-4-7",
"opus-4-8",
"fable",
"mythos",
"haiku-5",
];
pub fn anthropic_adaptive_class(model: &str) -> bool {
let lowered = model.to_ascii_lowercase();
ADAPTIVE_CLASS_MARKERS
.iter()
.any(|marker| lowered.contains(marker))
}
pub use crate::types::EFFORT_THINKING_BUDGETS;
pub fn effort_thinking_budget(effort: ReasoningEffort) -> Option<u64> {
EFFORT_THINKING_BUDGETS
.iter()
.find(|(word, _)| *word == effort)
.map(|(_, budget)| *budget)
}
pub fn builtin_tool_type(name: &str) -> &str {
BUILTIN_TOOL_TYPES
.iter()
.find(|(canonical, _)| *canonical == name)
.map(|(_, wire)| *wire)
.unwrap_or(name)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn adaptive_class_is_a_substring_table() {
assert!(anthropic_adaptive_class("claude-sonnet-5"));
assert!(anthropic_adaptive_class("Claude-Opus-4-6"));
assert!(anthropic_adaptive_class("claude-haiku-5-20270101"));
assert!(!anthropic_adaptive_class("claude-sonnet-4-5"));
assert!(!anthropic_adaptive_class("claude-haiku-4-5"));
assert!(!anthropic_adaptive_class("deepseek-v4-flash"));
}
#[test]
fn budgets_and_builtin_types_are_the_reference_tables() {
assert_eq!(effort_thinking_budget(ReasoningEffort::Minimal), Some(1024));
assert_eq!(effort_thinking_budget(ReasoningEffort::Low), Some(2048));
assert_eq!(effort_thinking_budget(ReasoningEffort::Medium), Some(8192));
assert_eq!(effort_thinking_budget(ReasoningEffort::High), Some(16384));
assert_eq!(effort_thinking_budget(ReasoningEffort::Xhigh), Some(24576));
assert_eq!(effort_thinking_budget(ReasoningEffort::Max), Some(32768));
assert_eq!(effort_thinking_budget(ReasoningEffort::Off), None);
assert_eq!(builtin_tool_type("web_search"), "web_search_20250305");
assert_eq!(
builtin_tool_type("code_execution"),
"code_execution_20250522"
);
assert_eq!(builtin_tool_type("computer_20250124"), "computer_20250124");
}
}