mirror of
https://github.com/openai/codex.git
synced 2026-11-08 20:40:33 +00:00
Preserve incomplete response output in failed inference traces (#58456)
## Why When a response fails with incomplete output, attempted tool calls can appear only in the terminal response payload. Failed inference traces previously omitted those items, losing evidence of the attempted call. ## What changed Retain output items marked `incomplete` on `ResponseIncompleteError` and include recognized items in failed inference traces, deduplicating by item ID. Keep these items out of streamed output, tool dispatch, and the continuation cache, and omit their payloads from the error's debug representation. ## Testing Add tests for retaining only incomplete output from terminal responses and recording attempted calls in failed traces without streaming them or creating tool calls. Cover unknown response item types being skipped. GitOrigin-RevId: 594f6a37a5af543694f19fcffe0c164cb2addb36
This commit is contained in:
committed by
copyberry
parent
26cc286314
commit
7656a23b8d
@@ -475,6 +475,15 @@ pub fn process_responses_event(
|
||||
.map(Into::into);
|
||||
return Err(ResponsesEventError::Api(ApiError::ResponseIncomplete(
|
||||
Box::new(ResponseIncompleteError {
|
||||
partial_output: response
|
||||
.and_then(|r| r.get("output")?.as_array())
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter(|item| {
|
||||
item.get("status").and_then(Value::as_str) == Some("incomplete")
|
||||
})
|
||||
.cloned()
|
||||
.collect(),
|
||||
reason: reason.to_string(),
|
||||
response_id,
|
||||
token_usage,
|
||||
@@ -1407,6 +1416,25 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn incomplete_response_retains_partial_output_on_the_error() {
|
||||
let call = json!({
|
||||
"type": "function_call", "status": "incomplete", "id": "fc_attempt",
|
||||
"call_id": "attempt", "name": "unknown", "arguments": "{}",
|
||||
});
|
||||
let terminal = json!({
|
||||
"type": "response.incomplete",
|
||||
"response": {
|
||||
"id": "resp_1", "incomplete_details": {"reason": "invalid_recipient"},
|
||||
"output": [{"type": "message", "status": "completed"}, call],
|
||||
}
|
||||
});
|
||||
let sse = format!("event: response.incomplete\ndata: {terminal}\n\n");
|
||||
let events = collect_events(&[sse.as_bytes()]).await;
|
||||
assert_matches!(events.as_slice(), [Err(ApiError::ResponseIncomplete(error))]
|
||||
if error.reason == "invalid_recipient" && error.partial_output == [call]);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn typed_errors_handle_missing_or_blank_message() {
|
||||
for (code, fallback) in [
|
||||
|
||||
Reference in New Issue
Block a user