mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-24 20:14:44 -07:00
fix(billing): fix overage strategy lifecycle and settings integration (#21236)
This commit is contained in:
@@ -229,14 +229,14 @@ describe('billing', () => {
|
||||
expect(isOverageEligibleModel('gemini-3.1-pro-preview')).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true for gemini-3.1-pro-preview-customtools', () => {
|
||||
it('should return false for gemini-3.1-pro-preview-customtools', () => {
|
||||
expect(isOverageEligibleModel('gemini-3.1-pro-preview-customtools')).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
it('should return false for gemini-3-flash-preview', () => {
|
||||
expect(isOverageEligibleModel('gemini-3-flash-preview')).toBe(false);
|
||||
it('should return true for gemini-3-flash-preview', () => {
|
||||
expect(isOverageEligibleModel('gemini-3-flash-preview')).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for gemini-2.5-pro', () => {
|
||||
|
||||
@@ -12,6 +12,7 @@ import type {
|
||||
import {
|
||||
PREVIEW_GEMINI_MODEL,
|
||||
PREVIEW_GEMINI_3_1_MODEL,
|
||||
PREVIEW_GEMINI_FLASH_MODEL,
|
||||
} from '../config/models.js';
|
||||
|
||||
/**
|
||||
@@ -32,6 +33,7 @@ export const G1_CREDIT_TYPE: CreditType = 'GOOGLE_ONE_AI';
|
||||
export const OVERAGE_ELIGIBLE_MODELS = new Set([
|
||||
PREVIEW_GEMINI_MODEL,
|
||||
PREVIEW_GEMINI_3_1_MODEL,
|
||||
PREVIEW_GEMINI_FLASH_MODEL,
|
||||
]);
|
||||
|
||||
/**
|
||||
|
||||
@@ -48,6 +48,7 @@ import {
|
||||
shouldAutoUseCredits,
|
||||
} from '../billing/billing.js';
|
||||
import { logBillingEvent, logInvalidChunk } from '../telemetry/loggers.js';
|
||||
import { coreEvents } from '../utils/events.js';
|
||||
import { CreditsUsedEvent } from '../telemetry/billingEvents.js';
|
||||
import {
|
||||
fromCountTokenResponse,
|
||||
@@ -100,6 +101,11 @@ export class CodeAssistServer implements ContentGenerator {
|
||||
const modelIsEligible = isOverageEligibleModel(req.model);
|
||||
const shouldEnableCredits = modelIsEligible && autoUse;
|
||||
|
||||
if (shouldEnableCredits && !this.config?.getCreditsNotificationShown()) {
|
||||
this.config?.setCreditsNotificationShown(true);
|
||||
coreEvents.emitFeedback('info', 'Using AI Credits for this request.');
|
||||
}
|
||||
|
||||
const enabledCreditTypes = shouldEnableCredits
|
||||
? ([G1_CREDIT_TYPE] as string[])
|
||||
: undefined;
|
||||
|
||||
@@ -2426,6 +2426,65 @@ describe('Availability Service Integration', () => {
|
||||
config.resetTurn();
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('resetTurn does NOT reset billing state', () => {
|
||||
const config = new Config({
|
||||
...baseParams,
|
||||
billing: { overageStrategy: 'ask' },
|
||||
});
|
||||
|
||||
// Simulate accepting credits mid-turn
|
||||
config.setOverageStrategy('always');
|
||||
config.setCreditsNotificationShown(true);
|
||||
|
||||
// resetTurn should leave billing state intact
|
||||
config.resetTurn();
|
||||
expect(config.getBillingSettings().overageStrategy).toBe('always');
|
||||
expect(config.getCreditsNotificationShown()).toBe(true);
|
||||
});
|
||||
|
||||
it('resetBillingTurnState resets overageStrategy to configured value', () => {
|
||||
const config = new Config({
|
||||
...baseParams,
|
||||
billing: { overageStrategy: 'ask' },
|
||||
});
|
||||
|
||||
config.setOverageStrategy('always');
|
||||
expect(config.getBillingSettings().overageStrategy).toBe('always');
|
||||
|
||||
config.resetBillingTurnState('ask');
|
||||
expect(config.getBillingSettings().overageStrategy).toBe('ask');
|
||||
});
|
||||
|
||||
it('resetBillingTurnState preserves overageStrategy when configured as always', () => {
|
||||
const config = new Config({
|
||||
...baseParams,
|
||||
billing: { overageStrategy: 'always' },
|
||||
});
|
||||
|
||||
config.resetBillingTurnState('always');
|
||||
expect(config.getBillingSettings().overageStrategy).toBe('always');
|
||||
});
|
||||
|
||||
it('resetBillingTurnState defaults to ask when no strategy provided', () => {
|
||||
const config = new Config({
|
||||
...baseParams,
|
||||
billing: { overageStrategy: 'always' },
|
||||
});
|
||||
|
||||
config.resetBillingTurnState();
|
||||
expect(config.getBillingSettings().overageStrategy).toBe('ask');
|
||||
});
|
||||
|
||||
it('resetBillingTurnState resets creditsNotificationShown', () => {
|
||||
const config = new Config(baseParams);
|
||||
|
||||
config.setCreditsNotificationShown(true);
|
||||
expect(config.getCreditsNotificationShown()).toBe(true);
|
||||
|
||||
config.resetBillingTurnState();
|
||||
expect(config.getCreditsNotificationShown()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Hooks configuration', () => {
|
||||
|
||||
@@ -685,6 +685,7 @@ export class Config implements McpContext {
|
||||
fallbackModelHandler?: FallbackModelHandler;
|
||||
validationHandler?: ValidationHandler;
|
||||
private quotaErrorOccurred: boolean = false;
|
||||
private creditsNotificationShown: boolean = false;
|
||||
private modelQuotas: Map<
|
||||
string,
|
||||
{ remaining: number; limit: number; resetTime?: string }
|
||||
@@ -1454,6 +1455,12 @@ export class Config implements McpContext {
|
||||
this.modelAvailabilityService.resetTurn();
|
||||
}
|
||||
|
||||
/** Resets billing state (overageStrategy, creditsNotificationShown) once per user prompt. */
|
||||
resetBillingTurnState(overageStrategy?: OverageStrategy): void {
|
||||
this.creditsNotificationShown = false;
|
||||
this.billing.overageStrategy = overageStrategy ?? 'ask';
|
||||
}
|
||||
|
||||
getMaxSessionTurns(): number {
|
||||
return this.maxSessionTurns;
|
||||
}
|
||||
@@ -1466,6 +1473,14 @@ export class Config implements McpContext {
|
||||
return this.quotaErrorOccurred;
|
||||
}
|
||||
|
||||
setCreditsNotificationShown(value: boolean): void {
|
||||
this.creditsNotificationShown = value;
|
||||
}
|
||||
|
||||
getCreditsNotificationShown(): boolean {
|
||||
return this.creditsNotificationShown;
|
||||
}
|
||||
|
||||
setQuota(
|
||||
remaining: number | undefined,
|
||||
limit: number | undefined,
|
||||
|
||||
Reference in New Issue
Block a user