From da260c38cbaf17438eb08573467e272229a76e3b Mon Sep 17 00:00:00 2001 From: JustVugg Date: Wed, 15 Jul 2026 14:56:01 +0200 Subject: [PATCH] server: clamp max_tokens to the server cap instead of rejecting it (fixes #260) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit opencode / the ai-sdk OpenAI-compatible client sends a large default max_tokens (> the server's --max-tokens cap, 1024 by default), and generation_options returned 400 "must be an integer between 1 and 1024" — even for a trivial "hello". OpenAI-compatible servers clamp to their own ceiling rather than reject. Now max_tokens > limit is clamped to limit; only non-int / non-positive values are a hard error. Test updated to assert the clamp + keep the <1 reject. Co-Authored-By: Claude Opus 4.8 --- c/openai_server.py | 7 +++++-- c/tests/test_openai_server.py | 7 ++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/c/openai_server.py b/c/openai_server.py index f31e8f7..ba19e43 100644 --- a/c/openai_server.py +++ b/c/openai_server.py @@ -410,8 +410,11 @@ def generation_options(body, limit): top_p = body.get("top_p") temperature = 0.7 if temperature is None else temperature top_p = 0.9 if top_p is None else top_p - if isinstance(maximum, bool) or not isinstance(maximum, int) or not 1 <= maximum <= limit: - raise APIError(400, f"`{maximum_param}` must be an integer between 1 and {limit}.", maximum_param) + if isinstance(maximum, bool) or not isinstance(maximum, int) or maximum < 1: + raise APIError(400, f"`{maximum_param}` must be a positive integer.", maximum_param) + if maximum > limit: + maximum = limit # clamp to the server's --max-tokens cap instead of 400 (#260): OpenAI + # clients (opencode/ai-sdk) default to large max_tokens; rejecting breaks them. if (isinstance(temperature, bool) or not isinstance(temperature, (int, float)) or not math.isfinite(temperature) or not 0 <= temperature <= 2): raise APIError(400, "`temperature` must be between 0 and 2.", "temperature") diff --git a/c/tests/test_openai_server.py b/c/tests/test_openai_server.py index 0064070..f8aec86 100644 --- a/c/tests/test_openai_server.py +++ b/c/tests/test_openai_server.py @@ -72,8 +72,13 @@ class TemplateTest(unittest.TestCase): def test_validates_generation_limits(self): self.assertEqual(generation_options({"max_tokens": 4, "temperature": 0, "top_p": 1}, 8), (4, 0.0, 1.0)) + # max_tokens above the server cap is clamped, not rejected (#260): OpenAI + # clients default to large values; erroring breaks them. + self.assertEqual(generation_options({"max_tokens": 9, "temperature": 0, "top_p": 1}, 8), + (8, 0.0, 1.0)) + # non-positive / non-int max_tokens is still a hard error with self.assertRaises(APIError): - generation_options({"max_tokens": 9}, 8) + generation_options({"max_tokens": 0}, 8) with self.assertRaises(APIError): generation_options({"temperature": math.nan}, 8) with self.assertRaises(APIError):