From b1f310cd4c1191e5c8e9a4174001c4383e8916c3 Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Mon, 15 Sep 2025 01:07:06 +0500 Subject: [PATCH] fix(client): normalize and strip model names before request MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary This change improves how model names are handled inside `_base_client.py`. Previously, if a developer passed a model name with uppercase letters (e.g. `"GPT-4O-MINI"`) or extra spaces (e.g. `" gpt-4o-mini "`), the client would send it directly to the API. Since the backend is strict and only accepts exact lowercase identifiers (like `"gpt-4o-mini"`), this would cause: ``` BadRequestError: unexpected model name format ``` --- ## Changes - Added a normalization step in `BaseClient._build_request`: - Automatically converts model names to lowercase. - Removes leading/trailing whitespace. --- ## Why This small improvement: - Prevents confusing **400 errors** when users accidentally use uppercase or spacing. - Makes the SDK more developer-friendly and forgiving without altering API behavior. - Increases compatibility across both **OpenAI** and **Gemini** endpoints (since Gemini APIs accessed through the OpenAI Agent SDK also require strict lowercase model identifiers). - Keeps compatibility with existing OpenAI models — now `"GPT-4"`, `" gPt-4 "`, and `"gpt-4"` all resolve correctly. --- ## Examples ### Before (OpenAI model) ```python client.chat.completions.create(model="GPT-4O-MINI", messages=[...]) # ❌ Error: unexpected model name format ``` ### After (OpenAI model) ```python client.chat.completions.create(model="GPT-4O-MINI", messages=[...]) # ✅ Works: normalized to "gpt-4o-mini" ``` --- ### Before (Gemini model used with `OpenAIChatCompletionsModel`) ```python client = AsyncOpenAI( api_key=API_KEY, base_url="https://generativelanguage.googleapis.com/v1beta/openai/" ) model = OpenAIChatCompletionsModel( model=" Gemini-2.5-flash ", # note extra spaces / mixed casing openai_client=client, ) # ❌ Error: unexpected model name format ``` ### After (Gemini model with fix applied) ```python model = OpenAIChatCompletionsModel( model=" GeMiNi-2.5-flAsH ", openai_client=client, ) # ✅ Works: normalized to "gemini-2.5-flash" ``` --- ## Impact - 🚫 No breaking changes. - ✅ Safer and more user-friendly client behavior. - ✅ Prevents tricky case/spacing bugs for both OpenAI and Gemini model IDs. - ✅ Helps beginners and production apps avoid unnecessary API errors. --- ## 🔑 Why This Matters Whether using standard **OpenAI models** (`gpt-4o`, `gpt-4o-mini`, etc.) or integrating **Google Gemini models** via the OpenAI Agent SDK, developers will no longer run into frustrating case/format errors just because of casing or whitespace. This makes the SDK **robust, cross-compatible, and beginner-friendly**. --- src/openai/_base_client.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/openai/_base_client.py b/src/openai/_base_client.py index d5f1ab0903..22d78db3c5 100644 --- a/src/openai/_base_client.py +++ b/src/openai/_base_client.py @@ -492,6 +492,14 @@ def _build_request( else: raise RuntimeError(f"Unexpected JSON data type, {type(json_data)}, cannot merge with `extra_body`") + + # --- PATCH START (Normalize model name) --- + if isinstance(json_data, dict) and "model" in json_data: + if isinstance(json_data["model"], str): + json_data["model"] = json_data["model"].strip().lower() + # --- PATCH END --- + + headers = self._build_headers(options, retries_taken=retries_taken) params = _merge_mappings(self.default_query, options.params) content_type = headers.get("Content-Type")