Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions src/services/api/claude.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1433,7 +1433,6 @@ async function* queryModel(
if (
!cacheEditingHeaderLatched &&
cachedMCEnabled &&
getAPIProvider() === 'firstParty' &&
options.querySource === 'repl_main_thread'
) {
cacheEditingHeaderLatched = true
Expand Down Expand Up @@ -1674,11 +1673,9 @@ async function* queryModel(
// the feature disables but the header doesn't flip.
const useCachedMC =
cachedMCEnabled &&
getAPIProvider() === 'firstParty' &&
options.querySource === 'repl_main_thread'
if (
cacheEditingHeaderLatched &&
getAPIProvider() === 'firstParty' &&
options.querySource === 'repl_main_thread' &&
!betasParams.includes(cacheEditingBetaHeader)
) {
Expand Down
24 changes: 5 additions & 19 deletions src/utils/betas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,7 @@ export function modelSupportsStructuredOutputs(model: string): boolean {
export function modelSupportsAutoMode(model: string): boolean {
if (feature('TRANSCRIPT_CLASSIFIER')) {
const m = getCanonicalName(model)
// External: firstParty-only at launch (PI probes not wired for
// Bedrock/Vertex/Foundry yet). Checked before allowModels so the GB
// override can't enable auto mode on unsupported providers.
if (process.env.USER_TYPE !== 'ant' && getAPIProvider() !== 'firstParty') {
return false
}
// NOTE: Removed firstParty check to allow custom proxies to use auto mode
// GrowthBook override: tengu_auto_mode_config.allowModels force-enables
// auto mode for listed models, bypassing the denylist/allowlist below.
// Exact model IDs (e.g. "claude-strudel-v6-p") match only that model;
Expand Down Expand Up @@ -212,23 +207,14 @@ export function getToolSearchBetaHeader(): string {
* These are betas that are only available on firstParty provider
* and may not be supported by proxies or other providers.
*/
// NOTE: Removed firstParty checks to allow custom proxies to use experimental betas
export function shouldIncludeFirstPartyOnlyBetas(): boolean {
return (
(getAPIProvider() === 'firstParty' || getAPIProvider() === 'foundry') &&
!isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS)
)
return !isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS)
}

/**
* Global-scope prompt caching is firstParty only. Foundry is excluded because
* GrowthBook never bucketed Foundry users into the rollout experiment — the
* treatment data is firstParty-only.
*/
// NOTE: Removed firstParty check to allow custom proxies to use global cache scope
export function shouldUseGlobalCacheScope(): boolean {
return (
getAPIProvider() === 'firstParty' &&
!isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS)
)
return !isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS)
}

export const getAllModelBetas = memoize((model: string): string[] => {
Expand Down
7 changes: 2 additions & 5 deletions src/utils/effort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { isUltrathinkEnabled } from './thinking.js'
import { getInitialSettings } from './settings/settings.js'
import { isProSubscriber, isMaxSubscriber, isTeamSubscriber } from './auth.js'
import { getFeatureValue_CACHED_MAY_BE_STALE } from 'src/services/analytics/growthbook.js'
import { getAPIProvider } from './model/providers.js'
import { get3PModelCapabilityOverride } from './model/modelSupportOverrides.js'
import { isEnvTruthy } from './envUtils.js'
import type { EffortLevel } from 'src/entrypoints/sdk/runtimeTypes.js'
Expand Down Expand Up @@ -42,10 +41,8 @@ export function modelSupportsEffort(model: string): boolean {
// the model launch DRI and research. This is a sensitive setting that can
// greatly affect model quality and bashing.

// Default to true for unknown model strings on 1P.
// Do not default to true for 3P as they have different formats for their
// model strings (ex. anthropics/claude-code#30795)
return getAPIProvider() === 'firstParty'
// NOTE: Removed firstParty check to allow custom proxies to use effort
return true
Comment on lines +44 to +45
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if there's error handling for effort parameter rejection in API calls
rg -n -C5 'effort.*reject|invalid.*effort|unsupported.*effort' --type=ts
# Check configureEffortParams error handling
ast-grep --pattern $'function configureEffortParams($$$) {
  $$$
}'

Repository: paoloanzn/free-code

Length of output: 3613


🏁 Script executed:

rg -n 'configureEffortParams' --type=ts -B2 -A5

Repository: paoloanzn/free-code

Length of output: 893


🏁 Script executed:

rg -n -C8 'configureEffortParams.*effort' --type=ts

Repository: paoloanzn/free-code

Length of output: 45


🏁 Script executed:

# Find claude.ts file location and check error handling around API calls
fd -name 'claude.ts' --type f

Repository: paoloanzn/free-code

Length of output: 293


🏁 Script executed:

# Check for try-catch blocks that might handle API errors related to effort
rg -n 'try\s*{' --type=ts -A10 | rg -B5 -A5 'effort|catch'

Repository: paoloanzn/free-code

Length of output: 140


🏁 Script executed:

# Get context around the configureEffortParams call at line 1562
sed -n '1540,1600p' src/services/api/claude.ts

Repository: paoloanzn/free-code

Length of output: 2243


🏁 Script executed:

# Find the actual API call and error handling
rg -n 'client\.(messages|beta|request)' src/services/api/claude.ts -A8 -B2

Repository: paoloanzn/free-code

Length of output: 45


🏁 Script executed:

# Check if there's a try-catch wrapping the API call
sed -n '1500,1700p' src/services/api/claude.ts | grep -n -C15 'try\|catch'

Repository: paoloanzn/free-code

Length of output: 6073


🏁 Script executed:

# Find where client makes the actual API call
rg -n 'client\.beta\.messages|client\.messages|\.create\(' src/services/api/claude.ts -A3 -B3 | head -60

Repository: paoloanzn/free-code

Length of output: 1022


🏁 Script executed:

# Check for error handling around the API call - look for try/catch patterns
sed -n '1650,1850p' src/services/api/claude.ts | head -80

Repository: paoloanzn/free-code

Length of output: 2701


🏁 Script executed:

# Look at the full configureEffortParams function to understand what it does
sed -n '440,480p' src/services/api/claude.ts

Repository: paoloanzn/free-code

Length of output: 1461


🏁 Script executed:

# Check the full try-catch block starting at line 862
sed -n '860,920p' src/services/api/claude.ts

Repository: paoloanzn/free-code

Length of output: 2173


🏁 Script executed:

# Check error handling around the streaming API call at line 1820
sed -n '1800,1900p' src/services/api/claude.ts

Repository: paoloanzn/free-code

Length of output: 3987


🏁 Script executed:

# Look for retry logic or error handling that might catch parameter rejection errors
rg -n 'catch.*Error|APIError|BadRequest|400' src/services/api/claude.ts -B3 -A5 | head -80

Repository: paoloanzn/free-code

Length of output: 2715


Unconditional return true may cause API errors on proxies that reject the effort parameter.

Custom proxies that don't recognize the effort parameter will receive 400 errors instead of silently ignoring it. While general error handling exists in the API call layer (try-catch and logging), there's no graceful degradation specific to parameter rejection. The get3PModelCapabilityOverride() escape hatch (lines 27-30) and CLAUDE_CODE_ALWAYS_ENABLE_EFFORT=0 exist, but users must proactively configure them.

Consider whether a more defensive default (e.g., return false for unknown models) with explicit opt-in would be safer, or ensure the error handling specifically detects and recovers from effort parameter rejection on custom proxies.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/effort.ts` around lines 44 - 45, The function currently
unconditionally returns true (allowing the effort parameter) which can cause 400
errors on proxies that reject it; change the logic in the function (referenced
as get3PModelCapabilityOverride and the current return true) to be defensive:
consult get3PModelCapabilityOverride(modelId) and the
CLAUDE_CODE_ALWAYS_ENABLE_EFFORT env flag first and only return true when those
explicitly indicate support, otherwise return false for unknown models; update
the function to default to false for unknown/unsupported models so proxies that
reject effort won’t receive it unless explicitly opted-in.

}

// @[MODEL LAUNCH]: Add the new model to the allowlist if it supports 'max' effort.
Expand Down
8 changes: 1 addition & 7 deletions src/utils/fastMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
type ModelSetting,
parseUserSpecifiedModel,
} from './model/model.js'
import { getAPIProvider } from './model/providers.js'
import { isEssentialTrafficOnly } from './privacyLevel.js'
import {
getInitialSettings,
Expand Down Expand Up @@ -109,12 +108,7 @@ export function getFastModeUnavailableReason(): string | null {
}
}

// Only available for 1P (not Bedrock/Vertex/Foundry)
if (getAPIProvider() !== 'firstParty') {
const reason = 'Fast mode is not available on Bedrock, Vertex, or Foundry'
logForDebugging(`Fast mode unavailable: ${reason}`)
return reason
}
// NOTE: Removed firstParty check to allow custom proxies to use fast mode

if (orgStatus.status === 'disabled') {
if (
Expand Down