Merge pull request #1721 from kaitranntt/kai/fix/1716-websearch-probe-perf

fix(websearch): filter disabled legacy CLI probes and skip unused version fetching (#1716)
This commit is contained in:
Kai (Tam Nhu) Tran authored and GitHub committed 2026-08-25 16:02:43 -04:00
commit 8f87937e8a
6 files changed
+298 -117

No files matched your search

+35 -23
View File
@@ -22,35 +22,47 @@ let agyCliCache: AgyCliStatus | null = null;
*
* @returns Antigravity CLI status with path and version
*/
export function getAgyCliStatus(): AgyCliStatus {
// Return cached result if available
if (agyCliCache) {
export function getAgyCliStatus(options?: { fetchVersion?: boolean }): AgyCliStatus {
const fetchVersion = options?.fetchVersion !== false;
if (
agyCliCache &&
(!fetchVersion || agyCliCache.version !== undefined || !agyCliCache.installed)
) {
if (!fetchVersion) {
return { ...agyCliCache, version: undefined };
}
return agyCliCache;
}
const result: AgyCliStatus = {
installed: false,
path: undefined,
version: undefined,
};
const result: AgyCliStatus = agyCliCache
? { ...agyCliCache }
: {
installed: false,
path: undefined,
version: undefined,
};
try {
const isWindows = process.platform === 'win32';
const whichCmd = isWindows ? 'where agy' : 'which agy';
if (!agyCliCache) {
const isWindows = process.platform === 'win32';
const whichCmd = isWindows ? 'where agy' : 'which agy';
const pathResult = execSync(whichCmd, {
encoding: 'utf8',
timeout: 5000,
stdio: ['pipe', 'pipe', 'pipe'],
});
const pathResult = execSync(whichCmd, {
encoding: 'utf8',
timeout: 5000,
stdio: ['pipe', 'pipe', 'pipe'],
});
const agyPath = pathResult.trim().split('\n')[0]; // First result on Windows
const agyPath = pathResult.trim().split('\n')[0];
if (agyPath) {
result.installed = true;
result.path = agyPath;
if (agyPath) {
result.installed = true;
result.path = agyPath;
}
}
// Try to get version
if (result.installed && fetchVersion && result.version === undefined) {
try {
const versionResult = execSync('agy --version', {
encoding: 'utf8',
@@ -59,17 +71,17 @@ export function getAgyCliStatus(): AgyCliStatus {
});
result.version = versionResult.trim();
} catch {
// Version check failed, but CLI is installed
result.version = 'unknown';
}
} else if (!fetchVersion) {
result.version = undefined;
}
} catch {
// Command not found - Antigravity CLI not installed
}
// Cache result
agyCliCache = result;
return result;
return fetchVersion ? result : { ...result, version: undefined };
}
/**
+35 -23
View File
@@ -23,35 +23,47 @@ let geminiCliCache: GeminiCliStatus | null = null;
*
* @returns Gemini CLI status with path and version
*/
export function getGeminiCliStatus(): GeminiCliStatus {
// Return cached result if available
if (geminiCliCache) {
export function getGeminiCliStatus(options?: { fetchVersion?: boolean }): GeminiCliStatus {
const fetchVersion = options?.fetchVersion !== false;
if (
geminiCliCache &&
(!fetchVersion || geminiCliCache.version !== undefined || !geminiCliCache.installed)
) {
if (!fetchVersion) {
return { ...geminiCliCache, version: undefined };
}
return geminiCliCache;
}
const result: GeminiCliStatus = {
installed: false,
path: undefined,
version: undefined,
};
const result: GeminiCliStatus = geminiCliCache
? { ...geminiCliCache }
: {
installed: false,
path: undefined,
version: undefined,
};
try {
const isWindows = process.platform === 'win32';
const whichCmd = isWindows ? 'where gemini' : 'which gemini';
if (!geminiCliCache) {
const isWindows = process.platform === 'win32';
const whichCmd = isWindows ? 'where gemini' : 'which gemini';
const pathResult = execSync(whichCmd, {
encoding: 'utf8',
timeout: 5000,
stdio: ['pipe', 'pipe', 'pipe'],
});
const pathResult = execSync(whichCmd, {
encoding: 'utf8',
timeout: 5000,
stdio: ['pipe', 'pipe', 'pipe'],
});
const geminiPath = pathResult.trim().split('\n')[0]; // First result on Windows
const geminiPath = pathResult.trim().split('\n')[0];
if (geminiPath) {
result.installed = true;
result.path = geminiPath;
if (geminiPath) {
result.installed = true;
result.path = geminiPath;
}
}
// Try to get version
if (result.installed && fetchVersion && result.version === undefined) {
try {
const versionResult = execSync('gemini --version', {
encoding: 'utf8',
@@ -60,17 +72,17 @@ export function getGeminiCliStatus(): GeminiCliStatus {
});
result.version = versionResult.trim();
} catch {
// Version check failed, but CLI is installed
result.version = 'unknown';
}
} else if (!fetchVersion) {
result.version = undefined;
}
} catch {
// Command not found - Gemini CLI not installed
}
// Cache result
geminiCliCache = result;
return result;
return fetchVersion ? result : { ...result, version: undefined };
}
/**
+35 -23
View File
@@ -20,35 +20,47 @@ let grokCliCache: GrokCliStatus | null = null;
*
* @returns Grok CLI status with path and version
*/
export function getGrokCliStatus(): GrokCliStatus {
// Return cached result if available
if (grokCliCache) {
export function getGrokCliStatus(options?: { fetchVersion?: boolean }): GrokCliStatus {
const fetchVersion = options?.fetchVersion !== false;
if (
grokCliCache &&
(!fetchVersion || grokCliCache.version !== undefined || !grokCliCache.installed)
) {
if (!fetchVersion) {
return { ...grokCliCache, version: undefined };
}
return grokCliCache;
}
const result: GrokCliStatus = {
installed: false,
path: undefined,
version: undefined,
};
const result: GrokCliStatus = grokCliCache
? { ...grokCliCache }
: {
installed: false,
path: undefined,
version: undefined,
};
try {
const isWindows = process.platform === 'win32';
const whichCmd = isWindows ? 'where grok' : 'which grok';
if (!grokCliCache) {
const isWindows = process.platform === 'win32';
const whichCmd = isWindows ? 'where grok' : 'which grok';
const pathResult = execSync(whichCmd, {
encoding: 'utf8',
timeout: 5000,
stdio: ['pipe', 'pipe', 'pipe'],
});
const pathResult = execSync(whichCmd, {
encoding: 'utf8',
timeout: 5000,
stdio: ['pipe', 'pipe', 'pipe'],
});
const grokPath = pathResult.trim().split('\n')[0]; // First result on Windows
const grokPath = pathResult.trim().split('\n')[0];
if (grokPath) {
result.installed = true;
result.path = grokPath;
if (grokPath) {
result.installed = true;
result.path = grokPath;
}
}
// Try to get version
if (result.installed && fetchVersion && result.version === undefined) {
try {
const versionResult = execSync('grok --version', {
encoding: 'utf8',
@@ -57,17 +69,17 @@ export function getGrokCliStatus(): GrokCliStatus {
});
result.version = versionResult.trim();
} catch {
// Version check failed, but CLI is installed
result.version = 'unknown';
}
} else if (!fetchVersion) {
result.version = undefined;
}
} catch {
// Command not found - Grok CLI not installed
}
// Cache result
grokCliCache = result;
return result;
return fetchVersion ? result : { ...result, version: undefined };
}
/**
+35 -23
View File
@@ -20,35 +20,47 @@ let opencodeCliCache: OpenCodeCliStatus | null = null;
*
* @returns OpenCode CLI status with path and version
*/
export function getOpenCodeCliStatus(): OpenCodeCliStatus {
// Return cached result if available
if (opencodeCliCache) {
export function getOpenCodeCliStatus(options?: { fetchVersion?: boolean }): OpenCodeCliStatus {
const fetchVersion = options?.fetchVersion !== false;
if (
opencodeCliCache &&
(!fetchVersion || opencodeCliCache.version !== undefined || !opencodeCliCache.installed)
) {
if (!fetchVersion) {
return { ...opencodeCliCache, version: undefined };
}
return opencodeCliCache;
}
const result: OpenCodeCliStatus = {
installed: false,
path: undefined,
version: undefined,
};
const result: OpenCodeCliStatus = opencodeCliCache
? { ...opencodeCliCache }
: {
installed: false,
path: undefined,
version: undefined,
};
try {
const isWindows = process.platform === 'win32';
const whichCmd = isWindows ? 'where opencode' : 'which opencode';
if (!opencodeCliCache) {
const isWindows = process.platform === 'win32';
const whichCmd = isWindows ? 'where opencode' : 'which opencode';
const pathResult = execSync(whichCmd, {
encoding: 'utf8',
timeout: 5000,
stdio: ['pipe', 'pipe', 'pipe'],
});
const pathResult = execSync(whichCmd, {
encoding: 'utf8',
timeout: 5000,
stdio: ['pipe', 'pipe', 'pipe'],
});
const opencodePath = pathResult.trim().split('\n')[0]; // First result on Windows
const opencodePath = pathResult.trim().split('\n')[0];
if (opencodePath) {
result.installed = true;
result.path = opencodePath;
if (opencodePath) {
result.installed = true;
result.path = opencodePath;
}
}
// Try to get version
if (result.installed && fetchVersion && result.version === undefined) {
try {
const versionResult = execSync('opencode --version', {
encoding: 'utf8',
@@ -57,17 +69,17 @@ export function getOpenCodeCliStatus(): OpenCodeCliStatus {
});
result.version = versionResult.trim();
} catch {
// Version check failed, but CLI is installed
result.version = 'unknown';
}
} else if (!fetchVersion) {
result.version = undefined;
}
} catch {
// Command not found - OpenCode CLI not installed
}
// Cache result
opencodeCliCache = result;
return result;
return fetchVersion ? result : { ...result, version: undefined };
}
/**
+51 -25
View File
@@ -113,13 +113,25 @@ function applyCooldownStatus(
};
}
function getLegacyProviderStatuses(wsConfig: WebSearchConfigSnapshot): WebSearchCliInfo[] {
const agyStatus = getAgyCliStatus();
const geminiStatus = getGeminiCliStatus();
const grokStatus = getGrokCliStatus();
const opencodeStatus = getOpenCodeCliStatus();
const geminiAuthed = geminiStatus.installed && isGeminiAuthenticated();
function getLegacyProviderStatuses(
wsConfig: WebSearchConfigSnapshot,
options?: { includeVersions?: boolean; probeDisabled?: boolean }
): WebSearchCliInfo[] {
const probeAll = options?.probeDisabled ?? true;
const fetchVersion = options?.includeVersions ?? true;
const agyEnabled = probeAll || (wsConfig.providers?.agy?.enabled ?? false);
const geminiEnabled = probeAll || (wsConfig.providers?.gemini?.enabled ?? false);
const grokEnabled = probeAll || (wsConfig.providers?.grok?.enabled ?? false);
const opencodeEnabled = probeAll || (wsConfig.providers?.opencode?.enabled ?? false);
// agy detail renders its version on launch and in dashboard, so always fetch version when probed
const agyStatus = agyEnabled ? getAgyCliStatus({ fetchVersion: true }) : { installed: false };
const geminiStatus = geminiEnabled ? getGeminiCliStatus({ fetchVersion }) : { installed: false };
const grokStatus = grokEnabled ? getGrokCliStatus({ fetchVersion }) : { installed: false };
const opencodeStatus = opencodeEnabled
? getOpenCodeCliStatus({ fetchVersion })
: { installed: false };
const geminiAuthed = geminiEnabled && geminiStatus.installed && isGeminiAuthenticated();
return [
{
id: 'agy',
@@ -133,11 +145,13 @@ function getLegacyProviderStatuses(wsConfig: WebSearchConfigSnapshot): WebSearch
docsUrl: 'https://antigravity.google/cli',
requiresApiKey: false,
description: 'Recommended LLM CLI fallback with Google web search (Gemini CLI successor).',
detail: agyStatus.installed
? agyStatus.version
? `Installed (${agyStatus.version})`
: 'Installed'
: 'Not installed',
detail: !agyEnabled
? 'Disabled'
: agyStatus.installed
? agyStatus.version
? `Installed (${agyStatus.version})`
: 'Installed'
: 'Not installed',
},
{
id: 'gemini',
@@ -152,11 +166,13 @@ function getLegacyProviderStatuses(wsConfig: WebSearchConfigSnapshot): WebSearch
requiresApiKey: false,
description:
'Deprecated legacy fallback (Google retired the gemini CLI). Prefer Antigravity.',
detail: geminiStatus.installed
? geminiAuthed
? 'Authenticated'
: "Run 'gemini' to login"
: 'Not installed (retired - use Antigravity)',
detail: !geminiEnabled
? 'Disabled'
: geminiStatus.installed
? geminiAuthed
? 'Authenticated'
: "Run 'gemini' to login"
: 'Not installed (retired - use Antigravity)',
},
{
id: 'opencode',
@@ -170,7 +186,11 @@ function getLegacyProviderStatuses(wsConfig: WebSearchConfigSnapshot): WebSearch
docsUrl: 'https://github.com/sst/opencode',
requiresApiKey: false,
description: 'Optional legacy LLM fallback via OpenCode.',
detail: opencodeStatus.installed ? 'Installed' : 'Not installed',
detail: !opencodeEnabled
? 'Disabled'
: opencodeStatus.installed
? 'Installed'
: 'Not installed',
},
{
id: 'grok',
@@ -185,11 +205,13 @@ function getLegacyProviderStatuses(wsConfig: WebSearchConfigSnapshot): WebSearch
requiresApiKey: true,
apiKeyEnvVar: 'GROK_API_KEY',
description: 'Optional legacy LLM fallback with xAI Grok.',
detail: grokStatus.installed
? hasEnvValue('GROK_API_KEY')
? 'Ready'
: 'Set GROK_API_KEY'
: 'Not installed',
detail: !grokEnabled
? 'Disabled'
: grokStatus.installed
? hasEnvValue('GROK_API_KEY')
? 'Ready'
: 'Set GROK_API_KEY'
: 'Not installed',
},
];
}
@@ -198,7 +220,8 @@ function getLegacyProviderStatuses(wsConfig: WebSearchConfigSnapshot): WebSearch
* Get all WebSearch providers with their current status.
*/
export function getWebSearchCliProviders(
wsConfig: WebSearchConfigSnapshot = getWebSearchConfig()
wsConfig: WebSearchConfigSnapshot = getWebSearchConfig(),
options?: { includeVersions?: boolean; probeDisabled?: boolean }
): WebSearchCliInfo[] {
const apiKeyStates = getWebSearchApiKeyStates();
const cooldowns = readProviderCooldowns();
@@ -284,7 +307,7 @@ export function getWebSearchCliProviders(
},
];
return [...providers, ...getLegacyProviderStatuses(wsConfig)].map((provider) =>
return [...providers, ...getLegacyProviderStatuses(wsConfig, options)].map((provider) =>
applyCooldownStatus(provider, cooldowns)
);
}
@@ -359,7 +382,10 @@ export function buildWebSearchReadiness(
export function getWebSearchReadiness(
wsConfig: WebSearchConfigSnapshot = getWebSearchConfig()
): WebSearchStatus {
const providers = getWebSearchCliProviders(wsConfig);
const providers = getWebSearchCliProviders(wsConfig, {
includeVersions: false,
probeDisabled: false,
});
return buildWebSearchReadiness(wsConfig.enabled, providers);
}
+107
View File
@@ -301,6 +301,113 @@ describe('websearch readiness', () => {
}
});
it('does not invoke legacy CLI status probes when those providers are disabled', () => {
const getConfigSpy = spyOn(unifiedConfigLoader, 'getWebSearchConfig').mockReturnValue({
enabled: true,
providers: {
exa: { enabled: false, max_results: 5 },
tavily: { enabled: false, max_results: 5 },
brave: { enabled: false, max_results: 5 },
searxng: { enabled: false, url: '', max_results: 5 },
duckduckgo: { enabled: true, max_results: 5 },
agy: { enabled: false },
gemini: { enabled: false },
grok: { enabled: false },
opencode: { enabled: false },
},
} as any);
const apiKeySpy = spyOn(providerSecrets, 'getWebSearchApiKeyStates').mockReturnValue({
exa: { envVar: 'EXA_API_KEY', configured: false, available: false, source: 'none' },
tavily: { envVar: 'TAVILY_API_KEY', configured: false, available: false, source: 'none' },
brave: { envVar: 'BRAVE_API_KEY', configured: false, available: false, source: 'none' },
});
const agyStatusSpy = spyOn(agyCli, 'getAgyCliStatus').mockReturnValue({
installed: false,
} as any);
const geminiStatusSpy = spyOn(geminiCli, 'getGeminiCliStatus').mockReturnValue({
installed: false,
} as any);
const geminiAuthSpy = spyOn(geminiCli, 'isGeminiAuthenticated').mockReturnValue(false);
const grokStatusSpy = spyOn(grokCli, 'getGrokCliStatus').mockReturnValue({
installed: false,
} as any);
const opencodeStatusSpy = spyOn(opencodeCli, 'getOpenCodeCliStatus').mockReturnValue({
installed: false,
} as any);
try {
getWebSearchCliProviders(undefined, { probeDisabled: false });
expect(agyStatusSpy).not.toHaveBeenCalled();
expect(geminiStatusSpy).not.toHaveBeenCalled();
expect(geminiAuthSpy).not.toHaveBeenCalled();
expect(grokStatusSpy).not.toHaveBeenCalled();
expect(opencodeStatusSpy).not.toHaveBeenCalled();
} finally {
getConfigSpy.mockRestore();
apiKeySpy.mockRestore();
agyStatusSpy.mockRestore();
geminiStatusSpy.mockRestore();
geminiAuthSpy.mockRestore();
grokStatusSpy.mockRestore();
opencodeStatusSpy.mockRestore();
}
});
it('does not spawn --version when includeVersions is false', () => {
const wsConfig = {
enabled: true,
providers: {
exa: { enabled: false, max_results: 5 },
tavily: { enabled: false, max_results: 5 },
brave: { enabled: false, max_results: 5 },
searxng: { enabled: false, url: '', max_results: 5 },
duckduckgo: { enabled: false, max_results: 5 },
agy: { enabled: true, model: 'gemini-2.5-flash', timeout: 90 },
gemini: { enabled: true },
grok: { enabled: true },
opencode: { enabled: true },
},
};
const apiKeySpy = spyOn(providerSecrets, 'getWebSearchApiKeyStates').mockReturnValue({
exa: { envVar: 'EXA_API_KEY', configured: false, available: false, source: 'none' },
tavily: { envVar: 'TAVILY_API_KEY', configured: false, available: false, source: 'none' },
brave: { envVar: 'BRAVE_API_KEY', configured: false, available: false, source: 'none' },
});
const agyStatusSpy = spyOn(agyCli, 'getAgyCliStatus').mockReturnValue({
installed: true,
version: undefined,
});
const geminiStatusSpy = spyOn(geminiCli, 'getGeminiCliStatus').mockReturnValue({
installed: false,
version: undefined,
});
const geminiAuthSpy = spyOn(geminiCli, 'isGeminiAuthenticated').mockReturnValue(false);
const grokStatusSpy = spyOn(grokCli, 'getGrokCliStatus').mockReturnValue({
installed: false,
version: undefined,
});
const opencodeStatusSpy = spyOn(opencodeCli, 'getOpenCodeCliStatus').mockReturnValue({
installed: false,
version: undefined,
});
try {
getWebSearchCliProviders(wsConfig as Parameters<typeof getWebSearchCliProviders>[0], {
includeVersions: false,
});
expect(agyStatusSpy).toHaveBeenCalledWith({ fetchVersion: true });
expect(geminiStatusSpy).toHaveBeenCalledWith({ fetchVersion: false });
expect(grokStatusSpy).toHaveBeenCalledWith({ fetchVersion: false });
expect(opencodeStatusSpy).toHaveBeenCalledWith({ fetchVersion: false });
} finally {
apiKeySpy.mockRestore();
agyStatusSpy.mockRestore();
geminiStatusSpy.mockRestore();
geminiAuthSpy.mockRestore();
grokStatusSpy.mockRestore();
opencodeStatusSpy.mockRestore();
}
});
it('treats cooled-down providers as temporarily unavailable in readiness status', () => {
const tempHome = mkdtempSync(join(tmpdir(), 'websearch-status-cooldown-'));
const statePath = join(tempHome, '.ccs', 'cache', 'websearch-provider-state.json');