mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-02-01 22:48:03 +00:00
feat: implement real-time quota visibility in CLI footer
- Intercept rate-limit headers from both public (GoogleGenAI) and internal (CodeAssist) APIs. - Add QuotaDisplay UI component with color-coded remaining percentage. - Sync CodeAssistServer constructor with main (userTierName support). - Fix circular dependencies in contentGenerator.ts. - Improve test stability in clipboardUtils.test.ts by isolating environment state.
This commit is contained in:
@@ -197,4 +197,4 @@ export const Footer: React.FC = () => {
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -55,6 +55,7 @@ import {
|
||||
cleanupOldClipboardImages,
|
||||
splitEscapedPaths,
|
||||
parsePastedPaths,
|
||||
resetClipboardToolForTesting,
|
||||
} from './clipboardUtils.js';
|
||||
|
||||
// Define the type for the module to use in tests
|
||||
@@ -73,6 +74,7 @@ describe('clipboardUtils', () => {
|
||||
process.env = { ...originalEnv };
|
||||
|
||||
// Reset modules to clear internal state (linuxClipboardTool variable)
|
||||
resetClipboardToolForTesting();
|
||||
vi.resetModules();
|
||||
// Dynamically import the module to get a fresh instance for each test
|
||||
clipboardUtils = await import('./clipboardUtils.js');
|
||||
@@ -305,6 +307,8 @@ describe('clipboardUtils', () => {
|
||||
});
|
||||
|
||||
it('should return null if tool is not yet detected', async () => {
|
||||
setPlatform('linux');
|
||||
delete process.env['XDG_SESSION_TYPE'];
|
||||
// Don't prime the tool
|
||||
const result = await clipboardUtils.saveClipboardImage(mockTargetDir);
|
||||
expect(result).toBe(null);
|
||||
|
||||
@@ -35,6 +35,14 @@ const PATH_PREFIX_PATTERN = /^([/~.]|[a-zA-Z]:|\\\\)/;
|
||||
// Track which tool works on Linux to avoid redundant checks/failures
|
||||
let linuxClipboardTool: 'wl-paste' | 'xclip' | null = null;
|
||||
|
||||
/**
|
||||
* Resets the cached Linux clipboard tool.
|
||||
* Only intended for use in unit tests.
|
||||
*/
|
||||
export function resetClipboardToolForTesting() {
|
||||
linuxClipboardTool = null;
|
||||
}
|
||||
|
||||
// Helper to check the user's display server and whether they have a compatible clipboard tool installed
|
||||
function getUserLinuxClipboardTool(): typeof linuxClipboardTool {
|
||||
if (linuxClipboardTool !== null) {
|
||||
|
||||
@@ -43,6 +43,7 @@ describe('codeAssist', () => {
|
||||
const mockUserData = {
|
||||
projectId: 'test-project',
|
||||
userTier: UserTierId.FREE,
|
||||
userTierName: 'free-tier-name',
|
||||
};
|
||||
|
||||
it('should create a server for LOGIN_WITH_GOOGLE', async () => {
|
||||
@@ -70,7 +71,7 @@ describe('codeAssist', () => {
|
||||
httpOptions,
|
||||
'session-123',
|
||||
'free-tier',
|
||||
undefined,
|
||||
'free-tier-name',
|
||||
expect.any(Function),
|
||||
);
|
||||
expect(generator).toBeInstanceOf(MockedCodeAssistServer);
|
||||
@@ -100,7 +101,7 @@ describe('codeAssist', () => {
|
||||
httpOptions,
|
||||
undefined, // No session ID
|
||||
'free-tier',
|
||||
undefined,
|
||||
'free-tier-name',
|
||||
expect.any(Function),
|
||||
);
|
||||
expect(generator).toBeInstanceOf(MockedCodeAssistServer);
|
||||
@@ -173,4 +174,4 @@ describe('codeAssist', () => {
|
||||
expect(server).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -53,4 +53,4 @@ export function getCodeAssistServer(
|
||||
return undefined;
|
||||
}
|
||||
return server;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -623,6 +623,7 @@ describe('CodeAssistServer', () => {
|
||||
{},
|
||||
'test-session',
|
||||
UserTierId.FREE,
|
||||
undefined,
|
||||
onQuotaUpdate,
|
||||
);
|
||||
|
||||
|
||||
@@ -368,11 +368,12 @@ describe('createContentGenerator', () => {
|
||||
expect(GoogleGenAI).toHaveBeenCalledWith({
|
||||
apiKey: 'test-api-key',
|
||||
vertexai: undefined,
|
||||
httpOptions: {
|
||||
httpOptions: expect.objectContaining({
|
||||
headers: expect.objectContaining({
|
||||
'User-Agent': expect.any(String),
|
||||
}),
|
||||
},
|
||||
fetch: expect.any(Function),
|
||||
}),
|
||||
apiVersion: 'v1',
|
||||
});
|
||||
});
|
||||
@@ -401,11 +402,12 @@ describe('createContentGenerator', () => {
|
||||
expect(GoogleGenAI).toHaveBeenCalledWith({
|
||||
apiKey: 'test-api-key',
|
||||
vertexai: undefined,
|
||||
httpOptions: {
|
||||
httpOptions: expect.objectContaining({
|
||||
headers: expect.objectContaining({
|
||||
'User-Agent': expect.any(String),
|
||||
}),
|
||||
},
|
||||
fetch: expect.any(Function),
|
||||
}),
|
||||
});
|
||||
|
||||
expect(GoogleGenAI).toHaveBeenCalledWith(
|
||||
@@ -440,11 +442,12 @@ describe('createContentGenerator', () => {
|
||||
expect(GoogleGenAI).toHaveBeenCalledWith({
|
||||
apiKey: 'test-api-key',
|
||||
vertexai: undefined,
|
||||
httpOptions: {
|
||||
httpOptions: expect.objectContaining({
|
||||
headers: expect.objectContaining({
|
||||
'User-Agent': expect.any(String),
|
||||
}),
|
||||
},
|
||||
fetch: expect.any(Function),
|
||||
}),
|
||||
});
|
||||
|
||||
expect(GoogleGenAI).toHaveBeenCalledWith(
|
||||
@@ -480,11 +483,12 @@ describe('createContentGenerator', () => {
|
||||
expect(GoogleGenAI).toHaveBeenCalledWith({
|
||||
apiKey: 'test-api-key',
|
||||
vertexai: true,
|
||||
httpOptions: {
|
||||
httpOptions: expect.objectContaining({
|
||||
headers: expect.objectContaining({
|
||||
'User-Agent': expect.any(String),
|
||||
}),
|
||||
},
|
||||
fetch: expect.any(Function),
|
||||
}),
|
||||
apiVersion: 'v1alpha',
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user