diff --git a/lm15/providers/openai.py b/lm15/providers/openai.py index dad191e..f3d672c 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: @@ -177,12 +177,18 @@ 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) + 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 7995757..530351f 100644 --- a/tests/test_cache_mapping.py +++ b/tests/test_cache_mapping.py @@ -34,11 +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")