Download packages/core/src/billing/billing.ts from SaylorTwift/gemini-cli: direct link, hf CLI and curl.
- Browser
- Download file 5.52 kB
-
https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/core/src/billing/billing.ts
- Command line
-
hf download hf://SaylorTwift/gemini-cli/packages/core/src/billing/billing.ts
-
curl -L -o billing.ts https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/core/src/billing/billing.ts
5.52 kB
| /** | |
| * @license | |
| * Copyright 2026 Google LLC | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| import type { | |
| AvailableCredits, | |
| CreditType, | |
| GeminiUserTier, | |
| } from '../code_assist/types.js'; | |
| import { | |
| PREVIEW_GEMINI_MODEL, | |
| PREVIEW_GEMINI_3_1_MODEL, | |
| PREVIEW_GEMINI_FLASH_MODEL, | |
| } from '../config/models.js'; | |
| /** | |
| * Strategy for handling quota exhaustion when AI credits are available. | |
| * - 'ask': Prompt the user each time | |
| * - 'always': Automatically use credits | |
| * - 'never': Never use credits, show standard fallback | |
| */ | |
| export type OverageStrategy = 'ask' | 'always' | 'never'; | |
| /** Credit type for Google One AI credits */ | |
| export const G1_CREDIT_TYPE: CreditType = 'GOOGLE_ONE_AI'; | |
| /** | |
| * The set of models that support AI credits overage billing. | |
| * Only these models are eligible for the credits-based retry flow. | |
| */ | |
| export const OVERAGE_ELIGIBLE_MODELS = new Set([ | |
| PREVIEW_GEMINI_MODEL, | |
| PREVIEW_GEMINI_3_1_MODEL, | |
| PREVIEW_GEMINI_FLASH_MODEL, | |
| ]); | |
| /** | |
| * Checks if a model is eligible for AI credits overage billing. | |
| * @param model The model name to check. | |
| * @returns true if the model supports credits overage, false otherwise. | |
| */ | |
| export function isOverageEligibleModel(model: string): boolean { | |
| return OVERAGE_ELIGIBLE_MODELS.has(model); | |
| } | |
| /** Base URL for Google One AI page */ | |
| const G1_AI_BASE_URL = 'https://one.google.com/ai'; | |
| /** AccountChooser URL for redirecting with email context */ | |
| const ACCOUNT_CHOOSER_URL = 'https://accounts.google.com/AccountChooser'; | |
| /** UTM parameters for CLI tracking */ | |
| const UTM_SOURCE = 'gemini_cli'; | |
| // TODO: change to 'desktop' when G1 service fix is rolled out | |
| const UTM_MEDIUM = 'web'; | |
| /** | |
| * Wraps a URL in the AccountChooser redirect to maintain user context. | |
| * @param email User's email address for account selection | |
| * @param continueUrl The destination URL after account selection | |
| * @returns The full AccountChooser redirect URL | |
| */ | |
| export function wrapInAccountChooser( | |
| email: string, | |
| continueUrl: string, | |
| ): string { | |
| const params = new URLSearchParams({ | |
| Email: email, | |
| continue: continueUrl, | |
| }); | |
| return `${ACCOUNT_CHOOSER_URL}?${params.toString()}`; | |
| } | |
| /** | |
| * UTM campaign identifiers per the design doc. | |
| */ | |
| export const G1_UTM_CAMPAIGNS = { | |
| /** From Interception Flow "Manage" link (user has credits) */ | |
| MANAGE_ACTIVITY: 'hydrogen_cli_settings_ai_credits_activity_page', | |
| /** From "Manage" to add more credits */ | |
| MANAGE_ADD_CREDITS: 'hydrogen_cli_settings_add_credits', | |
| /** From Empty Wallet Flow "Get AI Credits" link */ | |
| EMPTY_WALLET_ADD_CREDITS: 'hydrogen_cli_insufficient_credits_add_credits', | |
| } as const; | |
| /** | |
| * Builds a G1 AI URL with UTM tracking parameters. | |
| * @param path The path segment (e.g., 'activity' or 'credits') | |
| * @param email User's email for AccountChooser wrapper | |
| * @param campaign The UTM campaign identifier | |
| * @returns The complete URL wrapped in AccountChooser | |
| */ | |
| export function buildG1Url( | |
| path: 'activity' | 'credits', | |
| email: string, | |
| campaign: string, | |
| ): string { | |
| const baseUrl = `${G1_AI_BASE_URL}/${path}`; | |
| const params = new URLSearchParams({ | |
| utm_source: UTM_SOURCE, | |
| utm_medium: UTM_MEDIUM, | |
| utm_campaign: campaign, | |
| }); | |
| const urlWithUtm = `${baseUrl}?${params.toString()}`; | |
| return wrapInAccountChooser(email, urlWithUtm); | |
| } | |
| /** | |
| * Extracts the G1 AI credit balance from a tier's available credits. | |
| * @param tier The user tier to check | |
| * @returns The credit amount as a number, 0 if eligible but empty, or null if not eligible | |
| */ | |
| export function getG1CreditBalance( | |
| tier: GeminiUserTier | null | undefined, | |
| ): number | null { | |
| if (!tier?.availableCredits) { | |
| return null; | |
| } | |
| const g1Credits = tier.availableCredits.filter( | |
| (credit: AvailableCredits) => credit.creditType === G1_CREDIT_TYPE, | |
| ); | |
| if (g1Credits.length === 0) { | |
| return null; | |
| } | |
| // creditAmount is an int64 represented as string; sum all matching entries | |
| return g1Credits.reduce((sum, credit) => { | |
| const amount = parseInt(credit.creditAmount ?? '0', 10); | |
| return sum + (isNaN(amount) ? 0 : amount); | |
| }, 0); | |
| } | |
| export const MIN_CREDIT_BALANCE = 50; | |
| /** | |
| * Determines if credits should be automatically used based on the overage strategy. | |
| * @param strategy The configured overage strategy | |
| * @param creditBalance The available credit balance | |
| * @returns true if credits should be auto-used, false otherwise | |
| */ | |
| export function shouldAutoUseCredits( | |
| strategy: OverageStrategy, | |
| creditBalance: number | null, | |
| ): boolean { | |
| return ( | |
| strategy === 'always' && | |
| creditBalance != null && | |
| creditBalance >= MIN_CREDIT_BALANCE | |
| ); | |
| } | |
| /** | |
| * Determines if the overage menu should be shown based on the strategy. | |
| * @param strategy The configured overage strategy | |
| * @param creditBalance The available credit balance | |
| * @returns true if the menu should be shown | |
| */ | |
| export function shouldShowOverageMenu( | |
| strategy: OverageStrategy, | |
| creditBalance: number | null, | |
| ): boolean { | |
| return ( | |
| strategy === 'ask' && | |
| creditBalance != null && | |
| creditBalance >= MIN_CREDIT_BALANCE | |
| ); | |
| } | |
| /** | |
| * Determines if the empty wallet menu should be shown. | |
| * @param strategy The configured overage strategy | |
| * @param creditBalance The available credit balance | |
| * @returns true if the empty wallet menu should be shown | |
| */ | |
| export function shouldShowEmptyWalletMenu( | |
| strategy: OverageStrategy, | |
| creditBalance: number | null, | |
| ): boolean { | |
| return ( | |
| strategy !== 'never' && | |
| creditBalance != null && | |
| creditBalance < MIN_CREDIT_BALANCE | |
| ); | |
| } | |