diff --git a/src/backend/codex-stdio.ts b/src/backend/codex-stdio.ts index e7cca31..3ea5a8b 100644 --- a/src/backend/codex-stdio.ts +++ b/src/backend/codex-stdio.ts @@ -1213,9 +1213,9 @@ function classifyMessageFailureKind(message: string, fallback: FailureKind): Fai if (/invalid function arguments json string/u.test(text)) return "provider-invalid-tool-call"; if (/rate.?limit|too many requests|\b429\b/u.test(text)) return "provider-rate-limited"; if (/\b401\b|\b403\b|unauthori[sz]ed|forbidden|invalid api key|api key (?:is )?(?:required|missing)|authentication|auth failed|oauth|access token/u.test(text)) return "provider-auth-failed"; + if (isProviderUnavailableMessage(text)) return "provider-unavailable"; if (isProviderStreamDisconnectedMessage(text)) return "provider-stream-disconnected"; if (isProviderHttpErrorMessage(text)) return "provider-http-error"; - if (isProviderUnavailableMessage(text)) return "provider-unavailable"; if (/timed out|timeout|idle timeout/u.test(text)) return "backend-timeout"; if (/invalid json|json parse/u.test(text)) return "backend-json-parse-error"; return fallback; @@ -1238,7 +1238,6 @@ function isProviderHttpErrorMessage(text: string): boolean { function isProviderUnavailableMessage(text: string): boolean { if (/\b(?:http(?:\s+status)?|status(?:\s+code)?|code)\s*[:=]?\s*5\d\d\b/u.test(text)) return true; if (/\b5\d\d\b/u.test(text) && /service unavailable|bad gateway|gateway timeout|internal server error|provider|upstream|response\s*stream\s*disconnected|responsestreamdisconnected/u.test(text)) return true; - if (/response\s*stream\s*disconnected|responsestreamdisconnected|stream disconnected before completion/u.test(text)) return true; if (/connection refused|econnrefused|connection reset|websocket.*(?:refused|unavailable|closed)/u.test(text)) return true; if (/service unavailable|temporar(?:y|ily) unavailable|provider (?:is )?unavailable|provider availability|upstream (?:is )?unavailable/u.test(text)) return true; return false; diff --git a/src/selftest/cases/30-codex-stdio.ts b/src/selftest/cases/30-codex-stdio.ts index 135c78a..49a278f 100644 --- a/src/selftest/cases/30-codex-stdio.ts +++ b/src/selftest/cases/30-codex-stdio.ts @@ -229,10 +229,10 @@ const selfTest: SelfTestCase = async (context) => { await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-invalid-tool-call", expectedStatus: "failed", expectedFailureKind: "provider-invalid-tool-call" }); await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-compact-404-terminal", expectedStatus: "failed", expectedFailureKind: "provider-compact-unsupported" }); await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-stream-disconnected-rpc-error", expectedStatus: "failed", expectedFailureKind: "provider-stream-disconnected" }); - await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-503-rpc-error", expectedStatus: "failed", expectedFailureKind: "provider-stream-disconnected" }); - await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-503-terminal", expectedStatus: "failed", expectedFailureKind: "provider-http-error" }); + await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-503-rpc-error", expectedStatus: "failed", expectedFailureKind: "provider-unavailable" }); + await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-503-terminal", expectedStatus: "failed", expectedFailureKind: "provider-unavailable" }); await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-unavailable-terminal", expectedStatus: "failed", expectedFailureKind: "provider-unavailable" }); - await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-503-retry-event", expectedStatus: "failed", expectedFailureKind: "provider-stream-disconnected", expectRetryError: true }); + await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "provider-503-retry-event", expectedStatus: "failed", expectedFailureKind: "provider-unavailable", expectRetryError: true }); await runRetryThenCompletedCase({ client, managerUrl: server.baseUrl, context }); await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "invalid-json", expectedStatus: "failed", expectedFailureKind: "backend-json-parse-error" }); await runFailureCase({ client, managerUrl: server.baseUrl, context, mode: "missing-terminal", expectedStatus: "failed", expectedFailureKind: "backend-timeout", timeoutMs: 500 });