agtrace_providers/claude/
models.rs1use std::collections::HashMap;
2
3#[derive(Debug, Clone, Copy, PartialEq)]
18pub struct ModelSpec {
19 pub prefix: &'static str,
20 pub context_window: u64,
21 pub compaction_buffer_pct: f64,
24}
25
26impl ModelSpec {
27 pub const fn new(
33 prefix: &'static str,
34 context_window: u64,
35 compaction_buffer_pct: f64,
36 ) -> Self {
37 Self {
38 prefix,
39 context_window,
40 compaction_buffer_pct,
41 }
42 }
43}
44
45const COMPACTION_BUFFER_PCT: f64 = 22.5;
48
49const MODEL_SPECS: &[ModelSpec] = &[
58 ModelSpec::new("claude-sonnet-4-5", 200_000, COMPACTION_BUFFER_PCT),
60 ModelSpec::new("claude-haiku-4-5", 200_000, COMPACTION_BUFFER_PCT),
61 ModelSpec::new("claude-opus-4-5", 200_000, COMPACTION_BUFFER_PCT),
62 ModelSpec::new("claude-sonnet-4", 200_000, COMPACTION_BUFFER_PCT),
64 ModelSpec::new("claude-haiku-4", 200_000, COMPACTION_BUFFER_PCT),
65 ModelSpec::new("claude-opus-4", 200_000, COMPACTION_BUFFER_PCT),
66 ModelSpec::new("claude-3-5", 200_000, COMPACTION_BUFFER_PCT),
68 ModelSpec::new("claude-3", 200_000, COMPACTION_BUFFER_PCT),
70];
71
72pub fn get_model_limits() -> HashMap<&'static str, (u64, f64)> {
74 MODEL_SPECS
75 .iter()
76 .map(|spec| {
77 (
78 spec.prefix,
79 (spec.context_window, spec.compaction_buffer_pct),
80 )
81 })
82 .collect()
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88 use std::collections::HashSet;
89
90 #[test]
91 fn test_no_duplicate_prefixes() {
92 let prefixes: Vec<&str> = MODEL_SPECS.iter().map(|spec| spec.prefix).collect();
93 let unique_prefixes: HashSet<&str> = prefixes.iter().copied().collect();
94
95 assert_eq!(
96 prefixes.len(),
97 unique_prefixes.len(),
98 "Duplicate prefixes found in MODEL_SPECS: {:?}",
99 prefixes
100 .iter()
101 .enumerate()
102 .filter(|(i, p)| prefixes.iter().skip(i + 1).any(|other| other == *p))
103 .map(|(_, p)| p)
104 .collect::<Vec<_>>()
105 );
106 }
107
108 #[test]
109 fn test_model_limits_coverage() {
110 let limits = get_model_limits();
111
112 assert_eq!(limits.get("claude-sonnet-4-5"), Some(&(200_000, 22.5)));
114 assert_eq!(limits.get("claude-haiku-4-5"), Some(&(200_000, 22.5)));
115 assert_eq!(limits.get("claude-opus-4-5"), Some(&(200_000, 22.5)));
116 assert_eq!(limits.get("claude-sonnet-4"), Some(&(200_000, 22.5)));
117 assert_eq!(limits.get("claude-3-5"), Some(&(200_000, 22.5)));
118 assert_eq!(limits.get("claude-3"), Some(&(200_000, 22.5)));
119 }
120
121 #[test]
122 fn test_all_specs_converted() {
123 let limits = get_model_limits();
124 assert_eq!(
125 limits.len(),
126 MODEL_SPECS.len(),
127 "HashMap size should match MODEL_SPECS length"
128 );
129 }
130}