diff --git a/backend/python/sglang/backend.py b/backend/python/sglang/backend.py index bb853af9a..bacb40159 100644 --- a/backend/python/sglang/backend.py +++ b/backend/python/sglang/backend.py @@ -207,6 +207,10 @@ class BackendServicer(backend_pb2_grpc.BackendServicer): return self.effort_budgets[effort] return self.thinking_budget + def _configured_budget(self) -> Optional[int]: + """Any budget configured for this model (fixed or per effort), for the load-time warning.""" + return self.thinking_budget or max((self.effort_budgets or {}).values(), default=None) + @staticmethod def _strict_thinking_warning(thinking_budget: Optional[int], engine_kwargs: dict) -> Optional[str]: """sglang only enforces the budget with enable_strict_thinking on; without @@ -389,9 +393,7 @@ class BackendServicer(backend_pb2_grpc.BackendServicer): print(f"engine_args error: {err}", file=sys.stderr) return backend_pb2.Result(success=False, message=str(err)) - warning = self._strict_thinking_warning( - self.thinking_budget or max((self.effort_budgets or {}).values(), default=None), engine_kwargs - ) + warning = self._strict_thinking_warning(self._configured_budget(), engine_kwargs) if warning: print(warning, file=sys.stderr) diff --git a/backend/python/sglang/test.py b/backend/python/sglang/test.py index c04c2156f..05c967a0f 100644 --- a/backend/python/sglang/test.py +++ b/backend/python/sglang/test.py @@ -402,6 +402,16 @@ class TestSglangHelpers(unittest.TestCase): self.assertIsNone(servicer._strict_thinking_warning(512, {"enable_strict_thinking": True})) self.assertIsNone(servicer._strict_thinking_warning(None, {})) + def test_warns_when_only_effort_budgets_are_set(self): + """A model with effort_budgets but no thinking_budget still needs strict thinking.""" + servicer = self._servicer() + servicer.thinking_budget = None + servicer.effort_budgets = {"low": 256, "max": 16384} + self.assertEqual(servicer._configured_budget(), 16384) + self.assertIn("enable_strict_thinking", servicer._strict_thinking_warning(servicer._configured_budget(), {})) + servicer.effort_budgets = {} + self.assertIsNone(servicer._configured_budget()) + def test_explicit_zero_temperature_and_seed_are_preserved(self): """Temperature=0 is greedy decoding and 0 is a valid seed — neither is an unset value. A dropped seed turns a reproducible request random.""" diff --git a/core/config/reasoning_effort_test.go b/core/config/reasoning_effort_test.go index c3a341eb2..4cf7362d2 100644 --- a/core/config/reasoning_effort_test.go +++ b/core/config/reasoning_effort_test.go @@ -46,11 +46,13 @@ var _ = Describe("ModelConfig.ApplyReasoningEffort", func() { }) It("does not let a level override an operator's config-level disable", func() { - disabled := true - c := &config.ModelConfig{} - c.ReasoningConfig.DisableReasoning = &disabled - c.ApplyReasoningEffort("high") - Expect(*c.ReasoningConfig.DisableReasoning).To(BeTrue()) + for _, level := range []string{"high", "xhigh", "max"} { + disabled := true + c := &config.ModelConfig{} + c.ReasoningConfig.DisableReasoning = &disabled + c.ApplyReasoningEffort(level) + Expect(*c.ReasoningConfig.DisableReasoning).To(BeTrue(), level) + } }) It("is a no-op on the toggle when no effort is set anywhere", func() {