chore(coding-agent): add startup phase timings
This commit is contained in:
@@ -7,6 +7,12 @@ const ENABLED = process.env.PI_TIMING === "1";
|
|||||||
const timings: Array<{ label: string; ms: number }> = [];
|
const timings: Array<{ label: string; ms: number }> = [];
|
||||||
let lastTime = Date.now();
|
let lastTime = Date.now();
|
||||||
|
|
||||||
|
export function resetTimings(): void {
|
||||||
|
if (!ENABLED) return;
|
||||||
|
timings.length = 0;
|
||||||
|
lastTime = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
export function time(label: string): void {
|
export function time(label: string): void {
|
||||||
if (!ENABLED) return;
|
if (!ENABLED) return;
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import { DefaultResourceLoader } from "./core/resource-loader.js";
|
|||||||
import { type CreateAgentSessionOptions, createAgentSession } from "./core/sdk.js";
|
import { type CreateAgentSessionOptions, createAgentSession } from "./core/sdk.js";
|
||||||
import { SessionManager } from "./core/session-manager.js";
|
import { SessionManager } from "./core/session-manager.js";
|
||||||
import { SettingsManager } from "./core/settings-manager.js";
|
import { SettingsManager } from "./core/settings-manager.js";
|
||||||
import { printTimings, time } from "./core/timings.js";
|
import { printTimings, resetTimings, time } from "./core/timings.js";
|
||||||
import { allTools } from "./core/tools/index.js";
|
import { allTools } from "./core/tools/index.js";
|
||||||
import { runMigrations, showDeprecationWarnings } from "./migrations.js";
|
import { runMigrations, showDeprecationWarnings } from "./migrations.js";
|
||||||
import { InteractiveMode, runPrintMode, runRpcMode } from "./modes/index.js";
|
import { InteractiveMode, runPrintMode, runRpcMode } from "./modes/index.js";
|
||||||
@@ -622,6 +622,7 @@ async function handleConfigCommand(args: string[]): Promise<boolean> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function main(args: string[]) {
|
export async function main(args: string[]) {
|
||||||
|
resetTimings();
|
||||||
const offlineMode = args.includes("--offline") || isTruthyEnvFlag(process.env.PI_OFFLINE);
|
const offlineMode = args.includes("--offline") || isTruthyEnvFlag(process.env.PI_OFFLINE);
|
||||||
if (offlineMode) {
|
if (offlineMode) {
|
||||||
process.env.PI_OFFLINE = "1";
|
process.env.PI_OFFLINE = "1";
|
||||||
@@ -638,6 +639,7 @@ export async function main(args: string[]) {
|
|||||||
|
|
||||||
// First pass: parse args to get --extension paths
|
// First pass: parse args to get --extension paths
|
||||||
const firstPass = parseArgs(args);
|
const firstPass = parseArgs(args);
|
||||||
|
time("parseArgs.firstPass");
|
||||||
const shouldTakeOverStdout = firstPass.mode !== undefined || firstPass.print || !process.stdin.isTTY;
|
const shouldTakeOverStdout = firstPass.mode !== undefined || firstPass.print || !process.stdin.isTTY;
|
||||||
if (shouldTakeOverStdout) {
|
if (shouldTakeOverStdout) {
|
||||||
takeOverStdout();
|
takeOverStdout();
|
||||||
@@ -645,6 +647,7 @@ export async function main(args: string[]) {
|
|||||||
|
|
||||||
// Run migrations (pass cwd for project-local migrations)
|
// Run migrations (pass cwd for project-local migrations)
|
||||||
const { migratedAuthProviders: migratedProviders, deprecationWarnings } = runMigrations(process.cwd());
|
const { migratedAuthProviders: migratedProviders, deprecationWarnings } = runMigrations(process.cwd());
|
||||||
|
time("runMigrations");
|
||||||
|
|
||||||
// Early load extensions to discover their CLI flags
|
// Early load extensions to discover their CLI flags
|
||||||
const cwd = process.cwd();
|
const cwd = process.cwd();
|
||||||
@@ -669,6 +672,7 @@ export async function main(args: string[]) {
|
|||||||
systemPrompt: firstPass.systemPrompt,
|
systemPrompt: firstPass.systemPrompt,
|
||||||
appendSystemPrompt: firstPass.appendSystemPrompt,
|
appendSystemPrompt: firstPass.appendSystemPrompt,
|
||||||
});
|
});
|
||||||
|
time("createResourceLoader");
|
||||||
await resourceLoader.reload();
|
await resourceLoader.reload();
|
||||||
time("resourceLoader.reload");
|
time("resourceLoader.reload");
|
||||||
|
|
||||||
@@ -698,6 +702,7 @@ export async function main(args: string[]) {
|
|||||||
|
|
||||||
// Second pass: parse args with extension flags
|
// Second pass: parse args with extension flags
|
||||||
const parsed = parseArgs(args, extensionFlags);
|
const parsed = parseArgs(args, extensionFlags);
|
||||||
|
time("parseArgs.secondPass");
|
||||||
|
|
||||||
// Pass flag values to extensions via runtime
|
// Pass flag values to extensions via runtime
|
||||||
for (const [name, value] of parsed.unknownFlags) {
|
for (const [name, value] of parsed.unknownFlags) {
|
||||||
@@ -729,6 +734,7 @@ export async function main(args: string[]) {
|
|||||||
parsed.print = true;
|
parsed.print = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
time("readPipedStdin");
|
||||||
|
|
||||||
if (parsed.export) {
|
if (parsed.export) {
|
||||||
let result: string;
|
let result: string;
|
||||||
@@ -745,6 +751,7 @@ export async function main(args: string[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
migrateKeybindingsConfigFile(agentDir);
|
migrateKeybindingsConfigFile(agentDir);
|
||||||
|
time("migrateKeybindingsConfigFile");
|
||||||
|
|
||||||
if (parsed.mode === "rpc" && parsed.fileArgs.length > 0) {
|
if (parsed.mode === "rpc" && parsed.fileArgs.length > 0) {
|
||||||
console.error(chalk.red("Error: @file arguments are not supported in RPC mode"));
|
console.error(chalk.red("Error: @file arguments are not supported in RPC mode"));
|
||||||
@@ -758,6 +765,7 @@ export async function main(args: string[]) {
|
|||||||
settingsManager.getImageAutoResize(),
|
settingsManager.getImageAutoResize(),
|
||||||
stdinContent,
|
stdinContent,
|
||||||
);
|
);
|
||||||
|
time("prepareInitialMessage");
|
||||||
const isInteractive = !parsed.print && parsed.mode === undefined;
|
const isInteractive = !parsed.print && parsed.mode === undefined;
|
||||||
const startupBenchmark = isTruthyEnvFlag(process.env.PI_STARTUP_BENCHMARK);
|
const startupBenchmark = isTruthyEnvFlag(process.env.PI_STARTUP_BENCHMARK);
|
||||||
if (startupBenchmark && !isInteractive) {
|
if (startupBenchmark && !isInteractive) {
|
||||||
@@ -766,6 +774,7 @@ export async function main(args: string[]) {
|
|||||||
}
|
}
|
||||||
const mode = parsed.mode || "text";
|
const mode = parsed.mode || "text";
|
||||||
initTheme(settingsManager.getTheme(), isInteractive);
|
initTheme(settingsManager.getTheme(), isInteractive);
|
||||||
|
time("initTheme");
|
||||||
|
|
||||||
// Show deprecation warnings in interactive mode
|
// Show deprecation warnings in interactive mode
|
||||||
if (isInteractive && deprecationWarnings.length > 0) {
|
if (isInteractive && deprecationWarnings.length > 0) {
|
||||||
@@ -777,9 +786,11 @@ export async function main(args: string[]) {
|
|||||||
if (modelPatterns && modelPatterns.length > 0) {
|
if (modelPatterns && modelPatterns.length > 0) {
|
||||||
scopedModels = await resolveModelScope(modelPatterns, modelRegistry);
|
scopedModels = await resolveModelScope(modelPatterns, modelRegistry);
|
||||||
}
|
}
|
||||||
|
time("resolveModelScope");
|
||||||
|
|
||||||
// Create session manager based on CLI flags
|
// Create session manager based on CLI flags
|
||||||
let sessionManager = await createSessionManager(parsed, cwd, extensionsResult);
|
let sessionManager = await createSessionManager(parsed, cwd, extensionsResult);
|
||||||
|
time("createSessionManager");
|
||||||
|
|
||||||
// Handle --resume: show session picker
|
// Handle --resume: show session picker
|
||||||
if (parsed.resume) {
|
if (parsed.resume) {
|
||||||
@@ -821,6 +832,7 @@ export async function main(args: string[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { session, modelFallbackMessage } = await createAgentSession(sessionOptions);
|
const { session, modelFallbackMessage } = await createAgentSession(sessionOptions);
|
||||||
|
time("createAgentSession");
|
||||||
|
|
||||||
if (!isInteractive && !session.model) {
|
if (!isInteractive && !session.model) {
|
||||||
console.error(chalk.red("No models available."));
|
console.error(chalk.red("No models available."));
|
||||||
@@ -846,6 +858,7 @@ export async function main(args: string[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode === "rpc") {
|
if (mode === "rpc") {
|
||||||
|
printTimings();
|
||||||
await runRpcMode(session);
|
await runRpcMode(session);
|
||||||
} else if (isInteractive) {
|
} else if (isInteractive) {
|
||||||
if (scopedModels.length > 0 && (parsed.verbose || !settingsManager.getQuietStartup())) {
|
if (scopedModels.length > 0 && (parsed.verbose || !settingsManager.getQuietStartup())) {
|
||||||
@@ -868,6 +881,8 @@ export async function main(args: string[]) {
|
|||||||
});
|
});
|
||||||
if (startupBenchmark) {
|
if (startupBenchmark) {
|
||||||
await interactiveMode.init();
|
await interactiveMode.init();
|
||||||
|
time("interactiveMode.init");
|
||||||
|
printTimings();
|
||||||
interactiveMode.stop();
|
interactiveMode.stop();
|
||||||
stopThemeWatcher();
|
stopThemeWatcher();
|
||||||
if (process.stdout.writableLength > 0) {
|
if (process.stdout.writableLength > 0) {
|
||||||
@@ -882,6 +897,7 @@ export async function main(args: string[]) {
|
|||||||
printTimings();
|
printTimings();
|
||||||
await interactiveMode.run();
|
await interactiveMode.run();
|
||||||
} else {
|
} else {
|
||||||
|
printTimings();
|
||||||
const exitCode = await runPrintMode(session, {
|
const exitCode = await runPrintMode(session, {
|
||||||
mode,
|
mode,
|
||||||
messages: parsed.messages,
|
messages: parsed.messages,
|
||||||
|
|||||||
Reference in New Issue
Block a user