fix: recover Codex rotation auth failures

- mark Codex bearer/refresh failures as terminal auth-expired states

- sync refreshed session auth back to rotation slots and revive refreshed dead_auth slots

- stop paired arbiter retry loops when Codex accounts are unavailable

- add regression coverage for rotation leases, follow-up suppression, and arbiter closure
This commit is contained in:
ejclaw
2026-06-02 00:21:16 +09:00
parent 1ff6b3434f
commit 03d4c81192
21 changed files with 1082 additions and 52 deletions

View File

@@ -19,6 +19,7 @@ import {
export interface StreamedTriggerReason {
reason: AgentTriggerReason;
retryAfterMs?: number;
message?: string;
}
export interface StreamedOutputState {
@@ -139,6 +140,28 @@ export function evaluateStreamedOutput(
nextState.sawSuccessNullResultWithoutOutput = true;
}
if (
isPrimaryCodex &&
typeof output.error === 'string' &&
output.error.length > 0 &&
!nextState.sawOutput &&
!nextState.streamedTriggerReason
) {
const trigger = detectCodexRotationTrigger(output.error);
if (trigger.shouldRotate) {
const newTrigger: StreamedTriggerReason = {
reason: trigger.reason,
message: output.error,
};
nextState.streamedTriggerReason = newTrigger;
return {
state: nextState,
shouldForwardOutput: !options.shortCircuitTriggeredErrors,
newTrigger,
};
}
}
if (
output.status === 'error' &&
!nextState.sawOutput &&
@@ -157,7 +180,7 @@ export function evaluateStreamedOutput(
} else if (isPrimaryCodex) {
const trigger = detectCodexRotationTrigger(output.error);
if (trigger.shouldRotate) {
newTrigger = { reason: trigger.reason };
newTrigger = { reason: trigger.reason, message: output.error };
}
}