mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-11 03:13:12 +00:00
fix(websearch): filter disabled legacy CLI probes and skip unused version fetching
Closes #1716
This commit is contained in:
1 parent
65dc902299
commit
f4911694e3
6 files changed
+267
-101
No files matched your search
+35
-23
@@ -22,35 +22,47 @@ let agyCliCache: AgyCliStatus | null = null;
|
|||||||
*
|
*
|
||||||
* @returns Antigravity CLI status with path and version
|
* @returns Antigravity CLI status with path and version
|
||||||
*/
|
*/
|
||||||
export function getAgyCliStatus(): AgyCliStatus {
|
export function getAgyCliStatus(options?: { fetchVersion?: boolean }): AgyCliStatus {
|
||||||
// Return cached result if available
|
const fetchVersion = options?.fetchVersion !== false;
|
||||||
if (agyCliCache) {
|
|
||||||
|
if (
|
||||||
|
agyCliCache &&
|
||||||
|
(!fetchVersion || agyCliCache.version !== undefined || !agyCliCache.installed)
|
||||||
|
) {
|
||||||
|
if (!fetchVersion) {
|
||||||
|
return { ...agyCliCache, version: undefined };
|
||||||
|
}
|
||||||
return agyCliCache;
|
return agyCliCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result: AgyCliStatus = {
|
const result: AgyCliStatus = agyCliCache
|
||||||
installed: false,
|
? { ...agyCliCache }
|
||||||
path: undefined,
|
: {
|
||||||
version: undefined,
|
installed: false,
|
||||||
};
|
path: undefined,
|
||||||
|
version: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const isWindows = process.platform === 'win32';
|
if (!agyCliCache) {
|
||||||
const whichCmd = isWindows ? 'where agy' : 'which agy';
|
const isWindows = process.platform === 'win32';
|
||||||
|
const whichCmd = isWindows ? 'where agy' : 'which agy';
|
||||||
|
|
||||||
const pathResult = execSync(whichCmd, {
|
const pathResult = execSync(whichCmd, {
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
});
|
});
|
||||||
|
|
||||||
const agyPath = pathResult.trim().split('\n')[0]; // First result on Windows
|
const agyPath = pathResult.trim().split('\n')[0];
|
||||||
|
|
||||||
if (agyPath) {
|
if (agyPath) {
|
||||||
result.installed = true;
|
result.installed = true;
|
||||||
result.path = agyPath;
|
result.path = agyPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Try to get version
|
if (result.installed && fetchVersion && result.version === undefined) {
|
||||||
try {
|
try {
|
||||||
const versionResult = execSync('agy --version', {
|
const versionResult = execSync('agy --version', {
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
@@ -59,17 +71,17 @@ export function getAgyCliStatus(): AgyCliStatus {
|
|||||||
});
|
});
|
||||||
result.version = versionResult.trim();
|
result.version = versionResult.trim();
|
||||||
} catch {
|
} catch {
|
||||||
// Version check failed, but CLI is installed
|
|
||||||
result.version = 'unknown';
|
result.version = 'unknown';
|
||||||
}
|
}
|
||||||
|
} else if (!fetchVersion) {
|
||||||
|
result.version = undefined;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Command not found - Antigravity CLI not installed
|
// Command not found - Antigravity CLI not installed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache result
|
|
||||||
agyCliCache = result;
|
agyCliCache = result;
|
||||||
return result;
|
return fetchVersion ? result : { ...result, version: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -23,35 +23,47 @@ let geminiCliCache: GeminiCliStatus | null = null;
|
|||||||
*
|
*
|
||||||
* @returns Gemini CLI status with path and version
|
* @returns Gemini CLI status with path and version
|
||||||
*/
|
*/
|
||||||
export function getGeminiCliStatus(): GeminiCliStatus {
|
export function getGeminiCliStatus(options?: { fetchVersion?: boolean }): GeminiCliStatus {
|
||||||
// Return cached result if available
|
const fetchVersion = options?.fetchVersion !== false;
|
||||||
if (geminiCliCache) {
|
|
||||||
|
if (
|
||||||
|
geminiCliCache &&
|
||||||
|
(!fetchVersion || geminiCliCache.version !== undefined || !geminiCliCache.installed)
|
||||||
|
) {
|
||||||
|
if (!fetchVersion) {
|
||||||
|
return { ...geminiCliCache, version: undefined };
|
||||||
|
}
|
||||||
return geminiCliCache;
|
return geminiCliCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result: GeminiCliStatus = {
|
const result: GeminiCliStatus = geminiCliCache
|
||||||
installed: false,
|
? { ...geminiCliCache }
|
||||||
path: undefined,
|
: {
|
||||||
version: undefined,
|
installed: false,
|
||||||
};
|
path: undefined,
|
||||||
|
version: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const isWindows = process.platform === 'win32';
|
if (!geminiCliCache) {
|
||||||
const whichCmd = isWindows ? 'where gemini' : 'which gemini';
|
const isWindows = process.platform === 'win32';
|
||||||
|
const whichCmd = isWindows ? 'where gemini' : 'which gemini';
|
||||||
|
|
||||||
const pathResult = execSync(whichCmd, {
|
const pathResult = execSync(whichCmd, {
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
});
|
});
|
||||||
|
|
||||||
const geminiPath = pathResult.trim().split('\n')[0]; // First result on Windows
|
const geminiPath = pathResult.trim().split('\n')[0];
|
||||||
|
|
||||||
if (geminiPath) {
|
if (geminiPath) {
|
||||||
result.installed = true;
|
result.installed = true;
|
||||||
result.path = geminiPath;
|
result.path = geminiPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Try to get version
|
if (result.installed && fetchVersion && result.version === undefined) {
|
||||||
try {
|
try {
|
||||||
const versionResult = execSync('gemini --version', {
|
const versionResult = execSync('gemini --version', {
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
@@ -60,17 +72,17 @@ export function getGeminiCliStatus(): GeminiCliStatus {
|
|||||||
});
|
});
|
||||||
result.version = versionResult.trim();
|
result.version = versionResult.trim();
|
||||||
} catch {
|
} catch {
|
||||||
// Version check failed, but CLI is installed
|
|
||||||
result.version = 'unknown';
|
result.version = 'unknown';
|
||||||
}
|
}
|
||||||
|
} else if (!fetchVersion) {
|
||||||
|
result.version = undefined;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Command not found - Gemini CLI not installed
|
// Command not found - Gemini CLI not installed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache result
|
|
||||||
geminiCliCache = result;
|
geminiCliCache = result;
|
||||||
return result;
|
return fetchVersion ? result : { ...result, version: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -20,35 +20,47 @@ let grokCliCache: GrokCliStatus | null = null;
|
|||||||
*
|
*
|
||||||
* @returns Grok CLI status with path and version
|
* @returns Grok CLI status with path and version
|
||||||
*/
|
*/
|
||||||
export function getGrokCliStatus(): GrokCliStatus {
|
export function getGrokCliStatus(options?: { fetchVersion?: boolean }): GrokCliStatus {
|
||||||
// Return cached result if available
|
const fetchVersion = options?.fetchVersion !== false;
|
||||||
if (grokCliCache) {
|
|
||||||
|
if (
|
||||||
|
grokCliCache &&
|
||||||
|
(!fetchVersion || grokCliCache.version !== undefined || !grokCliCache.installed)
|
||||||
|
) {
|
||||||
|
if (!fetchVersion) {
|
||||||
|
return { ...grokCliCache, version: undefined };
|
||||||
|
}
|
||||||
return grokCliCache;
|
return grokCliCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result: GrokCliStatus = {
|
const result: GrokCliStatus = grokCliCache
|
||||||
installed: false,
|
? { ...grokCliCache }
|
||||||
path: undefined,
|
: {
|
||||||
version: undefined,
|
installed: false,
|
||||||
};
|
path: undefined,
|
||||||
|
version: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const isWindows = process.platform === 'win32';
|
if (!grokCliCache) {
|
||||||
const whichCmd = isWindows ? 'where grok' : 'which grok';
|
const isWindows = process.platform === 'win32';
|
||||||
|
const whichCmd = isWindows ? 'where grok' : 'which grok';
|
||||||
|
|
||||||
const pathResult = execSync(whichCmd, {
|
const pathResult = execSync(whichCmd, {
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
});
|
});
|
||||||
|
|
||||||
const grokPath = pathResult.trim().split('\n')[0]; // First result on Windows
|
const grokPath = pathResult.trim().split('\n')[0];
|
||||||
|
|
||||||
if (grokPath) {
|
if (grokPath) {
|
||||||
result.installed = true;
|
result.installed = true;
|
||||||
result.path = grokPath;
|
result.path = grokPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Try to get version
|
if (result.installed && fetchVersion && result.version === undefined) {
|
||||||
try {
|
try {
|
||||||
const versionResult = execSync('grok --version', {
|
const versionResult = execSync('grok --version', {
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
@@ -57,17 +69,17 @@ export function getGrokCliStatus(): GrokCliStatus {
|
|||||||
});
|
});
|
||||||
result.version = versionResult.trim();
|
result.version = versionResult.trim();
|
||||||
} catch {
|
} catch {
|
||||||
// Version check failed, but CLI is installed
|
|
||||||
result.version = 'unknown';
|
result.version = 'unknown';
|
||||||
}
|
}
|
||||||
|
} else if (!fetchVersion) {
|
||||||
|
result.version = undefined;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Command not found - Grok CLI not installed
|
// Command not found - Grok CLI not installed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache result
|
|
||||||
grokCliCache = result;
|
grokCliCache = result;
|
||||||
return result;
|
return fetchVersion ? result : { ...result, version: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -20,35 +20,47 @@ let opencodeCliCache: OpenCodeCliStatus | null = null;
|
|||||||
*
|
*
|
||||||
* @returns OpenCode CLI status with path and version
|
* @returns OpenCode CLI status with path and version
|
||||||
*/
|
*/
|
||||||
export function getOpenCodeCliStatus(): OpenCodeCliStatus {
|
export function getOpenCodeCliStatus(options?: { fetchVersion?: boolean }): OpenCodeCliStatus {
|
||||||
// Return cached result if available
|
const fetchVersion = options?.fetchVersion !== false;
|
||||||
if (opencodeCliCache) {
|
|
||||||
|
if (
|
||||||
|
opencodeCliCache &&
|
||||||
|
(!fetchVersion || opencodeCliCache.version !== undefined || !opencodeCliCache.installed)
|
||||||
|
) {
|
||||||
|
if (!fetchVersion) {
|
||||||
|
return { ...opencodeCliCache, version: undefined };
|
||||||
|
}
|
||||||
return opencodeCliCache;
|
return opencodeCliCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result: OpenCodeCliStatus = {
|
const result: OpenCodeCliStatus = opencodeCliCache
|
||||||
installed: false,
|
? { ...opencodeCliCache }
|
||||||
path: undefined,
|
: {
|
||||||
version: undefined,
|
installed: false,
|
||||||
};
|
path: undefined,
|
||||||
|
version: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const isWindows = process.platform === 'win32';
|
if (!opencodeCliCache) {
|
||||||
const whichCmd = isWindows ? 'where opencode' : 'which opencode';
|
const isWindows = process.platform === 'win32';
|
||||||
|
const whichCmd = isWindows ? 'where opencode' : 'which opencode';
|
||||||
|
|
||||||
const pathResult = execSync(whichCmd, {
|
const pathResult = execSync(whichCmd, {
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
});
|
});
|
||||||
|
|
||||||
const opencodePath = pathResult.trim().split('\n')[0]; // First result on Windows
|
const opencodePath = pathResult.trim().split('\n')[0];
|
||||||
|
|
||||||
if (opencodePath) {
|
if (opencodePath) {
|
||||||
result.installed = true;
|
result.installed = true;
|
||||||
result.path = opencodePath;
|
result.path = opencodePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Try to get version
|
if (result.installed && fetchVersion && result.version === undefined) {
|
||||||
try {
|
try {
|
||||||
const versionResult = execSync('opencode --version', {
|
const versionResult = execSync('opencode --version', {
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
@@ -57,17 +69,17 @@ export function getOpenCodeCliStatus(): OpenCodeCliStatus {
|
|||||||
});
|
});
|
||||||
result.version = versionResult.trim();
|
result.version = versionResult.trim();
|
||||||
} catch {
|
} catch {
|
||||||
// Version check failed, but CLI is installed
|
|
||||||
result.version = 'unknown';
|
result.version = 'unknown';
|
||||||
}
|
}
|
||||||
|
} else if (!fetchVersion) {
|
||||||
|
result.version = undefined;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Command not found - OpenCode CLI not installed
|
// Command not found - OpenCode CLI not installed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache result
|
|
||||||
opencodeCliCache = result;
|
opencodeCliCache = result;
|
||||||
return result;
|
return fetchVersion ? result : { ...result, version: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -113,13 +113,23 @@ function applyCooldownStatus(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLegacyProviderStatuses(wsConfig: WebSearchConfigSnapshot): WebSearchCliInfo[] {
|
function getLegacyProviderStatuses(
|
||||||
const agyStatus = getAgyCliStatus();
|
wsConfig: WebSearchConfigSnapshot,
|
||||||
const geminiStatus = getGeminiCliStatus();
|
options?: { includeVersions?: boolean }
|
||||||
const grokStatus = getGrokCliStatus();
|
): WebSearchCliInfo[] {
|
||||||
const opencodeStatus = getOpenCodeCliStatus();
|
const fetchVersion = options?.includeVersions !== false;
|
||||||
const geminiAuthed = geminiStatus.installed && isGeminiAuthenticated();
|
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 [
|
return [
|
||||||
{
|
{
|
||||||
id: 'agy',
|
id: 'agy',
|
||||||
@@ -198,7 +208,8 @@ function getLegacyProviderStatuses(wsConfig: WebSearchConfigSnapshot): WebSearch
|
|||||||
* Get all WebSearch providers with their current status.
|
* Get all WebSearch providers with their current status.
|
||||||
*/
|
*/
|
||||||
export function getWebSearchCliProviders(
|
export function getWebSearchCliProviders(
|
||||||
wsConfig: WebSearchConfigSnapshot = getWebSearchConfig()
|
wsConfig: WebSearchConfigSnapshot = getWebSearchConfig(),
|
||||||
|
options?: { includeVersions?: boolean }
|
||||||
): WebSearchCliInfo[] {
|
): WebSearchCliInfo[] {
|
||||||
const apiKeyStates = getWebSearchApiKeyStates();
|
const apiKeyStates = getWebSearchApiKeyStates();
|
||||||
const cooldowns = readProviderCooldowns();
|
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)
|
applyCooldownStatus(provider, cooldowns)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -359,7 +370,7 @@ export function buildWebSearchReadiness(
|
|||||||
export function getWebSearchReadiness(
|
export function getWebSearchReadiness(
|
||||||
wsConfig: WebSearchConfigSnapshot = getWebSearchConfig()
|
wsConfig: WebSearchConfigSnapshot = getWebSearchConfig()
|
||||||
): WebSearchStatus {
|
): WebSearchStatus {
|
||||||
const providers = getWebSearchCliProviders(wsConfig);
|
const providers = getWebSearchCliProviders(wsConfig, { includeVersions: false });
|
||||||
return buildWebSearchReadiness(wsConfig.enabled, providers);
|
return buildWebSearchReadiness(wsConfig.enabled, providers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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', () => {
|
it('treats cooled-down providers as temporarily unavailable in readiness status', () => {
|
||||||
const tempHome = mkdtempSync(join(tmpdir(), 'websearch-status-cooldown-'));
|
const tempHome = mkdtempSync(join(tmpdir(), 'websearch-status-cooldown-'));
|
||||||
const statePath = join(tempHome, '.ccs', 'cache', 'websearch-provider-state.json');
|
const statePath = join(tempHome, '.ccs', 'cache', 'websearch-provider-state.json');
|
||||||
|
|||||||
Reference in new issue
Block a user