From cbc2022ed1399b7e71ea3e8af57b3173b34640d4 Mon Sep 17 00:00:00 2001 From: kaitranntt Date: Tue, 16 Dec 2025 22:47:53 -0500 Subject: [PATCH] refactor(websearch): consolidate prompts with shared instructions + provider overrides - Add SHARED_INSTRUCTIONS constant with 7 quality guidelines applied to ALL providers - Refactor PROVIDER_CONFIG to use toolInstruction (provider-specific) and quirks (optional) - Add buildPrompt() function to combine shared + provider-specific instructions - Gemini: google_web_search tool instruction - OpenCode: built-in capabilities instruction - Grok: web search + X/Twitter quirk for real-time events DRY improvement: shared guidelines now maintained in one place --- lib/hooks/websearch-transformer.cjs | 71 +++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 20 deletions(-) diff --git a/lib/hooks/websearch-transformer.cjs b/lib/hooks/websearch-transformer.cjs index 38e92593..1658e439 100644 --- a/lib/hooks/websearch-transformer.cjs +++ b/lib/hooks/websearch-transformer.cjs @@ -30,8 +30,21 @@ const { spawnSync } = require('child_process'); // ============================================================================ /** - * Provider configurations - models and prompts for each CLI tool. - * Edit these to customize search behavior. + * SHARED INSTRUCTIONS - Applied to ALL providers + * Edit here to change behavior across all CLI tools at once. + */ +const SHARED_INSTRUCTIONS = `Instructions: +1. Search the web for current, up-to-date information +2. Provide a comprehensive summary of the search results +3. Include relevant URLs/sources when available +4. Be concise but thorough - prioritize key facts +5. Focus on factual information from reliable sources +6. If results conflict, note the discrepancy +7. Format output clearly with sections if the topic is complex`; + +/** + * PROVIDER-SPECIFIC CONFIG - Only tool-use differences and quirks + * Each provider may have unique capabilities or invocation methods. */ const PROVIDER_CONFIG = { gemini: { @@ -39,15 +52,11 @@ const PROVIDER_CONFIG = { model: 'gemini-2.5-flash', // Alternative free models: gemini-2.0-flash, gemini-1.5-flash - // Prompt template - {query} will be replaced with search query - prompt: `Search the web for: {query} + // Provider-specific: How to invoke web search (Gemini has google_web_search tool) + toolInstruction: 'Use the google_web_search tool to find current information.', -Instructions: -1. Use the google_web_search tool to find current information -2. Provide a comprehensive summary of the search results -3. Include relevant URLs/sources when available -4. Be concise but thorough -5. Focus on factual, up-to-date information`, + // Optional quirks (null if none) + quirks: null, }, opencode: { @@ -55,10 +64,11 @@ Instructions: model: 'opencode/gpt-5-nano', // Alternative models: opencode/gpt-4o, opencode/claude-3.5-sonnet - // Prompt template - prompt: `Search the web for: {query} + // Provider-specific: OpenCode has built-in web search via Zen + toolInstruction: 'Search the web using your built-in capabilities.', -Provide a comprehensive summary with relevant URLs/sources.`, + // Optional quirks + quirks: null, }, grok: { @@ -66,13 +76,35 @@ Provide a comprehensive summary with relevant URLs/sources.`, model: 'grok-3', // Note: Grok CLI doesn't support model selection via CLI - // Prompt template - prompt: `Search the web for: {query} + // Provider-specific: Grok has web + X/Twitter search + toolInstruction: 'Use your web search capabilities to find information.', -Provide a comprehensive summary with relevant URLs/sources.`, + // Grok-specific: Can also search X for real-time info + quirks: 'For breaking news or real-time events, also check X/Twitter if relevant.', }, }; +/** + * Build the complete prompt for a provider + * Combines: query + tool instruction + shared instructions + quirks + */ +function buildPrompt(providerId, query) { + const config = PROVIDER_CONFIG[providerId]; + const parts = [ + `Search the web for: ${query}`, + '', + config.toolInstruction, + '', + SHARED_INSTRUCTIONS, + ]; + + if (config.quirks) { + parts.push('', `Note: ${config.quirks}`); + } + + return parts.join('\n'); +} + // Minimum response length to consider valid const MIN_VALID_RESPONSE_LENGTH = 20; @@ -224,7 +256,7 @@ function tryGeminiSearch(query, timeoutSec = DEFAULT_TIMEOUT_SEC) { try { const timeoutMs = timeoutSec * 1000; const config = PROVIDER_CONFIG.gemini; - const prompt = config.prompt.replace('{query}', query); + const prompt = buildPrompt('gemini', query); if (process.env.CCS_DEBUG) { console.error(`[CCS Hook] Executing: gemini --model ${config.model} --yolo -p "..."`); @@ -290,7 +322,7 @@ function tryOpenCodeSearch(query, timeoutSec = DEFAULT_TIMEOUT_SEC) { // Allow model override via env var const model = process.env.CCS_WEBSEARCH_OPENCODE_MODEL || config.model; - const prompt = config.prompt.replace('{query}', query); + const prompt = buildPrompt('opencode', query); if (process.env.CCS_DEBUG) { console.error(`[CCS Hook] Executing: opencode run --model ${model} "..."`); @@ -352,8 +384,7 @@ function tryOpenCodeSearch(query, timeoutSec = DEFAULT_TIMEOUT_SEC) { function tryGrokSearch(query, timeoutSec = DEFAULT_TIMEOUT_SEC) { try { const timeoutMs = timeoutSec * 1000; - const config = PROVIDER_CONFIG.grok; - const prompt = config.prompt.replace('{query}', query); + const prompt = buildPrompt('grok', query); if (process.env.CCS_DEBUG) { console.error('[CCS Hook] Executing: grok "..."');