1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use serde::{Deserialize, Serialize};
/// Configuration for enabling Claude's extended thinking capabilities.
///
/// This can be either enabled (with a token budget) or disabled.
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "type")]
pub enum ThinkingConfig {
/// Disabled thinking configuration.
#[serde(rename = "disabled")]
Disabled,
/// Enabled thinking configuration with a token budget.
#[serde(rename = "enabled")]
Enabled {
/// Determines how many tokens Claude can use for its internal reasoning process.
///
/// Larger budgets can enable more thorough analysis for complex problems, improving
/// response quality.
///
/// Must be ≥1024 and less than `max_tokens`.
#[serde(rename = "budget_tokens")]
budget_tokens: u32,
},
}
impl ThinkingConfig {
/// Returns the number of budget tokens configured for thinking.
///
/// Returns 0 if thinking is disabled.
pub fn num_tokens(&self) -> u32 {
match self {
ThinkingConfig::Disabled => 0,
ThinkingConfig::Enabled { budget_tokens } => *budget_tokens,
}
}
/// Create a new enabled thinking configuration with the given budget tokens.
///
/// Budget tokens must be ≥1024.
pub fn enabled(budget_tokens: u32) -> Self {
Self::Enabled { budget_tokens }
}
/// Create a new disabled thinking configuration.
pub fn disabled() -> Self {
Self::Disabled
}
}
impl Default for ThinkingConfig {
fn default() -> Self {
Self::disabled()
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::{json, to_value};
#[test]
fn thinking_config_enabled_serialization() {
let config = ThinkingConfig::enabled(2048);
let json = to_value(config).unwrap();
assert_eq!(
json,
json!({
"type": "enabled",
"budget_tokens": 2048
})
);
}
#[test]
fn thinking_config_disabled_serialization() {
let config = ThinkingConfig::disabled();
let json = to_value(config).unwrap();
assert_eq!(
json,
json!({
"type": "disabled"
})
);
}
#[test]
fn thinking_config_enabled_deserialization() {
let json = json!({
"type": "enabled",
"budget_tokens": 2048
});
let config: ThinkingConfig = serde_json::from_value(json).unwrap();
match config {
ThinkingConfig::Enabled { budget_tokens } => {
assert_eq!(budget_tokens, 2048);
}
_ => panic!("Expected Enabled variant"),
}
}
#[test]
fn thinking_config_disabled_deserialization() {
let json = json!({
"type": "disabled"
});
let config: ThinkingConfig = serde_json::from_value(json).unwrap();
match config {
ThinkingConfig::Disabled => {}
_ => panic!("Expected Disabled variant"),
}
}
}