@@ -1323,7 +1323,28 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio
13231323 } )
13241324
13251325 if ( ! res . ok ) {
1326- throw new Error ( `Resume request failed (${ res . status } )` )
1326+ // Attach status and classify permanent failures
1327+ const err : any = new Error ( `Resume request failed (${ res . status } )` )
1328+ err . status = res . status
1329+
1330+ // 401/403 are permanent for the current request - emit failed and stop
1331+ if ( res . status === 401 || res . status === 403 ) {
1332+ yield {
1333+ type : "status" ,
1334+ mode : "background" ,
1335+ status : "failed" ,
1336+ responseId,
1337+ }
1338+ throw createTerminalBackgroundError ( `Resume unauthorized/forbidden (${ res . status } )` )
1339+ }
1340+
1341+ // Other statuses (e.g., 404/429/5xx) are treated as transient; log and retry with backoff
1342+ console . warn ?.( "[openai-native] resume attempt failed" , {
1343+ attempt,
1344+ status : res . status ,
1345+ responseId,
1346+ } )
1347+ throw err
13271348 }
13281349 if ( ! res . body ) {
13291350 throw new Error ( "Resume request failed (no body)" )
@@ -1358,10 +1379,24 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio
13581379 } catch ( err ) {
13591380 // If terminal error, don't keep retrying resume; fall back to polling immediately
13601381 const delay = resumeBaseDelayMs * Math . pow ( 2 , attempt )
1382+
13611383 if ( isTerminalBackgroundError ( err ) ) {
1384+ console . warn ?.( "[openai-native] resume terminated" , {
1385+ attempt,
1386+ responseId,
1387+ error : ( err as any ) ?. message ,
1388+ } )
13621389 break
13631390 }
1364- // Otherwise retry with backoff
1391+
1392+ // Otherwise retry with backoff and lightweight logging for diagnostics
1393+ console . warn ?.( "[openai-native] resume retry" , {
1394+ attempt,
1395+ responseId,
1396+ error : ( err as any ) ?. message ,
1397+ nextDelayMs : delay ,
1398+ } )
1399+
13651400 if ( delay > 0 ) {
13661401 await new Promise ( ( r ) => setTimeout ( r , delay ) )
13671402 }
@@ -1392,7 +1427,23 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio
13921427 } )
13931428
13941429 if ( ! pollRes . ok ) {
1395- // transient; wait and retry
1430+ // Treat auth/permission as permanent; others as transient with logging
1431+ if ( pollRes . status === 401 || pollRes . status === 403 ) {
1432+ yield {
1433+ type : "status" ,
1434+ mode : "background" ,
1435+ status : "failed" ,
1436+ responseId,
1437+ }
1438+ throw createTerminalBackgroundError (
1439+ `Polling unauthorized/forbidden (${ pollRes . status } ) for ${ responseId } ` ,
1440+ )
1441+ }
1442+
1443+ console . warn ?.( "[openai-native] polling non-OK response" , {
1444+ status : pollRes . status ,
1445+ responseId,
1446+ } )
13961447 await new Promise ( ( r ) => setTimeout ( r , pollIntervalMs ) )
13971448 continue
13981449 }
0 commit comments