feat(websearch): add OpenCode CLI as third WebSearch provider

- Add OpenCodeWebSearchConfig type with enabled, model, timeout options
- Implement getOpenCodeCliStatus() for CLI detection with caching
- Add hasOpenCodeCli() and clearOpenCodeCliCache() helper functions
- Update getWebSearchCliProviders() to include OpenCode provider info
- Update hasAnyWebSearchCli() to check all three providers
- Update getCliInstallHints() with OpenCode install command
- Update WebSearchStatus interface to include opencodeCli
- Update getWebSearchReadiness() to report OpenCode status
- Update routes.ts PUT /api/websearch to handle opencode config
- Update routes.ts GET /api/websearch/status to return opencodeCli
- Add OpenCode provider card in settings.tsx UI
- Add purple-themed installation hints for OpenCode
- Order providers: Gemini (1st) -> OpenCode (2nd) -> Grok (3rd/last)

OpenCode uses `opencode run` with `opencode/gpt-5-nano` model for
web search. FREE tier available via OpenCode Zen, no API key required.
This commit is contained in:
kaitranntt
2025-12-16 21:37:31 -05:00
parent 81e46bd0e1
commit 482cda0f8e
4 changed files with 250 additions and 30 deletions
+22 -1
View File
@@ -62,6 +62,7 @@ import {
getWebSearchReadiness,
getGeminiCliStatus,
getGrokCliStatus,
getOpenCodeCliStatus,
} from '../utils/websearch-manager';
export const apiRoutes = Router();
@@ -1489,6 +1490,20 @@ apiRoutes.put('/websearch', (req: Request, res: Response): void => {
timeout:
providers.grok?.timeout ?? existingConfig.websearch?.providers?.grok?.timeout ?? 55,
},
opencode: {
enabled:
providers.opencode?.enabled ??
existingConfig.websearch?.providers?.opencode?.enabled ??
false,
model:
providers.opencode?.model ??
existingConfig.websearch?.providers?.opencode?.model ??
'opencode/gpt-5-nano',
timeout:
providers.opencode?.timeout ??
existingConfig.websearch?.providers?.opencode?.timeout ??
60,
},
}
: existingConfig.websearch?.providers,
};
@@ -1506,12 +1521,13 @@ apiRoutes.put('/websearch', (req: Request, res: Response): void => {
/**
* GET /api/websearch/status - Get WebSearch status
* Returns: { geminiCli, grokCli, readiness }
* Returns: { geminiCli, grokCli, opencodeCli, readiness }
*/
apiRoutes.get('/websearch/status', (_req: Request, res: Response): void => {
try {
const geminiCli = getGeminiCliStatus();
const grokCli = getGrokCliStatus();
const opencodeCli = getOpenCodeCliStatus();
const readiness = getWebSearchReadiness();
res.json({
@@ -1525,6 +1541,11 @@ apiRoutes.get('/websearch/status', (_req: Request, res: Response): void => {
path: grokCli.path,
version: grokCli.version,
},
opencodeCli: {
installed: opencodeCli.installed,
path: opencodeCli.path,
version: opencodeCli.version,
},
readiness: {
status: readiness.readiness,
message: readiness.message,