mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-20 16:57:46 +00:00
This commit is contained in:
committed by
GitHub
parent
d820c2335b
commit
925d747b9d
@@ -16,18 +16,6 @@ export const validateAuthMethod = (authMethod: string): string | null => {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (authMethod === AuthType.LOGIN_WITH_GOOGLE_GCA) {
|
||||
if (!process.env['GOOGLE_CLOUD_PROJECT']) {
|
||||
return (
|
||||
'[Error] GOOGLE_CLOUD_PROJECT is not set.\n' +
|
||||
'Please set it using:\n' +
|
||||
' export GOOGLE_CLOUD_PROJECT=<your-project-id>\n' +
|
||||
'and try again.'
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (authMethod === AuthType.USE_GEMINI) {
|
||||
if (!process.env['GEMINI_API_KEY']) {
|
||||
return 'GEMINI_API_KEY environment variable not found. Add that to your environment and try again (no reload needed if using .env)!';
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
|
||||
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
|
||||
import { aboutCommand } from './aboutCommand.js';
|
||||
import type { CommandContext } from './types.js';
|
||||
import { type CommandContext } from './types.js';
|
||||
import { createMockCommandContext } from '../../test-utils/mockCommandContext.js';
|
||||
import * as versionUtils from '../../utils/version.js';
|
||||
import { MessageType } from '../types.js';
|
||||
|
||||
import type { IdeClient } from '@google/gemini-cli-core';
|
||||
import type { IdeClient } from '../../../../core/src/ide/ide-client.js';
|
||||
|
||||
vi.mock('../../utils/version.js', () => ({
|
||||
getCliVersion: vi.fn(),
|
||||
@@ -29,11 +29,10 @@ describe('aboutCommand', () => {
|
||||
getModel: vi.fn(),
|
||||
getIdeClient: vi.fn(),
|
||||
getIdeMode: vi.fn().mockReturnValue(true),
|
||||
getGeminiClient: vi.fn(),
|
||||
},
|
||||
settings: {
|
||||
merged: {
|
||||
selectedAuthType: 'oauth-gca',
|
||||
selectedAuthType: 'test-auth',
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -53,11 +52,6 @@ describe('aboutCommand', () => {
|
||||
vi.spyOn(mockContext.services.config!, 'getIdeClient').mockReturnValue({
|
||||
getDetectedIdeDisplayName: vi.fn().mockReturnValue('test-ide'),
|
||||
} as Partial<IdeClient> as IdeClient);
|
||||
vi.spyOn(mockContext.services.config!, 'getGeminiClient').mockReturnValue({
|
||||
getUserTier: vi.fn().mockReturnValue(undefined),
|
||||
} as unknown as ReturnType<
|
||||
NonNullable<typeof mockContext.services.config>['getGeminiClient']
|
||||
>);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -89,10 +83,9 @@ describe('aboutCommand', () => {
|
||||
osVersion: 'test-os',
|
||||
sandboxEnv: 'no sandbox',
|
||||
modelVersion: 'test-model',
|
||||
selectedAuthType: 'oauth-gca',
|
||||
selectedAuthType: 'test-auth',
|
||||
gcpProject: 'test-gcp-project',
|
||||
ideClient: 'test-ide',
|
||||
userTier: undefined,
|
||||
},
|
||||
expect.any(Number),
|
||||
);
|
||||
@@ -132,14 +125,11 @@ describe('aboutCommand', () => {
|
||||
});
|
||||
|
||||
it('should not show ide client when it is not detected', async () => {
|
||||
// Change to oauth type that doesn't use GCP project
|
||||
mockContext.services.settings.merged.selectedAuthType = 'oauth';
|
||||
|
||||
vi.spyOn(mockContext.services.config!, 'getIdeClient').mockReturnValue({
|
||||
getDetectedIdeDisplayName: vi.fn().mockReturnValue(undefined),
|
||||
} as Partial<IdeClient> as IdeClient);
|
||||
|
||||
process.env['SANDBOX'] = '';
|
||||
process.env.SANDBOX = '';
|
||||
if (!aboutCommand.action) {
|
||||
throw new Error('The about command must have an action.');
|
||||
}
|
||||
@@ -153,8 +143,8 @@ describe('aboutCommand', () => {
|
||||
osVersion: 'test-os',
|
||||
sandboxEnv: 'no sandbox',
|
||||
modelVersion: 'test-model',
|
||||
selectedAuthType: 'oauth',
|
||||
gcpProject: '',
|
||||
selectedAuthType: 'test-auth',
|
||||
gcpProject: 'test-gcp-project',
|
||||
ideClient: '',
|
||||
}),
|
||||
expect.any(Number),
|
||||
|
||||
@@ -28,18 +28,11 @@ export const aboutCommand: SlashCommand = {
|
||||
const cliVersion = await getCliVersion();
|
||||
const selectedAuthType =
|
||||
context.services.settings.merged.selectedAuthType || '';
|
||||
// Only show GCP Project for auth types that actually use it
|
||||
const gcpProject =
|
||||
selectedAuthType === 'oauth-gca' ||
|
||||
selectedAuthType === 'vertex-ai' ||
|
||||
selectedAuthType === 'cloud-shell'
|
||||
? process.env['GOOGLE_CLOUD_PROJECT'] || ''
|
||||
: '';
|
||||
const gcpProject = process.env['GOOGLE_CLOUD_PROJECT'] || '';
|
||||
const ideClient =
|
||||
(context.services.config?.getIdeMode() &&
|
||||
context.services.config?.getIdeClient()?.getDetectedIdeDisplayName()) ||
|
||||
'';
|
||||
const userTier = context.services.config?.getGeminiClient()?.getUserTier();
|
||||
|
||||
const aboutItem: Omit<HistoryItemAbout, 'id'> = {
|
||||
type: MessageType.ABOUT,
|
||||
@@ -50,7 +43,6 @@ export const aboutCommand: SlashCommand = {
|
||||
selectedAuthType,
|
||||
gcpProject,
|
||||
ideClient,
|
||||
userTier,
|
||||
};
|
||||
|
||||
context.ui.addItem(aboutItem, Date.now());
|
||||
|
||||
@@ -8,8 +8,6 @@ import type React from 'react';
|
||||
import { Box, Text } from 'ink';
|
||||
import { Colors } from '../colors.js';
|
||||
import { GIT_COMMIT_INFO } from '../../generated/git-commit.js';
|
||||
import type { UserTierId } from '@google/gemini-cli-core';
|
||||
import { getLicenseDisplay } from '../../utils/license.js';
|
||||
|
||||
interface AboutBoxProps {
|
||||
cliVersion: string;
|
||||
@@ -19,7 +17,6 @@ interface AboutBoxProps {
|
||||
selectedAuthType: string;
|
||||
gcpProject: string;
|
||||
ideClient: string;
|
||||
userTier?: UserTierId;
|
||||
}
|
||||
|
||||
export const AboutBox: React.FC<AboutBoxProps> = ({
|
||||
@@ -30,7 +27,6 @@ export const AboutBox: React.FC<AboutBoxProps> = ({
|
||||
selectedAuthType,
|
||||
gcpProject,
|
||||
ideClient,
|
||||
userTier,
|
||||
}) => (
|
||||
<Box
|
||||
borderStyle="round"
|
||||
@@ -109,16 +105,6 @@ export const AboutBox: React.FC<AboutBoxProps> = ({
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box flexDirection="row">
|
||||
<Box width="35%">
|
||||
<Text bold color={Colors.LightBlue}>
|
||||
License
|
||||
</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>{getLicenseDisplay(selectedAuthType, userTier)}</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
{gcpProject && (
|
||||
<Box flexDirection="row">
|
||||
<Box width="35%">
|
||||
|
||||
@@ -64,14 +64,9 @@ export function AuthDialog({
|
||||
});
|
||||
const items = [
|
||||
{
|
||||
label: 'Login with Google - Free Tier',
|
||||
label: 'Login with Google',
|
||||
value: AuthType.LOGIN_WITH_GOOGLE,
|
||||
},
|
||||
{
|
||||
label:
|
||||
'Login with Google - Gemini Code Assist (Requires GOOGLE_CLOUD_PROJECT)',
|
||||
value: AuthType.LOGIN_WITH_GOOGLE_GCA,
|
||||
},
|
||||
...(process.env['CLOUD_SHELL'] === 'true'
|
||||
? [
|
||||
{
|
||||
|
||||
@@ -74,7 +74,6 @@ export const HistoryItemDisplay: React.FC<HistoryItemDisplayProps> = ({
|
||||
selectedAuthType={item.selectedAuthType}
|
||||
gcpProject={item.gcpProject}
|
||||
ideClient={item.ideClient}
|
||||
userTier={item.userTier}
|
||||
/>
|
||||
)}
|
||||
{item.type === 'help' && commands && <Help commands={commands} />}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
import type {
|
||||
ToolCallConfirmationDetails,
|
||||
ToolResultDisplay,
|
||||
UserTierId,
|
||||
} from '@google/gemini-cli-core';
|
||||
|
||||
// Only defining the state enum needed by the UI
|
||||
@@ -97,7 +96,6 @@ export type HistoryItemAbout = HistoryItemBase & {
|
||||
selectedAuthType: string;
|
||||
gcpProject: string;
|
||||
ideClient: string;
|
||||
userTier?: UserTierId;
|
||||
};
|
||||
|
||||
export type HistoryItemHelp = HistoryItemBase & {
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { getLicenseDisplay } from './license.js';
|
||||
import { AuthType, UserTierId } from '@google/gemini-cli-core';
|
||||
|
||||
describe('getLicenseDisplay', () => {
|
||||
describe('Free Tier (Login with Google)', () => {
|
||||
it('should return Free Tier for LOGIN_WITH_GOOGLE', () => {
|
||||
expect(getLicenseDisplay(AuthType.LOGIN_WITH_GOOGLE)).toBe(
|
||||
'Free Tier (Login with Google)',
|
||||
);
|
||||
});
|
||||
|
||||
it('should ignore userTier for LOGIN_WITH_GOOGLE', () => {
|
||||
expect(
|
||||
getLicenseDisplay(AuthType.LOGIN_WITH_GOOGLE, UserTierId.STANDARD),
|
||||
).toBe('Free Tier (Login with Google)');
|
||||
expect(
|
||||
getLicenseDisplay(AuthType.LOGIN_WITH_GOOGLE, UserTierId.LEGACY),
|
||||
).toBe('Free Tier (Login with Google)');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Gemini Code Assist (Google Workspace)', () => {
|
||||
it('should return GCA Standard for LOGIN_WITH_GOOGLE_GCA with STANDARD tier', () => {
|
||||
expect(
|
||||
getLicenseDisplay(AuthType.LOGIN_WITH_GOOGLE_GCA, UserTierId.STANDARD),
|
||||
).toBe('Gemini Code Assist Standard (Google Workspace)');
|
||||
});
|
||||
|
||||
it('should return GCA Enterprise for LOGIN_WITH_GOOGLE_GCA with LEGACY tier', () => {
|
||||
expect(
|
||||
getLicenseDisplay(AuthType.LOGIN_WITH_GOOGLE_GCA, UserTierId.LEGACY),
|
||||
).toBe('Gemini Code Assist Enterprise (Google Workspace)');
|
||||
});
|
||||
|
||||
it('should return generic GCA for LOGIN_WITH_GOOGLE_GCA without tier', () => {
|
||||
expect(getLicenseDisplay(AuthType.LOGIN_WITH_GOOGLE_GCA)).toBe(
|
||||
'Gemini Code Assist (Google Workspace)',
|
||||
);
|
||||
});
|
||||
|
||||
it('should return generic GCA for LOGIN_WITH_GOOGLE_GCA with unknown tier', () => {
|
||||
expect(
|
||||
getLicenseDisplay(
|
||||
AuthType.LOGIN_WITH_GOOGLE_GCA,
|
||||
'unknown-tier' as UserTierId,
|
||||
),
|
||||
).toBe('Gemini Code Assist (Google Workspace)');
|
||||
});
|
||||
|
||||
it('should return generic GCA for LOGIN_WITH_GOOGLE_GCA with FREE tier', () => {
|
||||
expect(
|
||||
getLicenseDisplay(AuthType.LOGIN_WITH_GOOGLE_GCA, UserTierId.FREE),
|
||||
).toBe('Gemini Code Assist (Google Workspace)');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Gemini API Key', () => {
|
||||
it('should return Gemini API Key for USE_GEMINI', () => {
|
||||
expect(getLicenseDisplay(AuthType.USE_GEMINI)).toBe('Gemini API Key');
|
||||
});
|
||||
|
||||
it('should ignore userTier for USE_GEMINI', () => {
|
||||
expect(getLicenseDisplay(AuthType.USE_GEMINI, UserTierId.STANDARD)).toBe(
|
||||
'Gemini API Key',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Vertex AI', () => {
|
||||
it('should return Vertex AI for USE_VERTEX_AI', () => {
|
||||
expect(getLicenseDisplay(AuthType.USE_VERTEX_AI)).toBe('Vertex AI');
|
||||
});
|
||||
|
||||
it('should ignore userTier for USE_VERTEX_AI', () => {
|
||||
expect(getLicenseDisplay(AuthType.USE_VERTEX_AI, UserTierId.LEGACY)).toBe(
|
||||
'Vertex AI',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Cloud Shell', () => {
|
||||
it('should return Cloud Shell for CLOUD_SHELL', () => {
|
||||
expect(getLicenseDisplay(AuthType.CLOUD_SHELL)).toBe('Cloud Shell');
|
||||
});
|
||||
|
||||
it('should ignore userTier for CLOUD_SHELL', () => {
|
||||
expect(getLicenseDisplay(AuthType.CLOUD_SHELL, UserTierId.STANDARD)).toBe(
|
||||
'Cloud Shell',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Unknown auth types', () => {
|
||||
it('should return the auth type as-is for unknown values', () => {
|
||||
expect(getLicenseDisplay('custom-auth-type')).toBe('custom-auth-type');
|
||||
expect(getLicenseDisplay('oauth')).toBe('oauth');
|
||||
expect(getLicenseDisplay('unknown-auth')).toBe('unknown-auth');
|
||||
});
|
||||
|
||||
it('should handle undefined gracefully', () => {
|
||||
expect(getLicenseDisplay(undefined as unknown as string)).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should handle null gracefully', () => {
|
||||
expect(getLicenseDisplay(null as unknown as string)).toBe(null);
|
||||
});
|
||||
|
||||
it('should handle empty string', () => {
|
||||
expect(getLicenseDisplay('')).toBe('');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,43 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { AuthType, UserTierId } from '@google/gemini-cli-core';
|
||||
|
||||
/**
|
||||
* Get human-readable license display text based on auth type and user tier.
|
||||
* @param selectedAuthType - The authentication type selected by the user
|
||||
* @param userTier - Optional user tier information from the server
|
||||
* @returns Human-readable license information
|
||||
*/
|
||||
export function getLicenseDisplay(
|
||||
selectedAuthType: string,
|
||||
userTier?: UserTierId,
|
||||
): string {
|
||||
switch (selectedAuthType) {
|
||||
case AuthType.LOGIN_WITH_GOOGLE:
|
||||
return 'Free Tier (Login with Google)';
|
||||
|
||||
case AuthType.LOGIN_WITH_GOOGLE_GCA:
|
||||
if (userTier === UserTierId.STANDARD) {
|
||||
return 'Gemini Code Assist Standard (Google Workspace)';
|
||||
} else if (userTier === UserTierId.LEGACY) {
|
||||
return 'Gemini Code Assist Enterprise (Google Workspace)';
|
||||
}
|
||||
return 'Gemini Code Assist (Google Workspace)';
|
||||
|
||||
case AuthType.USE_GEMINI:
|
||||
return 'Gemini API Key';
|
||||
|
||||
case AuthType.USE_VERTEX_AI:
|
||||
return 'Vertex AI';
|
||||
|
||||
case AuthType.CLOUD_SHELL:
|
||||
return 'Cloud Shell';
|
||||
|
||||
default:
|
||||
return selectedAuthType;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user