mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-03 00:17:47 +00:00
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:
@@ -82,6 +82,20 @@ function getCodexWindowKind(label: string): CodexWindowKind {
|
|||||||
return 'unknown';
|
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.
|
* Build explicit 5h + weekly usage summary from raw Codex windows.
|
||||||
* Falls back to shortest/longest reset windows if API labels change.
|
* 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 data = (await response.json()) as CodexUsageResponse;
|
||||||
const windows = buildCodexQuotaWindows(data);
|
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);
|
const coreUsage = buildCodexCoreUsageSummary(windows);
|
||||||
|
|
||||||
// Extract plan type
|
// Extract plan type
|
||||||
@@ -475,4 +496,4 @@ export async function fetchAllCodexQuotas(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Export for testing
|
// Export for testing
|
||||||
export { readCodexAuthData, buildCodexQuotaWindows };
|
export { readCodexAuthData, buildCodexQuotaWindows, getUnknownCodexWindowLabels };
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { describe, it, expect } from 'bun:test';
|
|||||||
import {
|
import {
|
||||||
buildCodexQuotaWindows,
|
buildCodexQuotaWindows,
|
||||||
buildCodexCoreUsageSummary,
|
buildCodexCoreUsageSummary,
|
||||||
|
getUnknownCodexWindowLabels,
|
||||||
} from '../../../src/cliproxy/quota-fetcher-codex';
|
} from '../../../src/cliproxy/quota-fetcher-codex';
|
||||||
|
|
||||||
describe('Codex Quota Fetcher', () => {
|
describe('Codex Quota Fetcher', () => {
|
||||||
@@ -255,4 +256,55 @@ describe('Codex Quota Fetcher', () => {
|
|||||||
expect(summary.weekly).toBeNull();
|
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([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user