From cbd4da272b0b70942c231f6baa2bb566c170a41f Mon Sep 17 00:00:00 2001 From: oimwiodev Date: Thu, 21 May 2026 20:18:30 +0100 Subject: [PATCH] Add GPT-5.5 Pro preset --- README.md | 1 + chatmock/fast_mode.py | 1 + chatmock/model_registry.py | 24 ++++++++++++++++++------ tests/test_models.py | 14 +++++++++++++- tests/test_routes.py | 2 ++ 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index acf410f..fa943c9 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,7 @@ curl http://127.0.0.1:8000/v1/chat/completions \ ## Supported Models - `gpt-5.5` +- `gpt-5.5-pro` (preset for `gpt-5.5` with xhigh reasoning) - `gpt-5.4` - `gpt-5.4-mini` - `gpt-5.2` diff --git a/chatmock/fast_mode.py b/chatmock/fast_mode.py index 8dbb557..7010ca4 100644 --- a/chatmock/fast_mode.py +++ b/chatmock/fast_mode.py @@ -9,6 +9,7 @@ from .model_registry import normalize_model_name PRIORITY_SUPPORTED_MODELS = frozenset( ( "gpt-5.4", + "gpt-5.5", "gpt-5.2", "gpt-5.1", "gpt-5", diff --git a/chatmock/model_registry.py b/chatmock/model_registry.py index 1b97bc6..4ffa17b 100644 --- a/chatmock/model_registry.py +++ b/chatmock/model_registry.py @@ -16,6 +16,7 @@ class ModelSpec: allowed_efforts: frozenset[str] variant_efforts: tuple[str, ...] uses_codex_instructions: bool = False + preset_effort: str | None = None _MODEL_SPECS = ( @@ -61,6 +62,14 @@ _MODEL_SPECS = ( allowed_efforts=frozenset(("none", "low", "medium", "high", "xhigh")), variant_efforts=("xhigh", "high", "medium", "low", "none"), ), + ModelSpec( + public_id="gpt-5.5-pro", + upstream_id="gpt-5.5", + aliases=("gpt5.5-pro", "gpt-5.5-pro-latest"), + allowed_efforts=frozenset(("none", "low", "medium", "high", "xhigh")), + variant_efforts=(), + preset_effort="xhigh", + ), ModelSpec( public_id="gpt-5.3-codex", upstream_id="gpt-5.3-codex", @@ -127,12 +136,12 @@ _MODEL_SPECS = ( ), ) -_SPECS_BY_UPSTREAM = {spec.upstream_id: spec for spec in _MODEL_SPECS} +_SPECS_BY_PUBLIC_ID = {spec.public_id: spec for spec in _MODEL_SPECS} _ALIASES = {} for _spec in _MODEL_SPECS: - _ALIASES[_spec.public_id] = _spec.upstream_id + _ALIASES[_spec.public_id] = _spec.public_id for _alias in _spec.aliases: - _ALIASES[_alias] = _spec.upstream_id + _ALIASES[_alias] = _spec.public_id def _strip_model_name(model: str | None) -> tuple[str, str | None]: @@ -155,10 +164,10 @@ def _strip_model_name(model: str | None) -> tuple[str, str | None]: def model_spec_for_name(model: str | None) -> ModelSpec | None: base, _ = _strip_model_name(model) - upstream_id = _ALIASES.get(base) - if not upstream_id: + public_id = _ALIASES.get(base) + if not public_id: return None - return _SPECS_BY_UPSTREAM.get(upstream_id) + return _SPECS_BY_PUBLIC_ID.get(public_id) def normalize_model_name(model: str | None, debug_model: str | None = None) -> str: @@ -187,6 +196,9 @@ def allowed_efforts_for_model(model: str | None) -> frozenset[str]: def extract_reasoning_from_model_name(model: str | None) -> dict[str, str] | None: _, effort = _strip_model_name(model) + if not effort: + spec = model_spec_for_name(model) + effort = spec.preset_effort if spec is not None else None if not effort: return None return {"effort": effort} diff --git a/tests/test_models.py b/tests/test_models.py index 022cdd2..ac72872 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -2,7 +2,12 @@ from __future__ import annotations import unittest -from chatmock.model_registry import allowed_efforts_for_model, list_public_models, normalize_model_name +from chatmock.model_registry import ( + allowed_efforts_for_model, + extract_reasoning_from_model_name, + list_public_models, + normalize_model_name, +) class ModelRegistryTests(unittest.TestCase): @@ -11,6 +16,7 @@ class ModelRegistryTests(unittest.TestCase): self.assertEqual(normalize_model_name("gpt5.4"), "gpt-5.4") self.assertEqual(normalize_model_name("gpt5.4-mini"), "gpt-5.4-mini") self.assertEqual(normalize_model_name("gpt5.5"), "gpt-5.5") + self.assertEqual(normalize_model_name("gpt-5.5-pro"), "gpt-5.5") self.assertEqual(normalize_model_name("gpt5.3-codex-spark"), "gpt-5.3-codex-spark") self.assertEqual(normalize_model_name("codex"), "codex-mini-latest") @@ -24,13 +30,19 @@ class ModelRegistryTests(unittest.TestCase): def test_allowed_efforts_follow_registry(self) -> None: self.assertEqual(allowed_efforts_for_model("gpt-5.5"), frozenset(("none", "low", "medium", "high", "xhigh"))) + self.assertEqual(allowed_efforts_for_model("gpt-5.5-pro"), frozenset(("none", "low", "medium", "high", "xhigh"))) self.assertEqual(allowed_efforts_for_model("gpt-5.4"), frozenset(("none", "low", "medium", "high", "xhigh"))) self.assertEqual(allowed_efforts_for_model("gpt-5.4-mini"), frozenset(("low", "medium", "high", "xhigh"))) self.assertEqual(allowed_efforts_for_model("gpt-5.1-codex"), frozenset(("low", "medium", "high"))) + def test_pro_preset_uses_xhigh_reasoning(self) -> None: + self.assertEqual(extract_reasoning_from_model_name("gpt-5.5-pro"), {"effort": "xhigh"}) + self.assertEqual(extract_reasoning_from_model_name("gpt-5.5-pro-low"), {"effort": "low"}) + def test_public_models_include_variants(self) -> None: model_ids = list_public_models(expose_reasoning_models=True) self.assertIn("gpt-5.5", model_ids) + self.assertIn("gpt-5.5-pro", model_ids) self.assertIn("gpt-5.4", model_ids) self.assertIn("gpt-5.4-mini", model_ids) self.assertIn("gpt-5.3-codex-spark", model_ids) diff --git a/tests/test_routes.py b/tests/test_routes.py index c5d94bc..789a2b5 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -59,6 +59,8 @@ class RouteTests(unittest.TestCase): body = response.get_json() self.assertEqual(response.status_code, 200) model_ids = [item["id"] for item in body["data"]] + self.assertIn("gpt-5.5", model_ids) + self.assertIn("gpt-5.5-pro", model_ids) self.assertIn("gpt-5.4", model_ids) self.assertIn("gpt-5.4-mini", model_ids) self.assertIn("gpt-5.3-codex-spark", model_ids)