fix(cliproxy): log unknown codex quota window labels

- detect and de-duplicate unclassified quota window labels

- emit diagnostics in verbose/debug modes for API label drift

- add unit tests for unknown-label extraction behavior
This commit is contained in:
Tam Nhu Tran
2026-02-17 20:53:03 +07:00
parent 53e18d4c8d
commit 9031e5a085
2 changed files with 74 additions and 1 deletions
+22 -1
View File
@@ -82,6 +82,20 @@ function getCodexWindowKind(label: string): CodexWindowKind {
return 'unknown';
}
function getUnknownCodexWindowLabels(windows: CodexQuotaWindow[]): string[] {
const unknownLabels = windows
.filter((window) => getCodexWindowKind(window.label) === 'unknown')
.map((window) => window.label)
.filter((label): label is string => typeof label === 'string' && label.trim().length > 0);
return Array.from(new Set(unknownLabels));
}
function shouldLogCodexWindowWarnings(verbose: boolean): boolean {
if (verbose) return true;
const debugFlag = process.env['CCS_DEBUG'];
return debugFlag === '1' || debugFlag === 'true';
}
/**
* Build explicit 5h + weekly usage summary from raw Codex windows.
* Falls back to shortest/longest reset windows if API labels change.
@@ -388,6 +402,13 @@ export async function fetchCodexQuota(
const data = (await response.json()) as CodexUsageResponse;
const windows = buildCodexQuotaWindows(data);
const unknownWindowLabels = getUnknownCodexWindowLabels(windows);
if (unknownWindowLabels.length > 0 && shouldLogCodexWindowWarnings(verbose)) {
console.error(
`[!] Codex quota detected unknown window labels: ${unknownWindowLabels.join(', ')}`
);
console.error(' Window classification may need an update for upstream API changes.');
}
const coreUsage = buildCodexCoreUsageSummary(windows);
// Extract plan type
@@ -475,4 +496,4 @@ export async function fetchAllCodexQuotas(
}
// Export for testing
export { readCodexAuthData, buildCodexQuotaWindows };
export { readCodexAuthData, buildCodexQuotaWindows, getUnknownCodexWindowLabels };
@@ -8,6 +8,7 @@ import { describe, it, expect } from 'bun:test';
import {
buildCodexQuotaWindows,
buildCodexCoreUsageSummary,
getUnknownCodexWindowLabels,
} from '../../../src/cliproxy/quota-fetcher-codex';
describe('Codex Quota Fetcher', () => {
@@ -255,4 +256,55 @@ describe('Codex Quota Fetcher', () => {
expect(summary.weekly).toBeNull();
});
});
describe('getUnknownCodexWindowLabels', () => {
it('returns unknown labels and de-duplicates them', () => {
const labels = getUnknownCodexWindowLabels([
{
label: 'Window A',
usedPercent: 1,
remainingPercent: 99,
resetAfterSeconds: 10,
resetAt: null,
},
{
label: 'Window A',
usedPercent: 2,
remainingPercent: 98,
resetAfterSeconds: 20,
resetAt: null,
},
{
label: 'Primary',
usedPercent: 3,
remainingPercent: 97,
resetAfterSeconds: 30,
resetAt: null,
},
]);
expect(labels).toEqual(['Window A']);
});
it('returns empty array when all labels are recognized', () => {
const labels = getUnknownCodexWindowLabels([
{
label: 'Primary',
usedPercent: 10,
remainingPercent: 90,
resetAfterSeconds: 100,
resetAt: null,
},
{
label: 'Code Review (Secondary)',
usedPercent: 20,
remainingPercent: 80,
resetAfterSeconds: 200,
resetAt: null,
},
]);
expect(labels).toEqual([]);
});
});
});