mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
Serialize Responses routing fields before large inputs (#49675)
## Why Gateways that inspect request bodies incrementally need routing fields before potentially multi-megabyte prompts so they can route requests without buffering the input first. ## What changed Serialize `model`, `stream`, and optional `service_tier` before `input` in both HTTP Responses requests and WebSocket `response.create` messages. Preserve field values and omission of unset `service_tier`. ## Testing Add an HTTP regression test with a 2 MiB input that checks routing field order and unchanged JSON contents. Extend WebSocket serialization coverage to assert the routing fields appear first, and check that HTTP requests omit unset `service_tier`. GitOrigin-RevId: dbc174e1fe7ca30d0c00f075bc37dd5f97b27b37
This commit is contained in:
committed by
copyberry
parent
67727e7cf1
commit
ed0cc1a4ab
@@ -277,7 +277,12 @@ impl Serialize for ResponsesApiTools {
|
||||
|
||||
#[derive(Debug, Serialize, Clone, PartialEq)]
|
||||
pub struct ResponsesApiRequest {
|
||||
// Keep routing fields first: serde serializes struct fields in declaration order, and
|
||||
// gateways may inspect request bodies incrementally before potentially multi-megabyte input.
|
||||
pub model: String,
|
||||
pub stream: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub service_tier: Option<String>,
|
||||
#[serde(skip_serializing_if = "String::is_empty")]
|
||||
pub instructions: String,
|
||||
pub input: Vec<ResponseItem>,
|
||||
@@ -287,13 +292,10 @@ pub struct ResponsesApiRequest {
|
||||
pub parallel_tool_calls: bool,
|
||||
pub reasoning: Option<Reasoning>,
|
||||
pub store: bool,
|
||||
pub stream: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub stream_options: Option<StreamOptions>,
|
||||
pub include: Vec<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub service_tier: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub prompt_cache_key: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub text: Option<TextControls>,
|
||||
@@ -330,7 +332,12 @@ impl<'a> From<&'a ResponsesApiRequest> for ResponseCreateWsRequest<'a> {
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ResponseCreateWsRequest<'a> {
|
||||
// Keep routing fields first: serde serializes struct fields in declaration order, and
|
||||
// gateways may inspect request bodies incrementally before potentially multi-megabyte input.
|
||||
pub model: &'a str,
|
||||
pub stream: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub service_tier: Option<&'a str>,
|
||||
#[serde(skip_serializing_if = "str::is_empty")]
|
||||
pub instructions: &'a str,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@@ -342,13 +349,10 @@ pub struct ResponseCreateWsRequest<'a> {
|
||||
pub parallel_tool_calls: bool,
|
||||
pub reasoning: Option<&'a Reasoning>,
|
||||
pub store: bool,
|
||||
pub stream: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub stream_options: Option<&'a StreamOptions>,
|
||||
pub include: &'a [String],
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub service_tier: Option<&'a str>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub prompt_cache_key: Option<&'a str>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub text: Option<&'a TextControls>,
|
||||
|
||||
@@ -997,6 +997,9 @@ mod tests {
|
||||
expected_payload["generate"] = json!(false);
|
||||
let request_text =
|
||||
serialize_websocket_request(&request).expect("serialize websocket request");
|
||||
assert!(request_text.starts_with(
|
||||
r#"{"type":"response.create","model":"gpt-test","stream":true,"service_tier":"priority","instructions":"Use the available tools.","previous_response_id":"resp-1","input":"#
|
||||
));
|
||||
let wire_payload =
|
||||
serde_json::from_str::<Value>(&request_text).expect("parse websocket request");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user