Skip restored token usage replay for exec resumes (#35621)

## What changed

Set `excludeTurns` on `codex exec` thread resume requests so the app server
does not return reconstructed turns or replay their restored token usage.

## Testing

Extend the `resume --last` integration test to verify that resuming a session
emits only the live turn's `thread/tokenUsage/updated` event.

GitOrigin-RevId: 3347071142e7453ea9e3ac9ac292aa5384d98430
This commit is contained in:
Charlie Marsh
2026-07-27 14:12:50 +00:00
committed by copyberry
parent fbe65995bb
commit fea2d8b18f
2 changed files with 27 additions and 4 deletions
+1
View File
@@ -1115,6 +1115,7 @@ fn thread_resume_params_from_config(
sandbox: sandbox.flatten(),
permissions,
config: thread_config_overrides_from_config(config),
exclude_turns: true,
..ThreadResumeParams::default()
}
}
+26 -4
View File
@@ -133,7 +133,18 @@ async fn exec_resume_last_appends_to_existing_file() -> anyhow::Result<()> {
let test = test_codex_exec();
let server = MockServer::start().await;
let _response_mock = mount_exec_responses(&server, /*count*/ 2).await;
let _response_mock = responses::mount_sse_sequence(
&server,
vec![
responses::sse(vec![
responses::ev_response_created("resp-exec-0"),
responses::ev_assistant_message("msg-exec-0", "exec response"),
responses::ev_completed_with_tokens("resp-exec-0", /*total_tokens*/ 7),
]),
exec_sse_response(/*index*/ 1),
],
)
.await;
let repo_root = exec_repo_root()?;
// 1) First run: create a session with a unique marker in the content.
@@ -157,15 +168,26 @@ async fn exec_resume_last_appends_to_existing_file() -> anyhow::Result<()> {
let marker2 = format!("resume-last-2-{}", Uuid::new_v4());
let prompt2 = format!("echo {marker2}");
test.cmd_with_server(&server)
let output = test
.cmd_with_server(&server)
.env("RUST_LOG", "codex_app_server::outgoing_message=trace")
.arg("--skip-git-repo-check")
.arg("-C")
.arg(&repo_root)
.arg(&prompt2)
.arg("resume")
.arg("--last")
.assert()
.success();
.output()
.context("resume run should succeed")?;
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(output.status.success(), "resume failed: {stderr}");
assert_eq!(
stderr
.matches("app-server event: thread/tokenUsage/updated")
.count(),
1,
"resume should not replay restored token usage: {stderr}"
);
// Ensure the same file was updated and contains both markers.
let resumed_path = find_session_file_containing_marker(&sessions_dir, &marker2)