From 5d4ddd6b374b9dddbe2dcc73af3696f9b1c94689 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Sun, 24 May 2026 20:24:53 +0000 Subject: [PATCH] Revert "Surface OpenAI Responses service_tier='scale' (PR #5711)" Round 19 added scale to /v1/responses based on the openai-python SDK type, but round 20 reviewers (3/10 against) and the round 18 aggregator both noted that the live OpenAI Responses reference limits Responses service tiers to auto/default/flex/priority. The PR contract in the original description also lists scale only for Chat Completions, not Responses. Studio routes OpenAI through Responses, so forwarding scale risks a 400 from the upstream and exposes a picker option the API does not accept. Restore the conservative drop behaviour: only documented Responses tiers reach the wire; legacy scale settings still validate (the ServiceTier Literal and chat-settings storage allowlist keep it for forward-compat). --- .../backend/core/inference/external_provider.py | 14 ++++++-------- .../tests/test_sampling_params_routing.py | 17 ++++++++--------- .../src/features/chat/provider-capabilities.ts | 11 +++++------ 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/studio/backend/core/inference/external_provider.py b/studio/backend/core/inference/external_provider.py index f0e6d2b852..d1f2aec813 100644 --- a/studio/backend/core/inference/external_provider.py +++ b/studio/backend/core/inference/external_provider.py @@ -2827,14 +2827,12 @@ class ExternalProviderClient: "input": input_items, "stream": True, } - # Responses accepts auto|default|flex|scale|priority per the - # openai-python SDK type - # (src/openai/types/responses/response_create_params.py). - # Scale Tier is enterprise-gated and the live docs sometimes - # omit it from the request enum, but the SDK ships it and - # Studio's enterprise users need to opt in. parallel_tool_calls - # default is true. - if service_tier in ("auto", "default", "flex", "scale", "priority"): + # Responses accepts auto|default|flex|priority per the live + # docs. The openai-python SDK type happens to include "scale" + # too but the public Responses reference does not, so drop it + # here to avoid a 400. Scale Tier is still selectable on Chat + # Completions backends. parallel_tool_calls default is true. + if service_tier in ("auto", "default", "flex", "priority"): body["service_tier"] = service_tier if parallel_tool_calls is not None: body["parallel_tool_calls"] = bool(parallel_tool_calls) diff --git a/studio/backend/tests/test_sampling_params_routing.py b/studio/backend/tests/test_sampling_params_routing.py index f667245118..1a0b3fed60 100644 --- a/studio/backend/tests/test_sampling_params_routing.py +++ b/studio/backend/tests/test_sampling_params_routing.py @@ -461,22 +461,21 @@ def test_openai_responses_forwards_service_tier(monkeypatch): assert body.get("service_tier") == "priority", body -@pytest.mark.parametrize("value", ["auto", "default", "flex", "scale", "priority"]) +@pytest.mark.parametrize("value", ["auto", "default", "flex", "priority"]) def test_openai_responses_forwards_documented_service_tiers(monkeypatch, value): - """openai-python ships service_tier as - `Literal["auto","default","flex","scale","priority"]` for - /v1/responses (response_create_params.py). Pin that every value - in the SDK enum forwards untouched.""" + """The live OpenAI Responses API reference lists `service_tier` as + `auto|default|flex|priority` for /v1/responses. Pin that every value + in the documented enum forwards untouched.""" captured = _install_mock(monkeypatch, sse_payload = _responses_done_payload()) body = _drive_openai_responses(captured, service_tier = value) assert body.get("service_tier") == value, body -@pytest.mark.parametrize("bogus", ["standard_only", "bogus", ""]) +@pytest.mark.parametrize("bogus", ["scale", "standard_only", "bogus", ""]) def test_openai_responses_drops_undocumented_service_tier(monkeypatch, bogus): - """Anything outside the SDK enum (Anthropic-only `standard_only`, - typos, empty string) is dropped client-side so a stale frontend - never sends an upstream-rejected value.""" + """`scale` and `standard_only` are not in the documented Responses + request enum; drop them client-side so a stale frontend never + sends an upstream-rejected value.""" captured = _install_mock(monkeypatch, sse_payload = _responses_done_payload()) body = _drive_openai_responses(captured, service_tier = bogus) assert "service_tier" not in body, body diff --git a/studio/frontend/src/features/chat/provider-capabilities.ts b/studio/frontend/src/features/chat/provider-capabilities.ts index 6b64efb649..b190dc79be 100644 --- a/studio/frontend/src/features/chat/provider-capabilities.ts +++ b/studio/frontend/src/features/chat/provider-capabilities.ts @@ -101,11 +101,10 @@ export type ServiceTierOption = /** * Legal `service_tier` values per provider. Anthropic exposes only * `auto` and `standard_only`. OpenAI in Studio is routed through - * `/v1/responses`; the openai-python SDK type - * (`src/openai/types/responses/response_create_params.py`) lists - * `auto|default|flex|scale|priority`, so the enterprise-gated `scale` - * tier is surfaced for users who have it. Other providers fall - * through to a permissive `auto` / `default` pair so the picker + * `/v1/responses`, which the live docs list as + * `auto|default|flex|priority`; `scale` is excluded here even though + * the openai-python SDK type happens to include it. Other providers + * fall through to a permissive `auto` / `default` pair so the picker * stays usable for OpenAI-compat backends. */ export function getServiceTierOptions( @@ -115,7 +114,7 @@ export function getServiceTierOptions( return ["auto", "standard_only"] as const; } if (providerType === "openai") { - return ["auto", "default", "flex", "scale", "priority"] as const; + return ["auto", "default", "flex", "priority"] as const; } return ["auto", "default"] as const; }