Do not attempt to append after response.completed (#11402)

Completed responses are fully done, and new response must be created.
This commit is contained in:
pakrym-oai
2026-02-11 07:45:17 -08:00
committed by GitHub
parent 83a54766b7
commit eac5473114
9 changed files with 93 additions and 12 deletions

View File

@@ -63,6 +63,8 @@ pub enum ResponseEvent {
Completed {
response_id: String,
token_usage: Option<TokenUsage>,
/// Whether the client can append more items to a long-running websocket response.
can_append: bool,
},
OutputTextDelta(String),
ReasoningSummaryDelta {

View File

@@ -66,6 +66,7 @@ impl Stream for AggregatedStream {
Poll::Ready(Some(Ok(ResponseEvent::Completed {
response_id,
token_usage,
can_append: _can_append,
}))) => {
let mut emitted_any = false;
@@ -102,6 +103,7 @@ impl Stream for AggregatedStream {
this.pending.push_back(ResponseEvent::Completed {
response_id: response_id.clone(),
token_usage: token_usage.clone(),
can_append: false,
});
if let Some(ev) = this.pending.pop_front() {
return Poll::Ready(Some(Ok(ev)));
@@ -111,6 +113,7 @@ impl Stream for AggregatedStream {
return Poll::Ready(Some(Ok(ResponseEvent::Completed {
response_id,
token_usage,
can_append: false,
})));
}
Poll::Ready(Some(Ok(ResponseEvent::Created))) => continue,

View File

@@ -343,6 +343,7 @@ async fn run_websocket_response_stream(
)));
}
};
trace!("websocket request: {request_text}");
let request_start = Instant::now();
let result = ws_stream

View File

@@ -259,6 +259,7 @@ pub fn process_responses_event(
return Ok(Some(ResponseEvent::Completed {
response_id: resp.id,
token_usage: resp.usage.map(Into::into),
can_append: false,
}));
}
Err(err) => {
@@ -276,6 +277,7 @@ pub fn process_responses_event(
return Ok(Some(ResponseEvent::Completed {
response_id: resp.id.unwrap_or_default(),
token_usage: resp.usage.map(Into::into),
can_append: true,
}));
}
Err(err) => {
@@ -290,6 +292,7 @@ pub fn process_responses_event(
return Ok(Some(ResponseEvent::Completed {
response_id: String::new(),
token_usage: None,
can_append: true,
}));
}
"response.output_item.added" => {
@@ -548,9 +551,11 @@ mod tests {
Ok(ResponseEvent::Completed {
response_id,
token_usage,
can_append,
}) => {
assert_eq!(response_id, "resp1");
assert!(token_usage.is_none());
assert!(!can_append);
}
other => panic!("unexpected third event: {other:?}"),
}
@@ -585,7 +590,7 @@ mod tests {
}
#[tokio::test]
async fn response_done_emits_completed() {
async fn response_done_emits_incremental_completed() {
let done = json!({
"type": "response.done",
"response": {
@@ -610,9 +615,11 @@ mod tests {
Ok(ResponseEvent::Completed {
response_id,
token_usage,
can_append,
}) => {
assert_eq!(response_id, "");
assert!(token_usage.is_some());
assert!(*can_append);
}
other => panic!("unexpected event: {other:?}"),
}
@@ -635,9 +642,11 @@ mod tests {
Ok(ResponseEvent::Completed {
response_id,
token_usage,
can_append,
}) => {
assert_eq!(response_id, "");
assert!(token_usage.is_none());
assert!(*can_append);
}
other => panic!("unexpected event: {other:?}"),
}
@@ -673,9 +682,11 @@ mod tests {
Ok(ResponseEvent::Completed {
response_id,
token_usage,
can_append,
}) => {
assert_eq!(response_id, "resp1");
assert!(token_usage.is_none());
assert!(!can_append);
}
other => panic!("unexpected event: {other:?}"),
}