From 6bd1f420d994e799125f338940689e969e524991 Mon Sep 17 00:00:00 2001 From: kaitranntt Date: Thu, 18 Dec 2025 00:27:40 -0500 Subject: [PATCH] fix(websearch): pass through to native WebSearch for account profiles WebSearch hook was blocking native Claude accounts (ccs ck, default) with "No Providers Enabled" message instead of passing through to server-side WebSearch. Changes: - Add shouldSkipHook() detection for account/default profile types - Fix blocking bug: exit(0) when no providers enabled instead of blocking - Pass CCS_PROFILE_TYPE and CCS_WEBSEARCH_SKIP env vars for profile-aware behavior - Add profile type signals to settings, cliproxy, account, and default execution paths --- lib/hooks/websearch-transformer.cjs | 31 +++++++++++++++++++++-------- src/ccs.ts | 28 ++++++++++++++++++++++---- src/cliproxy/cliproxy-executor.ts | 7 ++++++- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/lib/hooks/websearch-transformer.cjs b/lib/hooks/websearch-transformer.cjs index 4384a63c..84d9f8d7 100644 --- a/lib/hooks/websearch-transformer.cjs +++ b/lib/hooks/websearch-transformer.cjs @@ -116,6 +116,24 @@ const DEFAULT_TIMEOUT_SEC = 55; // HOOK LOGIC - Generally no need to edit below // ============================================================================ +/** + * Determine if hook should skip and pass through to native WebSearch. + * Returns true for native Claude accounts where WebSearch works server-side. + */ +function shouldSkipHook() { + // Explicit skip signal (set by CCS for account profiles) + if (process.env.CCS_WEBSEARCH_SKIP === '1') return true; + + // Account/default profiles - use native WebSearch + const profileType = process.env.CCS_PROFILE_TYPE; + if (profileType === 'account' || profileType === 'default') return true; + + // Explicit disable + if (process.env.CCS_WEBSEARCH_ENABLED === '0') return true; + + return false; +} + // Read input from stdin let input = ''; process.stdin.setEncoding('utf8'); @@ -164,13 +182,8 @@ function isProviderEnabled(provider) { */ async function processHook() { try { - // Skip if disabled (for official Claude subscriptions) - if (process.env.CCS_WEBSEARCH_SKIP === '1') { - process.exit(0); - } - - // Check if enabled (default: enabled) - if (process.env.CCS_WEBSEARCH_ENABLED === '0') { + // Skip for native accounts (account, default profiles) or explicit disable + if (shouldSkipHook()) { process.exit(0); } @@ -238,7 +251,9 @@ async function processHook() { // All providers failed or none enabled if (enabledProviders.length === 0) { - outputNoProvidersEnabled(query); + // No providers enabled - pass through to native WebSearch + // This allows native Claude accounts to use server-side WebSearch + process.exit(0); } else { outputAllFailedMessage(query, errors); } diff --git a/src/ccs.ts b/src/ccs.ts index 3e1c22ef..437156a1 100644 --- a/src/ccs.ts +++ b/src/ccs.ts @@ -154,7 +154,12 @@ async function execClaudeWithProxy( const isWindows = process.platform === 'win32'; const needsShell = isWindows && /\.(cmd|bat|ps1)$/i.test(claudeCli); const webSearchEnv = getWebSearchHookEnv(); - const env = { ...process.env, ...envVars, ...webSearchEnv }; + const env = { + ...process.env, + ...envVars, + ...webSearchEnv, + CCS_PROFILE_TYPE: 'settings', // Signal to WebSearch hook this is a third-party provider + }; let claude: ChildProcess; if (needsShell) { @@ -401,7 +406,12 @@ async function main(): Promise { // EXISTING FLOW: Settings-based profile (glm, kimi) // Use --settings flag (backward compatible) const expandedSettingsPath = getSettingsPath(profileInfo.name); - execClaude(claudeCli, ['--settings', expandedSettingsPath, ...remainingArgs]); + const webSearchEnv = getWebSearchHookEnv(); + const envVars: NodeJS.ProcessEnv = { + ...webSearchEnv, + CCS_PROFILE_TYPE: 'settings', // Signal to WebSearch hook this is a third-party provider + }; + execClaude(claudeCli, ['--settings', expandedSettingsPath, ...remainingArgs], envVars); } } else if (profileInfo.type === 'account') { // NEW FLOW: Account-based profile (work, personal) @@ -420,11 +430,21 @@ async function main(): Promise { } // Execute Claude with instance isolation - const envVars: NodeJS.ProcessEnv = { CLAUDE_CONFIG_DIR: instancePath }; + // Skip WebSearch hook - account profiles use native server-side WebSearch + const envVars: NodeJS.ProcessEnv = { + CLAUDE_CONFIG_DIR: instancePath, + CCS_PROFILE_TYPE: 'account', + CCS_WEBSEARCH_SKIP: '1', + }; execClaude(claudeCli, remainingArgs, envVars); } else { // DEFAULT: No profile configured, use Claude's own defaults - execClaude(claudeCli, remainingArgs); + // Skip WebSearch hook - native Claude has server-side WebSearch + const envVars: NodeJS.ProcessEnv = { + CCS_PROFILE_TYPE: 'default', + CCS_WEBSEARCH_SKIP: '1', + }; + execClaude(claudeCli, remainingArgs, envVars); } } catch (error) { const err = error as ProfileError; diff --git a/src/cliproxy/cliproxy-executor.ts b/src/cliproxy/cliproxy-executor.ts index 3b69a2f6..f874a8dd 100644 --- a/src/cliproxy/cliproxy-executor.ts +++ b/src/cliproxy/cliproxy-executor.ts @@ -426,7 +426,12 @@ export async function execClaudeWithCLIProxy( // Uses custom settings path (for variants), user settings, or bundled defaults const envVars = getEffectiveEnvVars(provider, cfg.port, cfg.customSettingsPath); const webSearchEnv = getWebSearchHookEnv(); - const env = { ...process.env, ...envVars, ...webSearchEnv }; + const env = { + ...process.env, + ...envVars, + ...webSearchEnv, + CCS_PROFILE_TYPE: 'cliproxy', // Signal to WebSearch hook this is a third-party provider + }; log(`Claude env: ANTHROPIC_BASE_URL=${envVars.ANTHROPIC_BASE_URL}`); log(`Claude env: ANTHROPIC_MODEL=${envVars.ANTHROPIC_MODEL}`);