Skip to content

feat(billing): implement G1 AI credits overage flow with billing telemetry#18590

Merged
gsquared94 merged 3 commits intogoogle-gemini:mainfrom
gsquared94:g1-credits
Feb 27, 2026
Merged

feat(billing): implement G1 AI credits overage flow with billing telemetry#18590
gsquared94 merged 3 commits intogoogle-gemini:mainfrom
gsquared94:g1-credits

Conversation

@gsquared94
Copy link
Contributor

@gsquared94 gsquared94 commented Feb 9, 2026

Summary

Adds end-to-end support for Google One AI credits in quota exhaustion flows. When a user hits their free quota limit on an eligible model (Gemini 3 Pro Preview, 3.1 Pro Preview), they are offered the option to continue using their G1 AI credits, switch to a fallback model, or purchase more credits.

Related Issues

For https://github.com/google-gemini/maintainers-gemini-cli/issues/1227

How to Validate

Follow go/gemini-cli-x-ai-credits-integration-testing

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @gsquared94, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces comprehensive support for Google One AI Credits within the Gemini CLI. It enables users to seamlessly transition from free usage to paid credits when their quota is exhausted, enhancing the user experience by providing clear options and guidance. The changes encompass new backend logic for credit management, interactive user interface dialogs, updated statistics displays, and robust telemetry for tracking billing-related events, ensuring a smooth and configurable credit usage flow.

Highlights

  • Google One AI Credits Integration: The Gemini CLI now supports Google One AI Credits, allowing users to continue using models even after exhausting their free usage quota by leveraging their paid credits.
  • New Billing Infrastructure: A new core billing module has been introduced, featuring a strategy-based quota handling mechanism (OverageStrategy with 'ask', 'always', 'never' options), helper functions for credit balance and usage decisions, and URL builders for G1 credit purchase pages.
  • Interactive UI Dialogs: Two new UI dialogs, OverageMenuDialog and EmptyWalletDialog, are implemented to guide users when their quota is exhausted. The OverageMenuDialog appears when credits are available, offering options to use credits, manage them, switch authentication, or stop. The EmptyWalletDialog is shown when no credits are available, prompting users to purchase more.
  • Enhanced Stats Display: The /stats command has been updated to display the current AI Credit balance, providing users with immediate visibility into their credit status. The paidTier data is now exposed throughout the configuration layer to support this.
  • Intelligent Quota Interception: The useQuotaAndFallback.ts hook has been extended to intelligently intercept quota exhaustion based on the configured overageStrategy. It can automatically retry with credits ('always'), prompt the user ('ask'), or fall back to existing quota handling ('never').
  • Comprehensive Telemetry: New billing-related telemetry events have been added to track user interactions with the new credit system, including when overage/empty wallet menus are shown, options are selected, and credit purchases are initiated or credits are used.
  • Settings Configuration: A new billing.overageStrategy setting has been added to the CLI's settings schema, allowing users to configure their preferred behavior for handling quota overage with AI credits.
Changelog
  • package-lock.json
    • Removed 'peer: true' from several dependency entries, likely due to dependency updates or cleanup.
  • packages/cli/src/config/settingsSchema.ts
    • Added a new 'billing' section to the settings schema, including an 'overageStrategy' enum with 'ask', 'always', and 'never' options for AI credit usage.
  • packages/cli/src/test-utils/render.tsx
    • Added mock handlers for handleOverageMenuChoice and handleEmptyWalletChoice to the mockUIActions object for testing purposes.
  • packages/cli/src/ui/AppContainer.tsx
    • Imported GeminiUserTier type.
    • Introduced a new paidTier state to track user's paid tier information.
    • Updated the useQuotaAndFallback hook to pass paidTier and settings, and to receive new G1 AI Credits dialog requests and handlers.
    • Synchronized the paidTier state from the configuration when the user is authenticated.
    • Passed new G1 AI Credits dialog states and handlers to the DialogManager and UIActionsContext.
  • packages/cli/src/ui/commands/statsCommand.test.ts
    • Added creditBalance: 0 to the mock stats object.
    • Mocked the getUserPaidTier method in the config service.
  • packages/cli/src/ui/commands/statsCommand.ts
    • Imported getG1CreditBalance for calculating AI credit balance.
    • Modified getUserIdentity to retrieve the user's paidTier from the config and calculate the creditBalance.
    • Included creditBalance in the HistoryItemStats object for display.
  • packages/cli/src/ui/components/DialogManager.tsx
    • Imported the new OverageMenuDialog and EmptyWalletDialog components.
    • Added conditional rendering logic to display OverageMenuDialog or EmptyWalletDialog based on the uiState requests.
  • packages/cli/src/ui/components/EmptyWalletDialog.test.tsx
    • Added a new test file for the EmptyWalletDialog component.
    • Tests cover rendering with correct menu options, displaying zero credit balance, model name, purchase prompt, and optional reset time.
    • Includes tests for onChoice handling for 'get_credits', 'switch_auth', and 'stop' selections.
  • packages/cli/src/ui/components/EmptyWalletDialog.tsx
    • Added a new React component, EmptyWalletDialog, to inform users when their AI credit wallet is empty.
    • Provides options to 'Get AI Credits' (opens browser), 'Switch Auth', or 'Stop' the current request.
    • Displays the failed model and optional reset time.
  • packages/cli/src/ui/components/HistoryItemDisplay.tsx
    • Added the creditBalance prop to the StatsDisplay component to show AI credit information.
  • packages/cli/src/ui/components/OverageMenuDialog.test.tsx
    • Added a new test file for the OverageMenuDialog component.
    • Tests verify rendering with correct menu options, displaying credit balance, model name, and optional reset time.
    • Includes tests for onChoice handling for 'use_credits', 'manage', 'switch_auth', and 'stop' selections.
  • packages/cli/src/ui/components/OverageMenuDialog.tsx
    • Added a new React component, OverageMenuDialog, to prompt users when their quota is exhausted but AI credits are available.
    • Offers options to 'Use AI Credits', 'Manage' credits (opens browser), 'Switch Auth', or 'Stop' the current request.
    • Displays the failed model, available credit balance, and optional reset time.
  • packages/cli/src/ui/components/StatsDisplay.tsx
    • Added a creditBalance prop to the StatsDisplay component.
    • Implemented logic to display the AI Credits balance in the stats output, with different text colors based on whether credits are available.
  • packages/cli/src/ui/contexts/UIActionsContext.tsx
    • Added handleOverageMenuChoice and handleEmptyWalletChoice to the UIActions interface, defining new actions for the G1 AI Credits flow.
  • packages/cli/src/ui/contexts/UIStateContext.tsx
    • Defined new types: OverageMenuIntent, OverageMenuDialogRequest, EmptyWalletIntent, and EmptyWalletDialogRequest to manage the state of the new billing dialogs.
    • Added overageMenuRequest and emptyWalletRequest properties to the UIState interface to track pending dialog requests.
  • packages/cli/src/ui/hooks/useQuotaAndFallback.test.ts
    • Imported mockSettings and several billing utility functions and telemetry events.
    • Mocked billing utility functions (getG1CreditBalance, shouldAutoUseCredits, shouldShowOverageMenu, shouldShowEmptyWalletMenu, logBillingEvent).
    • Updated useQuotaAndFallback hook calls in tests to include paidTier and settings.
    • Added a new test suite for the 'G1 AI Credits Flow', covering scenarios for auto-using credits, showing the overage menu, and showing the empty wallet menu.
  • packages/cli/src/ui/hooks/useQuotaAndFallback.ts
    • Imported billing-related types, utility functions, and telemetry events.
    • Added paidTier and settings to the UseQuotaAndFallbackArgs interface.
    • Introduced overageMenuRequest and emptyWalletRequest states to manage the new dialogs.
    • Implemented the G1 Credits Flow logic within the fallbackHandler, which checks the overageStrategy, automatically uses credits, or displays the appropriate dialog (OverageMenuDialog or EmptyWalletDialog) and logs telemetry events.
    • Added handleOverageMenuChoice and handleEmptyWalletChoice callbacks to resolve dialog intents.
    • Updated useEffect dependencies to include new billing-related parameters.
  • packages/cli/src/ui/types.ts
    • Added an optional creditBalance property to the HistoryItemStats type to store AI credit information.
  • packages/core/src/billing/billing.test.ts
    • Added a new test file for the core billing utility functions.
    • Tests cover wrapInAccountChooser for URL redirection, buildG1Url for constructing G1 AI URLs with UTM parameters, getG1CreditBalance for extracting credit amounts, and shouldAutoUseCredits, shouldShowOverageMenu, shouldShowEmptyWalletMenu for strategy-based decision making.
  • packages/core/src/billing/billing.ts
    • Added a new module defining the OverageStrategy type ('ask', 'always', 'never').
    • Defined G1_CREDIT_TYPE constant.
    • Implemented wrapInAccountChooser and buildG1Url functions for handling Google Account Chooser and UTM tracking.
    • Provided getG1CreditBalance to extract AI credit balance from user tier data.
    • Added shouldAutoUseCredits, shouldShowOverageMenu, and shouldShowEmptyWalletMenu functions to determine appropriate UI/logic flow based on strategy and credit balance.
  • packages/core/src/billing/index.ts
    • Added a new index file to export all components from the new billing module.
  • packages/core/src/code_assist/codeAssist.ts
    • Updated the createCodeAssistContentGenerator function to pass paidTier and config objects to the CodeAssistServer constructor.
  • packages/core/src/code_assist/converter.ts
    • Imported the new Credits type.
    • Added enabled_credit_types to CAGenerateContentRequest to specify which credit types to use for a request.
    • Added consumed_credits and remaining_credits to CaGenerateContentResponse to report credit usage.
    • Updated toGenerateContentRequest to accept and pass enabledCreditTypes.
    • Added fromGenerateContentResponseUsage function to convert usage metadata.
  • packages/core/src/code_assist/server.ts
    • Imported Config, billing utility functions (G1_CREDIT_TYPE, getG1CreditBalance, shouldAutoUseCredits), and billing-related types (GeminiUserTier, Credits).
    • Added paidTier and config as readonly properties to the CodeAssistServer constructor.
    • Implemented logic in generateContentStream and generateContent to determine if credits should be enabled based on overageStrategy and paidTier, and passed enabledCreditTypes in the request.
    • Added a private updateCredits method to update the paidTier.availableCredits based on remaining_credits received in the response.
  • packages/core/src/code_assist/setup.ts
    • Added an optional paidTier property to the UserData interface.
    • Populated the paidTier property in the setupUser function when available from the load response.
  • packages/core/src/code_assist/types.ts
    • Defined new types: CreditType ('CREDIT_TYPE_UNSPECIFIED', 'GOOGLE_ONE_AI'), Credits (with credit_type and credit_amount), and aliases AvailableCredits, ConsumedCredits, RemainingCredits.
    • Added an optional availableCredits property to the GeminiUserTier interface to store AI credit information.
  • packages/core/src/config/config.ts
    • Imported OverageStrategy and GeminiUserTier types.
    • Added an optional billing property to the ConfigParameters interface.
    • Introduced a private billing object to store overage strategy and a transient useCreditsForNextRequest flag.
    • Initialized the billing configuration in the constructor.
    • Added new public methods: getUserPaidTier(), getBillingSettings(), setUseCreditsForNextRequest(), and shouldUseCreditsForNextRequest().
  • packages/core/src/core/client.ts
    • Added this.config.setUseCreditsForNextRequest(false); to reset the transient credit usage flag after a request turn is completed, ensuring it doesn't persist across unrelated requests.
  • packages/core/src/core/contentGenerator.ts
    • Imported GeminiUserTier type.
    • Added an optional paidTier property to the ContentGenerator interface.
  • packages/core/src/core/fakeContentGenerator.ts
    • Imported GeminiUserTier type.
    • Added an optional paidTier property to the FakeContentGenerator class.
  • packages/core/src/core/loggingContentGenerator.ts
    • Imported GeminiUserTier type.
    • Added a getter for the paidTier property to the LoggingContentGenerator class.
  • packages/core/src/fallback/handler.ts
    • Added a new case for retry_with_credits in the processIntent function, which sets the useCreditsForNextRequest flag in the configuration.
  • packages/core/src/fallback/types.ts
    • Added retry_with_credits to the FallbackIntent type, indicating an intent to retry a request using Google One AI credits.
  • packages/core/src/index.ts
    • Exported the new billing module.
    • Exported new telemetry billingEvents and the logBillingEvent function.
  • packages/core/src/telemetry/billingEvents.ts
    • Added a new module defining specific telemetry events for billing-related interactions.
    • Includes OverageMenuShownEvent, OverageOptionSelectedEvent, EmptyWalletMenuShownEvent, CreditPurchaseClickEvent, and CreditsUsedEvent with their respective attributes and log bodies.
  • packages/core/src/telemetry/index.ts
    • Exported the new billingEvents.ts module to make billing telemetry events accessible.
  • packages/core/src/telemetry/loggers.ts
    • Imported the BillingTelemetryEvent type.
    • Added a new logBillingEvent function to log billing-specific telemetry events.
Activity
  • Comprehensive unit tests were added for the new OverageMenuDialog and EmptyWalletDialog components, totaling approximately 380 lines of test code.
  • The useQuotaAndFallback hook received extended test coverage, with around 200 new lines of tests.
  • A new test suite for the core billing module was introduced, adding approximately 187 lines of tests to ensure the new credit management logic functions correctly.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive integration for Google One AI Credits into the Gemini CLI. The changes are well-structured, adding a new billing module, UI dialogs for overage and empty wallets, and updating the stats display. The core logic in useQuotaAndFallback correctly handles different credit usage strategies.

I've found one critical issue related to data flow that causes the UI to display a stale credit balance after credits are used. My review includes a detailed comment and a code suggestion to address this by implementing an event-based update mechanism.

@gsquared94 gsquared94 force-pushed the g1-credits branch 4 times, most recently from d406da0 to b55abd9 Compare February 10, 2026 02:01
@gemini-cli
Copy link
Contributor

gemini-cli bot commented Feb 10, 2026

Hi there! Thank you for your contribution to Gemini CLI.

To improve our contribution process and better track changes, we now require all pull requests to be associated with an existing issue, as announced in our recent discussion and as detailed in our CONTRIBUTING.md.

This pull request is being closed because it is not currently linked to an issue. Once you have updated the description of this PR to link an issue (e.g., by adding Fixes #123 or Related to #123), it will be automatically reopened.

How to link an issue:
Add a keyword followed by the issue number (e.g., Fixes #123) in the description of your pull request. For more details on supported keywords and how linking works, please refer to the GitHub Documentation on linking pull requests to issues.

Thank you for your understanding and for being a part of our community!

@gemini-cli gemini-cli bot closed this Feb 10, 2026
@srithreepo srithreepo reopened this Feb 12, 2026
@gsquared94 gsquared94 changed the title feat: expose paidTier data, add stats display, and integrate quota interception for G1 credits feat: G1 AI Credits Integration - Quota Interception, Stats Display, and Dialog Flows Feb 19, 2026
@gsquared94 gsquared94 force-pushed the g1-credits branch 4 times, most recently from 0c682da to 8759e36 Compare February 25, 2026 11:40
@gsquared94 gsquared94 changed the title feat: G1 AI Credits Integration - Quota Interception, Stats Display, and Dialog Flows feat(billing): implement G1 AI credits overage flow with billing telemetry Feb 25, 2026
@gsquared94 gsquared94 marked this pull request as ready for review February 25, 2026 14:09
@gsquared94 gsquared94 requested review from a team as code owners February 25, 2026 14:09
@gemini-cli gemini-cli bot added the status/need-issue Pull requests that need to have an associated issue. label Feb 25, 2026
@scidomino
Copy link
Collaborator

Gemini review says:

  1. Test Mocking Standards: The rules strictly require vi.restoreAllMocks() to be called in an afterEach hook to prevent test pollution.
    • In packages/cli/src/ui/components/OverageMenuDialog.test.tsx, they only use vi.clearAllMocks() in beforeEach and do not import or define an afterEach hook at all.
    • packages/cli/src/ui/hooks/useQuotaAndFallback.test.ts uses vi.clearAllMocks() instead of vi.restoreAllMocks() in its afterEach.
  2. React Component Testing (Snapshots): In OverageMenuDialog.test.tsx and EmptyWalletDialog.test.tsx, the author mocks the RadioButtonSelect component and asserts against the props passed to it. While this
    functionally tests the logic, it violates the spirit of the CLI UI rules ("Use toMatchSnapshot to verify that rendering works as expected"). In Ink CLI apps, we typically test the fully-rendered component via
    expect(lastFrame()).toMatchSnapshot() to prevent accidental styling/layout regressions.

@gsquared94
Copy link
Contributor Author

Gemini review says:

  1. Test Mocking Standards: The rules strictly require vi.restoreAllMocks() to be called in an afterEach hook to prevent test pollution.

    • In packages/cli/src/ui/components/OverageMenuDialog.test.tsx, they only use vi.clearAllMocks() in beforeEach and do not import or define an afterEach hook at all.
    • packages/cli/src/ui/hooks/useQuotaAndFallback.test.ts uses vi.clearAllMocks() instead of vi.restoreAllMocks() in its afterEach.
  2. React Component Testing (Snapshots): In OverageMenuDialog.test.tsx and EmptyWalletDialog.test.tsx, the author mocks the RadioButtonSelect component and asserts against the props passed to it. While this
    functionally tests the logic, it violates the spirit of the CLI UI rules ("Use toMatchSnapshot to verify that rendering works as expected"). In Ink CLI apps, we typically test the fully-rendered component via
    expect(lastFrame()).toMatchSnapshot() to prevent accidental styling/layout regressions.

Fixed.

@gsquared94 gsquared94 requested a review from scidomino February 27, 2026 15:51
Adds end-to-end support for Google One AI credits in quota exhaustion flows:

- New billing module (packages/core/src/billing/) with credit balance
  checking, overage strategy management, and G1 URL construction
- OverageMenuDialog and EmptyWalletDialog UI components for quota
  exhaustion with credit purchase options
- Credits flow handler extracted to creditsFlowHandler.ts with overage
  menu, empty wallet, and auto-use-credits logic
- Server-side credit tracking: enabledCreditTypes on requests,
  consumed/remaining credits from streaming responses
- Billing telemetry events (overage menu shown, option selected, credits
  used, credit purchase click, API key updated)
- OpenTelemetry metrics for overage option and credit purchase counters
- Credit balance display in /stats command with refresh support
- Settings: general.overageStrategy (ask/always/never) for credit usage
- Error handling: INSUFFICIENT_G1_CREDITS_BALANCE as terminal error
  regardless of domain field presence
- Persistent info message after
- OverageMenuDialog.test.tsx: add afterEach with vi.restoreAllMocks(),
  remove RadioButtonSelect mock, use renderWithProviders + toMatchSnapshot
  for rendering tests and keyboard input for handler tests
- EmptyWalletDialog.test.tsx: same treatment as OverageMenuDialog
- useQuotaAndFallback.test.ts: vi.clearAllMocks() → vi.restoreAllMocks()
  in afterEach to prevent test pollution
@gsquared94 gsquared94 enabled auto-merge February 27, 2026 17:56
@gsquared94 gsquared94 added this pull request to the merge queue Feb 27, 2026
Merged via the queue into google-gemini:main with commit b2d6844 Feb 27, 2026
26 of 27 checks passed
@gsquared94 gsquared94 deleted the g1-credits branch February 27, 2026 18:25
BryanBradfo pushed a commit to BryanBradfo/gemini-cli that referenced this pull request Mar 5, 2026
liamhelmer pushed a commit to badal-io/gemini-cli that referenced this pull request Mar 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status/need-issue Pull requests that need to have an associated issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants