Repository navigation
Keep request service tiers closed; open only the response tier - #44
Merged
Merged
Conversation
#42 made `chat::ServiceTier` and `responses::ServiceTier` open, and the request types share them, so a request naming any tier became valid. A caller that validates incoming requests against these types widened its accepted values as a side effect of a response-decoding fix. Split the two directions. `ServiceTier` is closed again, exactly as before #42, and stays on `CreateChatCompletionRequest` and `CreateResponse`. The response fields (`CreateChatCompletionResponse`, `CreateChatCompletionStreamResponse`, `Response`) use `ServiceTierResponse`, which keeps an unnamed tier verbatim in `Other(String)`, with the hand-written any-string schema. `chat::ServiceTierResponse` was unused; it gains `Auto` so it covers every value the request enum can hold.
There was a problem hiding this comment.
🟢 Approved
The request/response type separation is consistent and adequately covered by focused serialization tests.
0 open findings
What changed in this PR
Separates closed request service tiers from forward-compatible response tiers.
Changes:
- Restores closed service-tier request enums.
- Adds open response enums preserving unknown tiers.
- Adds request rejection and response round-trip tests.
| File | Description |
|---|---|
async-openai/src/types/chat/chat_.rs |
Separates chat request and response tier types. |
async-openai/src/types/responses/response.rs |
Adds a forward-compatible response tier type. |
async-openai/tests/ser_de.rs |
Tests chat request restrictions and response tiers. |
async-openai/tests/responses_ser_de.rs |
Tests Responses API request restrictions and response tiers. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
krinart
added a commit
to spiceai/spiceai
that referenced
this pull request
Oct 9, 2026
…openai#44 spiceai/async-openai#42 opened `ServiceTier`, which the request types share, so `/v1/chat/completions` and `/v1/responses` started accepting and forwarding any `service_tier` a client sent. That widens a published request field, which the #14916 fix did not need. #44 (merged as dfadaed) restores the closed `ServiceTier` on requests and moves only the response fields to the open `ServiceTierResponse`. The Databricks stream type follows the response field. The guard now sends a named tier and checks the server's unnamed tier comes back, and a new `a_request_naming_an_unnamed_tier_is_refused` pins both request types to the listed tiers, which fails on the previous pin.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #42, from review of spiceai/spiceai#14927.
#42 opened
chat::ServiceTierandresponses::ServiceTier. The request types share those enums, so requests started accepting any tier. Spice deserializes/v1/chat/completionsand/v1/responsesrequest bodies into these types, so a client-suppliedservice_tier: "fast"went from 422 to forwarded: an unreviewed widening of a published request field. Only the response side needed to change.Change
ServiceTier(chat and responses) is closed again, byte-identical to before Accept a service_tier the enum does not name #42 (includingCopyand the derived schema). It stays onCreateChatCompletionRequestandCreateResponse.CreateChatCompletionResponse.service_tier,CreateChatCompletionStreamResponse.service_tier, andResponse.service_tieruseServiceTierResponse. It names the same five tiers and keeps any other tier verbatim in#[serde(untagged)] Other(String), with the hand-written any-string schema from Accept a service_tier the enum does not name #42.chat::ServiceTierResponsealready existed and was unused. It gainsAutoso it covers every request value.responses::ServiceTierResponseis new.Callers that name the response field's type change from
ServiceTiertoServiceTierResponse. In Spice that is one field in the Databricks stream type.Validation
cargo test --features "chat-completion-types response-types" --test ser_de --test responses_ser_de: 13 passed. New:a_request_names_only_the_closed_tiers(priorityaccepted,fastrefused) for both request types.cargo clippy --all-features --all-targetsbuilds with only the 4 existing warnings. Offline suites pass. The 12 lib andboxed_futurefailures are live-API tests that api.openai.com rejects withinvalid_api_key.llmsguard tests (health check, request, and stream through both chat backends against an endpoint answering"fast", plus a new request-side check): 7 passed on this branch. On Accept a service_tier the enum does not name #42's merge (2c102dc), the request-side check fails because"fast"deserializes toSome(Other("fast")).