Skip to content

Commit d0dd26e

Browse files
fix(gpt-5.3-codex-spark): support tool call arguments in done event without deltas (#2558)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent ca0fac8 commit d0dd26e

5 files changed

Lines changed: 282 additions & 38 deletions

File tree

crates/forge_domain/src/retry_config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl Default for RetryConfig {
4242
min_delay_ms: 1000,
4343
backoff_factor: 2,
4444
max_retry_attempts: 8,
45-
retry_status_codes: vec![429, 500, 502, 503, 504, 408, 522],
45+
retry_status_codes: vec![429, 500, 502, 503, 504, 408, 522, 520],
4646
max_delay: None,
4747
suppress_retry_errors: false,
4848
}
@@ -71,7 +71,7 @@ mod tests {
7171
assert_eq!(config.max_retry_attempts, 8);
7272
assert_eq!(
7373
config.retry_status_codes,
74-
vec![429, 500, 502, 503, 504, 408, 522]
74+
vec![429, 500, 502, 503, 504, 408, 522, 520]
7575
);
7676
assert_eq!(config.suppress_retry_errors, false);
7777
}

crates/forge_infra/src/http.rs

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ fn to_reqwest_tls(tls: TlsVersion) -> reqwest::tls::Version {
3333
}
3434
}
3535

36-
impl<F> ForgeHttpInfra<F> {
36+
impl<F: forge_app::FileWriterInfra + 'static> ForgeHttpInfra<F> {
3737
pub fn new(env: Environment, file_writer: Arc<F>) -> Self {
3838
let env = env.clone();
3939
let env_http = env.clone();
@@ -118,6 +118,8 @@ impl<F> ForgeHttpInfra<F> {
118118
let mut request_headers = self.headers(headers);
119119
request_headers.insert("Content-Type", HeaderValue::from_static("application/json"));
120120

121+
self.write_debug_request(&body);
122+
121123
self.execute_request("POST", url, |client| {
122124
client.post(url.clone()).headers(request_headers).body(body)
123125
})
@@ -202,6 +204,17 @@ impl<F> ForgeHttpInfra<F> {
202204
}
203205

204206
impl<F: forge_app::FileWriterInfra + 'static> ForgeHttpInfra<F> {
207+
fn write_debug_request(&self, body: &Bytes) {
208+
if let Some(debug_path) = &self.env.debug_requests {
209+
let file_writer = self.file.clone();
210+
let body_clone = body.clone();
211+
let debug_path = debug_path.clone();
212+
tokio::spawn(async move {
213+
let _ = file_writer.write(&debug_path, body_clone).await;
214+
});
215+
}
216+
}
217+
205218
async fn eventsource(
206219
&self,
207220
url: &Url,
@@ -211,15 +224,7 @@ impl<F: forge_app::FileWriterInfra + 'static> ForgeHttpInfra<F> {
211224
let mut request_headers = self.headers(headers);
212225
request_headers.insert("Content-Type", HeaderValue::from_static("application/json"));
213226

214-
if let Some(debug_path) = &self.env.debug_requests {
215-
let file_writer = self.file.clone();
216-
let body_clone = body.clone();
217-
let debug_path = debug_path.clone();
218-
tokio::spawn(async move {
219-
// Use debug_path if parent dir can be created, otherwise use fallback
220-
let _ = file_writer.write(&debug_path, body_clone).await;
221-
});
222-
}
227+
self.write_debug_request(&body);
223228

224229
self.client
225230
.post(url.clone())
@@ -385,6 +390,53 @@ mod tests {
385390
assert_eq!(writes[0].1, body);
386391
}
387392

393+
#[tokio::test]
394+
async fn test_debug_requests_post_none_does_not_write() {
395+
let file_writer = MockFileWriter::new();
396+
let env = create_test_env(None);
397+
let http = ForgeHttpInfra::new(env, Arc::new(file_writer.clone()));
398+
399+
let body = Bytes::from("test request body");
400+
let url = Url::parse("http://127.0.0.1:9/responses").unwrap();
401+
402+
let _ = http.post(&url, None, body).await;
403+
404+
// Give async task time to complete
405+
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
406+
407+
let writes = file_writer.get_writes().await;
408+
assert_eq!(
409+
writes.len(),
410+
0,
411+
"No files should be written for POST when debug_requests is None"
412+
);
413+
}
414+
415+
#[tokio::test]
416+
async fn test_debug_requests_post_writes_body() {
417+
let file_writer = MockFileWriter::new();
418+
let debug_path = PathBuf::from("/tmp/forge-test/debug-post.json");
419+
let env = create_test_env(Some(debug_path.clone()));
420+
let http = ForgeHttpInfra::new(env, Arc::new(file_writer.clone()));
421+
422+
let body = Bytes::from("test request body");
423+
let url = Url::parse("http://127.0.0.1:9/responses").unwrap();
424+
425+
let _ = http.post(&url, None, body.clone()).await;
426+
427+
// Give async task time to complete
428+
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
429+
430+
let writes = file_writer.get_writes().await;
431+
assert_eq!(
432+
writes.len(),
433+
1,
434+
"Should write one file for POST when debug_requests is set"
435+
);
436+
assert_eq!(writes[0].0, debug_path);
437+
assert_eq!(writes[0].1, body);
438+
}
439+
388440
#[tokio::test]
389441
async fn test_debug_requests_fallback_on_dir_creation_failure() {
390442
let file_writer = MockFileWriter::new();

crates/forge_repo/src/provider/openai_responses/repository.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,7 @@ mod tests {
10221022

10231023
assert_eq!(
10241024
repo.retry_config.retry_status_codes,
1025-
vec![429, 500, 502, 503, 504, 408, 522]
1025+
vec![429, 500, 502, 503, 504, 408, 522, 520]
10261026
);
10271027
}
10281028

0 commit comments

Comments
 (0)