fix(primer): refresh Codex usage before primer and allow 1% fresh accounts
Codex primer was skipping with no_eligible_accounts because it read a stale usage cache and required exactly 0% usage. Re-query usage right before the primer call and treat freshly-reset 0~1% accounts as eligible so the 5h window can be anchored at the fixed KST slot. Also hold new Codex-owner turns at fresh usage until the next primer slot. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
This commit is contained in:
77
src/usage-primer.test.ts
Normal file
77
src/usage-primer.test.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
const callOrder: string[] = [];
|
||||
|
||||
const refreshAllCodexAccountUsage = vi.fn(async () => {
|
||||
callOrder.push('refreshAll');
|
||||
return { rows: [], fetchedAt: '2026-06-01T00:00:00.000Z' };
|
||||
});
|
||||
const refreshActiveCodexUsage = vi.fn(async () => {
|
||||
callOrder.push('refreshActive');
|
||||
return { rows: [], fetchedAt: '2026-06-01T00:00:01.000Z' };
|
||||
});
|
||||
const runCodexWarmupCycle = vi.fn(async () => {
|
||||
callOrder.push('warmup');
|
||||
return { status: 'warmed', accountIndex: 0 };
|
||||
});
|
||||
|
||||
vi.mock('./config.js', () => ({
|
||||
CODEX_WARMUP_CONFIG: {
|
||||
enabled: false,
|
||||
prompt: 'Reply exactly OK. Do not run tools.',
|
||||
model: 'gpt-5.5',
|
||||
intervalMs: 300_000,
|
||||
minIntervalMs: 18_300_000,
|
||||
staggerMs: 1_800_000,
|
||||
maxUsagePct: 0,
|
||||
maxD7UsagePct: 0,
|
||||
commandTimeoutMs: 120_000,
|
||||
failureCooldownMs: 21_600_000,
|
||||
maxConsecutiveFailures: 2,
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('./logger.js', () => ({
|
||||
logger: {
|
||||
debug: vi.fn(),
|
||||
info: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('./token-rotation.js', () => ({
|
||||
getAllTokens: vi.fn(() => []),
|
||||
}));
|
||||
|
||||
vi.mock('./codex-usage-collector.js', () => ({
|
||||
refreshAllCodexAccountUsage,
|
||||
refreshActiveCodexUsage,
|
||||
}));
|
||||
|
||||
vi.mock('./codex-warmup.js', () => ({
|
||||
runCodexWarmupCycle,
|
||||
}));
|
||||
|
||||
describe('usage-primer', () => {
|
||||
it('refreshes Codex usage before primer selection and allows 1% fresh usage', async () => {
|
||||
callOrder.length = 0;
|
||||
refreshAllCodexAccountUsage.mockClear();
|
||||
refreshActiveCodexUsage.mockClear();
|
||||
runCodexWarmupCycle.mockClear();
|
||||
|
||||
const { runCodexPrimerCycle } = await import('./usage-primer.js');
|
||||
await runCodexPrimerCycle();
|
||||
|
||||
expect(callOrder).toEqual(['refreshAll', 'refreshActive', 'warmup']);
|
||||
expect(runCodexWarmupCycle).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
enabled: true,
|
||||
minIntervalMs: 18_000_000,
|
||||
maxUsagePct: 1,
|
||||
maxD7UsagePct: 100,
|
||||
}),
|
||||
{ ignoreZeroUsageWindow: true },
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user