mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-18 18:11:02 -07:00
feat: Add startup profiler to measure and record application initialization phases. (#13638)
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
type Config,
|
||||
StartSessionEvent,
|
||||
logCliConfiguration,
|
||||
startupProfiler,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { type LoadedSettings } from '../config/settings.js';
|
||||
import { performInitialAuth } from './auth.js';
|
||||
@@ -35,10 +36,12 @@ export async function initializeApp(
|
||||
config: Config,
|
||||
settings: LoadedSettings,
|
||||
): Promise<InitializationResult> {
|
||||
const authHandle = startupProfiler.start('authenticate');
|
||||
const authError = await performInitialAuth(
|
||||
config,
|
||||
settings.merged.security?.auth?.selectedType,
|
||||
);
|
||||
authHandle?.end();
|
||||
const themeError = validateTheme(settings);
|
||||
|
||||
const shouldOpenAuthDialog =
|
||||
|
||||
@@ -56,6 +56,7 @@ import {
|
||||
enterAlternateScreen,
|
||||
disableLineWrapping,
|
||||
shouldEnterAlternateScreen,
|
||||
startupProfiler,
|
||||
ExitCodes,
|
||||
} from '@google/gemini-cli-core';
|
||||
import {
|
||||
@@ -281,6 +282,7 @@ export async function startInteractiveUI(
|
||||
}
|
||||
|
||||
export async function main() {
|
||||
const cliStartupHandle = startupProfiler.start('cli_startup');
|
||||
const cleanupStdio = patchStdio();
|
||||
registerSyncCleanup(() => {
|
||||
// This is needed to ensure we don't lose any buffered output.
|
||||
@@ -289,7 +291,11 @@ export async function main() {
|
||||
});
|
||||
|
||||
setupUnhandledRejectionHandler();
|
||||
const loadSettingsHandle = startupProfiler.start('load_settings');
|
||||
const settings = loadSettings();
|
||||
loadSettingsHandle?.end();
|
||||
|
||||
const migrateHandle = startupProfiler.start('migrate_settings');
|
||||
migrateDeprecatedSettings(
|
||||
settings,
|
||||
// Temporary extension manager only used during this non-interactive UI phase.
|
||||
@@ -301,9 +307,12 @@ export async function main() {
|
||||
requestSetting: null,
|
||||
}),
|
||||
);
|
||||
migrateHandle?.end();
|
||||
await cleanupCheckpoints();
|
||||
|
||||
const parseArgsHandle = startupProfiler.start('parse_arguments');
|
||||
const argv = await parseArguments(settings.merged);
|
||||
parseArgsHandle?.end();
|
||||
|
||||
// Check for invalid input combinations early to prevent crashes
|
||||
if (argv.promptInteractive && !process.stdin.isTTY) {
|
||||
@@ -446,7 +455,9 @@ export async function main() {
|
||||
// to run Gemini CLI. It is now safe to perform expensive initialization that
|
||||
// may have side effects.
|
||||
{
|
||||
const loadConfigHandle = startupProfiler.start('load_cli_config');
|
||||
const config = await loadCliConfig(settings.merged, sessionId, argv);
|
||||
loadConfigHandle?.end();
|
||||
|
||||
const policyEngine = config.getPolicyEngine();
|
||||
const messageBus = config.getMessageBus();
|
||||
@@ -514,7 +525,9 @@ export async function main() {
|
||||
}
|
||||
|
||||
setMaxSizedBoxDebugging(isDebugMode);
|
||||
const initAppHandle = startupProfiler.start('initialize_app');
|
||||
const initializationResult = await initializeApp(config, settings);
|
||||
initAppHandle?.end();
|
||||
|
||||
if (
|
||||
settings.merged.security?.auth?.selectedType ===
|
||||
@@ -556,6 +569,7 @@ export async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
cliStartupHandle?.end();
|
||||
// Render UI, passing necessary config values. Check that there is no command line question.
|
||||
if (config.isInteractive()) {
|
||||
await startInteractiveUI(
|
||||
@@ -570,6 +584,7 @@ export async function main() {
|
||||
}
|
||||
|
||||
await config.initialize();
|
||||
startupProfiler.flush(config);
|
||||
|
||||
// If not a TTY, read from stdin
|
||||
// This is for cases where the user pipes input directly into the command
|
||||
|
||||
@@ -8,6 +8,7 @@ import { isDevelopment } from '../utils/installationInfo.js';
|
||||
import type { ICommandLoader } from './types.js';
|
||||
import type { SlashCommand } from '../ui/commands/types.js';
|
||||
import type { Config } from '@google/gemini-cli-core';
|
||||
import { startupProfiler } from '@google/gemini-cli-core';
|
||||
import { aboutCommand } from '../ui/commands/aboutCommand.js';
|
||||
import { authCommand } from '../ui/commands/authCommand.js';
|
||||
import { bugCommand } from '../ui/commands/bugCommand.js';
|
||||
@@ -56,6 +57,7 @@ export class BuiltinCommandLoader implements ICommandLoader {
|
||||
* @returns A promise that resolves to an array of `SlashCommand` objects.
|
||||
*/
|
||||
async loadCommands(_signal: AbortSignal): Promise<SlashCommand[]> {
|
||||
const handle = startupProfiler.start('load_builtin_commands');
|
||||
const allDefinitions: Array<SlashCommand | null> = [
|
||||
aboutCommand,
|
||||
authCommand,
|
||||
@@ -92,7 +94,7 @@ export class BuiltinCommandLoader implements ICommandLoader {
|
||||
setupGithubCommand,
|
||||
terminalSetupCommand,
|
||||
];
|
||||
|
||||
handle?.end();
|
||||
return allDefinitions.filter((cmd): cmd is SlashCommand => cmd !== null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ import {
|
||||
enableMouseEvents,
|
||||
disableLineWrapping,
|
||||
shouldEnterAlternateScreen,
|
||||
startupProfiler,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { validateAuthMethod } from '../config/auth.js';
|
||||
import process from 'node:process';
|
||||
@@ -282,6 +283,7 @@ export const AppContainer = (props: AppContainerProps) => {
|
||||
// handled by the global catch.
|
||||
await config.initialize();
|
||||
setConfigInitialized(true);
|
||||
startupProfiler.flush(config);
|
||||
})();
|
||||
registerCleanup(async () => {
|
||||
// Turn off mouse scroll.
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
debugLogger,
|
||||
ReadManyFilesTool,
|
||||
getEffectiveModel,
|
||||
startupProfiler,
|
||||
} from '@google/gemini-cli-core';
|
||||
import * as acp from './acp.js';
|
||||
import { AcpFileSystemService } from './fileSystemService.js';
|
||||
@@ -189,6 +190,7 @@ export class GeminiAgent {
|
||||
const config = await loadCliConfig(settings, sessionId, this.argv, cwd);
|
||||
|
||||
await config.initialize();
|
||||
startupProfiler.flush(config);
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user