mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 06:16:37 +00:00
fix(cliproxy): preserve manual quota pauses
This commit is contained in:
committed by
Tam Nhu Tran
parent
62a4d44b58
commit
6ecca9b16f
@@ -21,6 +21,7 @@ import {
|
||||
restoreExpiredQuotaPauses,
|
||||
} from '../../accounts/account-safety';
|
||||
import { sanitizeEmail } from '../../auth/auth-utils';
|
||||
import { pauseAccount } from '../registry';
|
||||
|
||||
// Setup test isolation
|
||||
let tmpDir: string;
|
||||
@@ -1228,6 +1229,65 @@ describe('Quota Exhaustion Handlers', () => {
|
||||
expect(fs.existsSync(path.join(tmpDir, '.ccs', 'cliproxy', 'quota-paused.json'))).toBe(false);
|
||||
});
|
||||
|
||||
it('does not auto-resume when a user manually re-pauses a quota-paused account', async () => {
|
||||
writeRegistry({
|
||||
agy: {
|
||||
default: 'cooldown@gmail.com',
|
||||
accounts: {
|
||||
'cooldown@gmail.com': {
|
||||
email: 'cooldown@gmail.com',
|
||||
tokenFile: 'agy-cooldown.json',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
writeAuthToken('agy-cooldown.json', {
|
||||
type: 'agy',
|
||||
email: 'cooldown@gmail.com',
|
||||
access_token: 'token',
|
||||
});
|
||||
|
||||
const now = Date.now();
|
||||
expect(pauseAccountForQuotaCooldown('agy', 'cooldown@gmail.com', 5, now)).toBe(true);
|
||||
|
||||
const registryPath = path.join(tmpDir, '.ccs', 'cliproxy', 'accounts.json');
|
||||
const quotaPausedPath = path.join(tmpDir, '.ccs', 'cliproxy', 'quota-paused.json');
|
||||
const originalPausedAt = '2026-01-01T00:00:00.000Z';
|
||||
const registry = JSON.parse(fs.readFileSync(registryPath, 'utf8')) as {
|
||||
providers: {
|
||||
agy: {
|
||||
accounts: Record<string, { paused?: boolean; pausedAt?: string }>;
|
||||
};
|
||||
};
|
||||
};
|
||||
const quotaPaused = JSON.parse(fs.readFileSync(quotaPausedPath, 'utf8')) as {
|
||||
entries: Array<{ pausedAt: string }>;
|
||||
};
|
||||
registry.providers.agy.accounts['cooldown@gmail.com'].pausedAt = originalPausedAt;
|
||||
quotaPaused.entries[0].pausedAt = originalPausedAt;
|
||||
fs.writeFileSync(registryPath, JSON.stringify(registry, null, 2));
|
||||
fs.writeFileSync(quotaPausedPath, JSON.stringify(quotaPaused, null, 2));
|
||||
|
||||
expect(pauseAccount('agy', 'cooldown@gmail.com')).toBe(true);
|
||||
|
||||
const refreshedRegistry = JSON.parse(
|
||||
fs.readFileSync(registryPath, 'utf8')
|
||||
) as typeof registry;
|
||||
expect(refreshedRegistry.providers.agy.accounts['cooldown@gmail.com'].pausedAt).not.toBe(
|
||||
originalPausedAt
|
||||
);
|
||||
|
||||
const resumed = restoreExpiredQuotaPauses(now + 6 * 60 * 1000);
|
||||
const { getAccount } = await import('../account-manager');
|
||||
|
||||
expect(resumed).toBe(0);
|
||||
expect(getAccount('agy', 'cooldown@gmail.com')?.paused).toBe(true);
|
||||
expect(
|
||||
fs.existsSync(path.join(tmpDir, '.ccs', 'cliproxy', 'auth-paused', 'agy-cooldown.json'))
|
||||
).toBe(true);
|
||||
expect(fs.existsSync(quotaPausedPath)).toBe(false);
|
||||
});
|
||||
|
||||
it('does not auto-resume quota-paused accounts when pausedAt metadata is missing', async () => {
|
||||
writeRegistry({
|
||||
agy: {
|
||||
|
||||
@@ -660,6 +660,10 @@ export function pauseAccount(provider: CLIProxyProvider, accountId: string): boo
|
||||
|
||||
const accountMeta = providerAccounts.accounts[accountId];
|
||||
if (accountMeta.paused) {
|
||||
// Treat an explicit pause request for an already paused account as a fresh
|
||||
// manual decision. This changes the pause metadata so quota cooldown
|
||||
// restore cannot later mistake the pause for its original auto-pause.
|
||||
accountMeta.pausedAt = new Date().toISOString();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1056,8 +1056,13 @@ export async function handlePauseAccount(args: string[]): Promise<void> {
|
||||
}
|
||||
|
||||
if (account.paused) {
|
||||
const refreshed = pauseAccount(provider, account.id);
|
||||
const refreshedAccount = refreshed ? findAccountByQuery(provider, account.id) : account;
|
||||
console.log(warn(`Account already paused: ${formatCliAccountLabel(account)}`));
|
||||
console.log(info(`Paused at: ${account.pausedAt || 'unknown'}`));
|
||||
if (refreshed) {
|
||||
console.log(info('Manual pause refreshed; account will stay out of quota rotation'));
|
||||
}
|
||||
console.log(info(`Paused at: ${refreshedAccount?.pausedAt || account.pausedAt || 'unknown'}`));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user