@@ -5,10 +5,10 @@ pub struct ReasoningTransform;
55impl Transformer for ReasoningTransform {
66 type Value = Context ;
77 fn transform ( & mut self , mut context : Self :: Value ) -> Self :: Value {
8- if let Some ( reasoning ) = context . reasoning . as_ref ( )
9- && reasoning . enabled . unwrap_or ( false )
10- {
11- // if reasoning is enabled then we've to drop top_k and top_p
8+ // Must stay in lockstep with the Anthropic request builder, which gates
9+ // on the same predicate — otherwise `thinking`/`output_config` ship
10+ // alongside sampling params that Anthropic rejects.
11+ if context . is_reasoning_supported ( ) {
1212 context. top_k = None ;
1313 context. top_p = None ;
1414 }
@@ -85,4 +85,51 @@ mod tests {
8585
8686 assert_eq ! ( actual, expected) ;
8787 }
88+
89+ #[ test]
90+ fn test_enabled_none_with_effort_still_strips_top_k_and_top_p ( ) {
91+ // `enabled: None` + effort is treated as reasoning-on (domain rule).
92+ let fixture = create_context_fixture ( ) . reasoning ( ReasoningConfig {
93+ enabled : None ,
94+ max_tokens : None ,
95+ effort : Some ( forge_domain:: Effort :: High ) ,
96+ exclude : None ,
97+ } ) ;
98+ let mut transformer = ReasoningTransform ;
99+ let actual = transformer. transform ( fixture) ;
100+
101+ assert_eq ! ( actual. top_k, None ) ;
102+ assert_eq ! ( actual. top_p, None ) ;
103+ }
104+
105+ #[ test]
106+ fn test_enabled_none_with_positive_max_tokens_still_strips_top_k_and_top_p ( ) {
107+ let fixture = create_context_fixture ( ) . reasoning ( ReasoningConfig {
108+ enabled : None ,
109+ max_tokens : Some ( 8000 ) ,
110+ effort : None ,
111+ exclude : None ,
112+ } ) ;
113+ let mut transformer = ReasoningTransform ;
114+ let actual = transformer. transform ( fixture) ;
115+
116+ assert_eq ! ( actual. top_k, None ) ;
117+ assert_eq ! ( actual. top_p, None ) ;
118+ }
119+
120+ #[ test]
121+ fn test_enabled_none_with_zero_max_tokens_preserves_top_k_and_top_p ( ) {
122+ // Matches `is_reasoning_supported`: max_tokens == 0 is treated as off.
123+ let fixture = create_context_fixture ( ) . reasoning ( ReasoningConfig {
124+ enabled : None ,
125+ max_tokens : Some ( 0 ) ,
126+ effort : None ,
127+ exclude : None ,
128+ } ) ;
129+ let mut transformer = ReasoningTransform ;
130+ let actual = transformer. transform ( fixture. clone ( ) ) ;
131+
132+ assert_eq ! ( actual. top_k, fixture. top_k) ;
133+ assert_eq ! ( actual. top_p, fixture. top_p) ;
134+ }
88135}
0 commit comments