mirror of
https://github.com/openai/codex.git
synced 2026-10-28 18:58:46 +00:00
Account for token usage from incomplete responses (#53670)
## Why Terminal `response.incomplete` errors discard reported token usage. Counting that usage as a new context baseline can also double-count input and trigger unnecessary compaction on the next turn. ## What changed - Carry the response ID and valid reported usage with incomplete-response errors. - Record usage for sampling and foreground compaction in cumulative totals, rollout records, budgets, and token-usage contributors without replacing the context baseline. Preserve the original terminal error, including when accounting exhausts the budget or cancellation races the error. - Charge incomplete background compaction requests to the rollout budget without publishing foreground token usage. - Ignore missing or malformed usage rather than estimating it. ## Testing Extend coverage for SSE and WebSocket incomplete responses, rollout usage records, compaction accounting, deferred token-count events, and token-usage contributors. Add regressions for unnecessary compaction on the next turn and background compaction publishing foreground usage. GitOrigin-RevId: bf1ee6df3912052ab7c19e1c6af8ad3dc4b07675
This commit is contained in:
@@ -11,6 +11,7 @@ use crate::telemetry::SseTelemetry;
|
||||
use codex_client::ByteStream;
|
||||
use codex_client::StreamResponse;
|
||||
use codex_protocol::ResponseUsageMetadata;
|
||||
use codex_protocol::error::ResponseIncompleteError;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use codex_protocol::protocol::ModelVerification;
|
||||
use codex_protocol::protocol::TokenUsage;
|
||||
@@ -429,8 +430,23 @@ pub fn process_responses_event(
|
||||
return Err(ResponsesEventError::Api(ApiError::ContentFilter));
|
||||
}
|
||||
if reason != "interrupted" {
|
||||
let response = event.response.as_ref();
|
||||
let response_id = response
|
||||
.and_then(|response| response.get("id"))
|
||||
.and_then(Value::as_str)
|
||||
.map(str::to_owned);
|
||||
let token_usage = response
|
||||
.and_then(|response| response.get("usage"))
|
||||
.and_then(|usage| {
|
||||
serde_json::from_value::<ResponseCompletedUsage>(usage.clone()).ok()
|
||||
})
|
||||
.map(Into::into);
|
||||
return Err(ResponsesEventError::Api(ApiError::ResponseIncomplete(
|
||||
reason.to_string(),
|
||||
Box::new(ResponseIncompleteError {
|
||||
reason: reason.to_string(),
|
||||
response_id,
|
||||
token_usage,
|
||||
}),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user