From 21632845219784bfeb4afa511ba65bc4598f96da Mon Sep 17 00:00:00 2001 From: Jakub Schwenkbeck Date: Fri, 16 Oct 2026 16:57:16 +0200 Subject: [PATCH 1/2] fix(openai): support major-only GPT cache model IDs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- lm15/providers/openai.py | 10 +++++----- tests/test_cache_mapping.py | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lm15/providers/openai.py b/lm15/providers/openai.py index dad191ec..d8800cc8 100644 --- a/lm15/providers/openai.py +++ b/lm15/providers/openai.py @@ -167,7 +167,7 @@ def _attach_unmapped(provider_data: dict[str, Any], unmapped: list[dict[str, str return out -_GPT_VERSION_RE = re.compile(r"^gpt-(\d+)\.(\d+)") +_GPT_VERSION_RE = re.compile(r"^gpt-(\d+)(?:\.(\d+))?(?:-|$)") def openai_model_has_cache_options(model: str) -> bool: @@ -177,12 +177,12 @@ def openai_model_has_cache_options(model: str) -> bool: that class accepts it (older models reject it with HTTP 400, and their writes are free anyway). Deciding client-side needs a model check — a table that rots. Stated trade-off: a future family whose name does - not match ``gpt-.`` keeps the provider's implicit writes - on ``mode="off"``; ``extensions={"prompt_cache_options": ...}`` is the - override. + not match ``gpt-`` or ``gpt-.`` keeps the + provider's implicit writes on ``mode="off"``; + ``extensions={"prompt_cache_options": ...}`` is the override. """ m = _GPT_VERSION_RE.match(model.lower()) - return bool(m) and (int(m.group(1)), int(m.group(2))) >= (5, 6) + return bool(m) and (int(m.group(1)), int(m.group(2) or 0)) >= (5, 6) def _cache_breakpoint_index(request: Request, cache_control: str) -> int | None: diff --git a/tests/test_cache_mapping.py b/tests/test_cache_mapping.py index 79957570..04b6c2b3 100644 --- a/tests/test_cache_mapping.py +++ b/tests/test_cache_mapping.py @@ -36,6 +36,7 @@ def _body(lm, request: Request) -> dict: def test_openai_model_class_for_cache_options() -> None: assert openai_model_has_cache_options("gpt-5.6-sol") assert openai_model_has_cache_options("gpt-6.0") + assert openai_model_has_cache_options("gpt-6-luna") assert openai_model_has_cache_options("GPT-5.10") assert not openai_model_has_cache_options("gpt-5.5") assert not openai_model_has_cache_options("gpt-4.1-mini") From 36628c90de605b625946fd2893c731b296cc293d Mon Sep 17 00:00:00 2001 From: Jakub Schwenkbeck Date: Sat, 17 Oct 2026 11:17:10 +0200 Subject: [PATCH 2/2] fix(openai): avoid Azure legacy GPT cache matching Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- lm15/providers/openai.py | 10 ++++++++-- tests/test_cache_mapping.py | 6 ++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lm15/providers/openai.py b/lm15/providers/openai.py index d8800cc8..f3d672c3 100644 --- a/lm15/providers/openai.py +++ b/lm15/providers/openai.py @@ -167,7 +167,7 @@ def _attach_unmapped(provider_data: dict[str, Any], unmapped: list[dict[str, str return out -_GPT_VERSION_RE = re.compile(r"^gpt-(\d+)(?:\.(\d+))?(?:-|$)") +_GPT_VERSION_RE = re.compile(r"^gpt-(?:(\d+)\.(\d+)|([1-9]))(?:-|$)") def openai_model_has_cache_options(model: str) -> bool: @@ -182,7 +182,13 @@ def openai_model_has_cache_options(model: str) -> bool: ``extensions={"prompt_cache_options": ...}`` is the override. """ m = _GPT_VERSION_RE.match(model.lower()) - return bool(m) and (int(m.group(1)), int(m.group(2) or 0)) >= (5, 6) + if not m: + return False + if m.group(1) is not None: + major, minor = int(m.group(1)), int(m.group(2)) + else: + major, minor = int(m.group(3)), 0 + return (major, minor) >= (5, 6) def _cache_breakpoint_index(request: Request, cache_control: str) -> int | None: diff --git a/tests/test_cache_mapping.py b/tests/test_cache_mapping.py index 04b6c2b3..530351fa 100644 --- a/tests/test_cache_mapping.py +++ b/tests/test_cache_mapping.py @@ -34,12 +34,18 @@ def _body(lm, request: Request) -> dict: # ─── model class table ─────────────────────────────────────────────── def test_openai_model_class_for_cache_options() -> None: + assert openai_model_has_cache_options("gpt-6") assert openai_model_has_cache_options("gpt-5.6-sol") assert openai_model_has_cache_options("gpt-6.0") assert openai_model_has_cache_options("gpt-6-luna") assert openai_model_has_cache_options("GPT-5.10") + assert not openai_model_has_cache_options("gpt-5") + assert not openai_model_has_cache_options("gpt-5-mini") assert not openai_model_has_cache_options("gpt-5.5") assert not openai_model_has_cache_options("gpt-4.1-mini") + assert not openai_model_has_cache_options("gpt-3.5-turbo") + assert not openai_model_has_cache_options("gpt-35-turbo") + assert not openai_model_has_cache_options("gpt-35-turbo-16k") assert not openai_model_has_cache_options("o3") # unknown pattern -> no switch (stated trade-off) assert not openai_model_has_cache_options("chat-latest")