Surface OpenAI Responses service_tier="scale" (PR #5711)

Round 19 reviewer consensus (3/10 plus an asymmetric-fix call-out
across rounds 8/9/12/14/17): the openai-python SDK ships
service_tier as Literal["auto","default","flex","scale","priority"]
on /v1/responses, and enterprise Scale Tier customers need to opt in
explicitly. Drop the defensive scale-filter on the backend and add
"scale" to the OpenAI picker option list so the field reaches the
wire when set. Other providers remain at auto/default per their docs.

Update the routing tests so `scale` lives in the forwarded-set fixture
and the dropped-set fixture only carries truly out-of-enum values
(Anthropic-only `standard_only`, typos, empty string).
This commit is contained in:
Daniel Han 2026-05-24 20:09:17 +00:00
commit b961c6f2f7
3 changed files with 25 additions and 19 deletions

View file

@ -2827,12 +2827,14 @@ class ExternalProviderClient:
"input": input_items,
"stream": True,
}
# 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"):
# 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"):
body["service_tier"] = service_tier
if parallel_tool_calls is not None:
body["parallel_tool_calls"] = bool(parallel_tool_calls)

View file

@ -461,21 +461,24 @@ def test_openai_responses_forwards_service_tier(monkeypatch):
assert body.get("service_tier") == "priority", body
@pytest.mark.parametrize("value", ["auto", "default", "flex", "priority"])
@pytest.mark.parametrize(
"value", ["auto", "default", "flex", "scale", "priority"]
)
def test_openai_responses_forwards_documented_service_tiers(monkeypatch, value):
"""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."""
"""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."""
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", ["scale", "standard_only", "bogus", ""])
@pytest.mark.parametrize("bogus", ["standard_only", "bogus", ""])
def test_openai_responses_drops_undocumented_service_tier(monkeypatch, bogus):
"""`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."""
"""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."""
captured = _install_mock(monkeypatch, sse_payload = _responses_done_payload())
body = _drive_openai_responses(captured, service_tier = bogus)
assert "service_tier" not in body, body

View file

@ -101,10 +101,11 @@ export type ServiceTierOption =
/**
* Legal `service_tier` values per provider. Anthropic exposes only
* `auto` and `standard_only`. OpenAI in Studio is routed through
* `/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
* `/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
* stays usable for OpenAI-compat backends.
*/
export function getServiceTierOptions(
@ -114,7 +115,7 @@ export function getServiceTierOptions(
return ["auto", "standard_only"] as const;
}
if (providerType === "openai") {
return ["auto", "default", "flex", "priority"] as const;
return ["auto", "default", "flex", "scale", "priority"] as const;
}
return ["auto", "default"] as const;
}