fix(websearch): filter disabled legacy CLI probes and skip unused version fetching

Closes #1716
This commit is contained in:
Tam Nhu Tran committed 2026-08-25 15:35:54 -04:00
1 parent 65dc902299
commit f4911694e3
6 files changed
+267 -101

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 };
}
/**
+20 -9
View File
@@ -113,13 +113,23 @@ 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 }
): WebSearchCliInfo[] {
const fetchVersion = options?.includeVersions !== false;
const agyEnabled = wsConfig.providers?.agy?.enabled ?? false;
const geminiEnabled = wsConfig.providers?.gemini?.enabled ?? false;
const grokEnabled = wsConfig.providers?.grok?.enabled ?? false;
const opencodeEnabled = wsConfig.providers?.opencode?.enabled ?? false;
const agyStatus = agyEnabled ? getAgyCliStatus({ fetchVersion }) : { 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',
@@ -198,7 +208,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 }
): WebSearchCliInfo[] {
const apiKeyStates = getWebSearchApiKeyStates();
const cooldowns = readProviderCooldowns();
@@ -284,7 +295,7 @@ export function getWebSearchCliProviders(
},
];
return [...providers, ...getLegacyProviderStatuses(wsConfig)].map((provider) =>
return [...providers, ...getLegacyProviderStatuses(wsConfig, options)].map((provider) =>
applyCooldownStatus(provider, cooldowns)
);
}
@@ -359,7 +370,7 @@ export function buildWebSearchReadiness(
export function getWebSearchReadiness(
wsConfig: WebSearchConfigSnapshot = getWebSearchConfig()
): WebSearchStatus {
const providers = getWebSearchCliProviders(wsConfig);
const providers = getWebSearchCliProviders(wsConfig, { includeVersions: 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();
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: false });
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');