@@ -221,8 +221,52 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio
221221 yield outChunk
222222 }
223223 }
224- } catch ( _sdkErr ) {
225- // Fallback to manual SSE via fetch to maintain functionality with custom base URLs or older SDKs
224+ } catch ( sdkErr : any ) {
225+ // Check if this is a 400 error about previous_response_id not found
226+ const errorMessage = sdkErr ?. message || sdkErr ?. error ?. message || ""
227+ const is400Error = sdkErr ?. status === 400 || sdkErr ?. response ?. status === 400
228+ const isPreviousResponseError =
229+ errorMessage . includes ( "Previous response" ) || errorMessage . includes ( "not found" )
230+
231+ if ( is400Error && requestBody . previous_response_id && isPreviousResponseError ) {
232+ // Log the error and retry without the previous_response_id
233+ console . warn (
234+ `[GPT-5] Previous response ID not found (${ requestBody . previous_response_id } ), retrying without it` ,
235+ )
236+
237+ // Remove the problematic previous_response_id and retry
238+ const retryRequestBody = { ...requestBody }
239+ delete retryRequestBody . previous_response_id
240+
241+ // Clear the stored lastResponseId to prevent using it again
242+ this . lastResponseId = undefined
243+
244+ try {
245+ // Retry with the SDK
246+ const retryStream = ( await ( this . client as any ) . responses . create (
247+ retryRequestBody ,
248+ ) ) as AsyncIterable < any >
249+
250+ if ( typeof ( retryStream as any ) [ Symbol . asyncIterator ] !== "function" ) {
251+ // If SDK fails, fall back to SSE
252+ yield * this . makeGpt5ResponsesAPIRequest ( retryRequestBody , model , metadata )
253+ return
254+ }
255+
256+ for await ( const event of retryStream ) {
257+ for await ( const outChunk of this . processGpt5Event ( event , model ) ) {
258+ yield outChunk
259+ }
260+ }
261+ return
262+ } catch ( retryErr ) {
263+ // If retry also fails, fall back to SSE
264+ yield * this . makeGpt5ResponsesAPIRequest ( retryRequestBody , model , metadata )
265+ return
266+ }
267+ }
268+
269+ // For other errors, fallback to manual SSE via fetch
226270 yield * this . makeGpt5ResponsesAPIRequest ( requestBody , model , metadata )
227271 }
228272 }
@@ -315,6 +359,48 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio
315359 errorDetails = errorText
316360 }
317361
362+ // Check if this is a 400 error about previous_response_id not found
363+ const isPreviousResponseError =
364+ errorDetails . includes ( "Previous response" ) || errorDetails . includes ( "not found" )
365+
366+ if ( response . status === 400 && requestBody . previous_response_id && isPreviousResponseError ) {
367+ // Log the error and retry without the previous_response_id
368+ console . warn (
369+ `[GPT-5 SSE] Previous response ID not found (${ requestBody . previous_response_id } ), retrying without it` ,
370+ )
371+
372+ // Remove the problematic previous_response_id and retry
373+ const retryRequestBody = { ...requestBody }
374+ delete retryRequestBody . previous_response_id
375+
376+ // Clear the stored lastResponseId to prevent using it again
377+ this . lastResponseId = undefined
378+
379+ // Retry the request without the previous_response_id
380+ const retryResponse = await fetch ( url , {
381+ method : "POST" ,
382+ headers : {
383+ "Content-Type" : "application/json" ,
384+ Authorization : `Bearer ${ apiKey } ` ,
385+ Accept : "text/event-stream" ,
386+ } ,
387+ body : JSON . stringify ( retryRequestBody ) ,
388+ } )
389+
390+ if ( ! retryResponse . ok ) {
391+ // If retry also fails, throw the original error
392+ throw new Error ( `GPT-5 API retry failed (${ retryResponse . status } )` )
393+ }
394+
395+ if ( ! retryResponse . body ) {
396+ throw new Error ( "No response body from Responses API retry" )
397+ }
398+
399+ // Handle the successful retry response
400+ yield * this . handleGpt5StreamResponse ( retryResponse . body , model )
401+ return
402+ }
403+
318404 // Provide user-friendly error messages based on status code
319405 switch ( response . status ) {
320406 case 400 :
0 commit comments