mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-02 06:20:04 +00:00
fix(codex): infer code review cadence from reset window
This commit is contained in:
@@ -103,20 +103,46 @@ function getCodexWindowKind(label: string): CodexWindowKind {
|
|||||||
return 'unknown';
|
return 'unknown';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCodexWindowDisplayLabel(label: string): string {
|
function getCodexWindowCadence(
|
||||||
switch (getCodexWindowKind(label)) {
|
resetAfterSeconds: number | null | undefined
|
||||||
|
): '5h' | 'weekly' | null {
|
||||||
|
if (
|
||||||
|
typeof resetAfterSeconds !== 'number' ||
|
||||||
|
!isFinite(resetAfterSeconds) ||
|
||||||
|
resetAfterSeconds <= 0
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resetAfterSeconds <= 6 * 60 * 60) return '5h';
|
||||||
|
if (resetAfterSeconds >= 24 * 60 * 60) return 'weekly';
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCodexWindowDisplayLabel(
|
||||||
|
window: Pick<CodexQuotaResult['windows'][number], 'label' | 'resetAfterSeconds'>
|
||||||
|
): string {
|
||||||
|
const cadence = getCodexWindowCadence(window.resetAfterSeconds);
|
||||||
|
|
||||||
|
switch (getCodexWindowKind(window.label)) {
|
||||||
case 'usage-5h':
|
case 'usage-5h':
|
||||||
|
if (cadence === 'weekly') return 'Weekly usage limit';
|
||||||
return '5h usage limit';
|
return '5h usage limit';
|
||||||
case 'usage-weekly':
|
case 'usage-weekly':
|
||||||
|
if (cadence === '5h') return '5h usage limit';
|
||||||
return 'Weekly usage limit';
|
return 'Weekly usage limit';
|
||||||
case 'code-review-5h':
|
case 'code-review-5h':
|
||||||
|
if (cadence === 'weekly') return 'Code review (weekly)';
|
||||||
return 'Code review (5h)';
|
return 'Code review (5h)';
|
||||||
case 'code-review-weekly':
|
case 'code-review-weekly':
|
||||||
|
if (cadence === '5h') return 'Code review (5h)';
|
||||||
return 'Code review (weekly)';
|
return 'Code review (weekly)';
|
||||||
case 'code-review':
|
case 'code-review':
|
||||||
|
if (cadence === '5h') return 'Code review (5h)';
|
||||||
|
if (cadence === 'weekly') return 'Code review (weekly)';
|
||||||
return 'Code review';
|
return 'Code review';
|
||||||
case 'unknown':
|
case 'unknown':
|
||||||
return label;
|
return window.label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +281,7 @@ function displayCodexQuotaSection(results: { account: string; quota: CodexQuotaR
|
|||||||
? dim(` Resets ${formatResetTime(window.resetAfterSeconds)}`)
|
? dim(` Resets ${formatResetTime(window.resetAfterSeconds)}`)
|
||||||
: '';
|
: '';
|
||||||
console.log(
|
console.log(
|
||||||
` ${getCodexWindowDisplayLabel(window.label).padEnd(24)} ${bar} ${window.remainingPercent.toFixed(0)}%${resetLabel}`
|
` ${getCodexWindowDisplayLabel(window).padEnd(24)} ${bar} ${window.remainingPercent.toFixed(0)}%${resetLabel}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
console.log('');
|
console.log('');
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export function QuotaTooltipContent({ quota, resetTime }: QuotaTooltipContentPro
|
|||||||
className="flex justify-between gap-4"
|
className="flex justify-between gap-4"
|
||||||
>
|
>
|
||||||
<span className={cn(w.remainingPercent < 20 && 'text-red-500')}>
|
<span className={cn(w.remainingPercent < 20 && 'text-red-500')}>
|
||||||
{getCodexWindowDisplayLabel(w.label)}
|
{getCodexWindowDisplayLabel(w)}
|
||||||
</span>
|
</span>
|
||||||
<span className="font-mono">{w.remainingPercent}%</span>
|
<span className="font-mono">{w.remainingPercent}%</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+31
-1
@@ -337,17 +337,47 @@ export function getCodexWindowKind(label: string): CodexWindowKind {
|
|||||||
/**
|
/**
|
||||||
* Convert raw Codex window labels into user-facing labels.
|
* Convert raw Codex window labels into user-facing labels.
|
||||||
*/
|
*/
|
||||||
export function getCodexWindowDisplayLabel(label: string): string {
|
function getCodexWindowCadence(
|
||||||
|
resetAfterSeconds: number | null | undefined
|
||||||
|
): '5h' | 'weekly' | null {
|
||||||
|
if (
|
||||||
|
typeof resetAfterSeconds !== 'number' ||
|
||||||
|
!isFinite(resetAfterSeconds) ||
|
||||||
|
resetAfterSeconds <= 0
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resetAfterSeconds <= 6 * 60 * 60) return '5h';
|
||||||
|
if (resetAfterSeconds >= 24 * 60 * 60) return 'weekly';
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCodexWindowDisplayLabel(
|
||||||
|
labelOrWindow: string | Pick<CodexQuotaWindow, 'label' | 'resetAfterSeconds'>,
|
||||||
|
resetAfterSecondsOverride?: number | null
|
||||||
|
): string {
|
||||||
|
const label = typeof labelOrWindow === 'string' ? labelOrWindow : labelOrWindow.label;
|
||||||
|
const cadence = getCodexWindowCadence(
|
||||||
|
typeof labelOrWindow === 'string' ? resetAfterSecondsOverride : labelOrWindow.resetAfterSeconds
|
||||||
|
);
|
||||||
|
|
||||||
switch (getCodexWindowKind(label)) {
|
switch (getCodexWindowKind(label)) {
|
||||||
case 'usage-5h':
|
case 'usage-5h':
|
||||||
|
if (cadence === 'weekly') return 'Weekly usage limit';
|
||||||
return '5h usage limit';
|
return '5h usage limit';
|
||||||
case 'usage-weekly':
|
case 'usage-weekly':
|
||||||
|
if (cadence === '5h') return '5h usage limit';
|
||||||
return 'Weekly usage limit';
|
return 'Weekly usage limit';
|
||||||
case 'code-review-5h':
|
case 'code-review-5h':
|
||||||
|
if (cadence === 'weekly') return 'Code review (weekly)';
|
||||||
return 'Code review (5h)';
|
return 'Code review (5h)';
|
||||||
case 'code-review-weekly':
|
case 'code-review-weekly':
|
||||||
|
if (cadence === '5h') return 'Code review (5h)';
|
||||||
return 'Code review (weekly)';
|
return 'Code review (weekly)';
|
||||||
case 'code-review':
|
case 'code-review':
|
||||||
|
if (cadence === '5h') return 'Code review (5h)';
|
||||||
|
if (cadence === 'weekly') return 'Code review (weekly)';
|
||||||
return 'Code review';
|
return 'Code review';
|
||||||
case 'unknown':
|
case 'unknown':
|
||||||
return label;
|
return label;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
getEarliestResetTime,
|
getEarliestResetTime,
|
||||||
getMinCodexQuota,
|
getMinCodexQuota,
|
||||||
getCodexResetTime,
|
getCodexResetTime,
|
||||||
|
getCodexWindowDisplayLabel,
|
||||||
getMinGeminiQuota,
|
getMinGeminiQuota,
|
||||||
getGeminiResetTime,
|
getGeminiResetTime,
|
||||||
getProviderMinQuota,
|
getProviderMinQuota,
|
||||||
@@ -526,6 +527,34 @@ describe('getCodexResetTime', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getCodexWindowDisplayLabel', () => {
|
||||||
|
it('labels code review primary window as weekly when reset cadence is weekly', () => {
|
||||||
|
expect(
|
||||||
|
getCodexWindowDisplayLabel({
|
||||||
|
label: 'Code Review (Primary)',
|
||||||
|
resetAfterSeconds: 604800,
|
||||||
|
})
|
||||||
|
).toBe('Code review (weekly)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('labels code review primary window as 5h when reset cadence is short', () => {
|
||||||
|
expect(
|
||||||
|
getCodexWindowDisplayLabel({
|
||||||
|
label: 'Code Review (Primary)',
|
||||||
|
resetAfterSeconds: 18000,
|
||||||
|
})
|
||||||
|
).toBe('Code review (5h)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('keeps secondary usage label as weekly by default', () => {
|
||||||
|
expect(getCodexWindowDisplayLabel('Secondary')).toBe('Weekly usage limit');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uses cadence override when provided with string label', () => {
|
||||||
|
expect(getCodexWindowDisplayLabel('Primary', 604800)).toBe('Weekly usage limit');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// ==================== Gemini Quota Functions ====================
|
// ==================== Gemini Quota Functions ====================
|
||||||
|
|
||||||
describe('getMinGeminiQuota', () => {
|
describe('getMinGeminiQuota', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user