添加模型混合模式#439
Conversation
📝 WalkthroughWalkthroughPull request adds "mix mode" enabling per-model-family API provider configuration. Users can enable mix mode via CLI, then during OAuth setup select a provider for each model family (opus, sonnet, haiku). The system tracks selected providers in settings, applies family-specific environment variables at query time, and routes requests accordingly. ChangesMix Mode Feature Implementation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/commands.ts (1)
300-409:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDon't read mix state inside the memoized command registry.
Line 386 is only evaluated once per process because
COMMANDS()andloadAllCommands()are memoized. In a 3P session started with mix mode off,/mix truestill leaves/loginunavailable until caches are cleared or the app restarts, so the new flow breaks mid-session. Move this gate into a non-memoized filter, or invalidate the command memoization when mix mode changes.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/commands.ts` around lines 300 - 409, COMMANDS is memoized and currently captures isMixModeEnabled() at process-start, causing commands like login() to remain hidden when mix mode changes mid-session; update the implementation so the mix-mode gate is applied outside the memoized COMMANDS() (e.g., return the full memoized list from COMMANDS and filter [...(!isUsing3PServices() || isMixModeEnabled() ? [logout, login()] : [])] in the non-memoized loadAllCommands() or caller), or invalidate the memoization when mix mode toggles; specifically change where COMMANDS() is referenced (and where loadAllCommands() consumes it) to apply the isMixModeEnabled() conditional at runtime rather than inside the memoized COMMANDS function.
🧹 Nitpick comments (1)
src/components/ConsoleOAuthFlow.tsx (1)
97-99: ⚡ Quick win
getFamilyModelEnvKeyduplicates the key-generation pattern already inmix.ts.
mix.tshasgetConfiguredModelEnvKeys(family)that generates the same${PROVIDER}_DEFAULT_${FAMILY}_MODELpattern for all four providers. This local helper must be kept in sync manually.Consider exporting a targeted helper from
mix.ts(e.g.getFamilyEnvKeyForProvider) and importing it here.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/ConsoleOAuthFlow.tsx` around lines 97 - 99, The local getFamilyModelEnvKey duplicates logic already in mix.ts (see getConfiguredModelEnvKeys); remove the local getFamilyModelEnvKey and instead import a single exported helper from mix.ts (e.g. getFamilyEnvKeyForProvider or another targeted export you add) and replace all uses of getFamilyModelEnvKey with that imported function; ensure the imported helper signature accepts the same provider prefix type (e.g. 'ANTHROPIC' | 'OPENAI' | 'GEMINI' etc.) and ModelFamily so types line up with existing calls to getConfiguredModelEnvKeys.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/ConsoleOAuthFlow.tsx`:
- Around line 101-115: The function buildProviderSettingsPatch currently sets
process.env[MIX_MODE_ENV] = '1' prematurely, causing the in-memory env to be
mutated before the settings write via updateSettingsForSource succeeds; move the
env mutation out of buildProviderSettingsPatch and instead set
process.env[MIX_MODE_ENV] = '1' only after a confirmed successful call to
updateSettingsForSource in each caller (references: buildProviderSettingsPatch,
createMixedModelSettingsPatch, updateSettingsForSource, MIX_MODE_ENV), ensuring
rollback is not needed because the mutation happens post-save.
In `@src/services/api/claude.ts`:
- Around line 1101-1103: applyMixedModelConfigForModel is mutating process.env
via applyMixedModelConfigForFamily (and using module-level
mixedEnvOriginalValues/lastAppliedMixedEnvKeys), causing races when called
before async requests; change the flow so we do not mutate global env per
request: have applyMixedModelConfigForModel return a resolved config object (API
keys, base URL, model settings) and pass that config into getAPIProviderForModel
and into the async query path, or if returning a config is not feasible,
snapshot process.env/mixedEnvOriginalValues before calling and restore it
immediately after the entire async request completes (ensure restore is done in
finally), and update callers (the call site using applyMixedModelConfigForModel
and getAPIProviderForModel) to accept and use the explicit config instead of
relying on global env mutations.
In `@src/utils/model/mix.ts`:
- Around line 219-244: applyMixedModelConfigForFamily is currently deleting
every key from the global MIXED_PROVIDER_ENV_KEYS set (via getKeysToManage) even
when a family's config.env omits them, which silently clears user shell vars;
change the logic so getKeysToManage for this call only returns keys that are
either present in config.env or are known-to-be-used-by config.provider (i.e.,
intersect MIXED_PROVIDER_ENV_KEYS with Object.keys(config.env) or the
provider-specific key subset), then continue to call rememberOriginalEnvValue
and set/delete only that narrowed key list and update lastAppliedMixedEnvKeys
accordingly; reference functions/values: applyMixedModelConfigForFamily,
getKeysToManage, MIXED_PROVIDER_ENV_KEYS, config.env, providerToAPIProvider,
rememberOriginalEnvValue, lastAppliedMixedEnvKeys.
- Around line 126-131: stripModelTags currently uses the literal regex
/\[1m\]$/i which never matches ANSI escapes; update stripModelTags to first
strip ANSI SGR sequences using a proper regex like /\x1b\[[0-9;]*m/g (or
/\x1b\[[0-9;]*m$/ if only trimming trailing codes) and then perform
.toLowerCase() and .trim(); modify the replace call in stripModelTags to use
that ANSI regex and reorder operations so ANSI codes are removed before
lowercasing/trimming.
- Around line 265-279: createMixedModelSettingsPatch currently returns
mixedModelConfigs containing only the single family, so a top-level shallow
merge (e.g., in updateSettingsForSource) will replace any existing
mixedModelConfigs and drop other family entries; to fix, change
createMixedModelSettingsPatch to accept or retrieve the current
mixedModelConfigs and return a patch that spreads existing configs and then
overrides the single family (i.e., merged = { ...existingMixedModelConfigs,
[family]: { provider, env } }), and update callers such as
ConsoleOAuthFlow.buildProviderSettingsPatch to pass the current settings'
mixedModelConfigs into createMixedModelSettingsPatch so updates are additive
rather than destructive.
In `@src/utils/settings/settings.ts`:
- Around line 254-255: getUserSettingsFilePath currently returns only
'ccbsettings.json', causing existing settings in 'settings.json' or
'cowork_settings.json' to be ignored on upgrade; update getUserSettingsFilePath
to first check for and return an existing legacy path ('settings.json' or
'cowork_settings.json') before defaulting to 'ccbsettings.json', and implement a
one-time migration routine (invoked when legacy file exists and ccbsettings.json
is missing) that reads legacy userSettings, writes them into the new
format/file, and preserves auth/provider/model/permission entries; reference the
getUserSettingsFilePath function and the userSettings load/save code paths to
locate where to add the existence checks and migration call.
---
Outside diff comments:
In `@src/commands.ts`:
- Around line 300-409: COMMANDS is memoized and currently captures
isMixModeEnabled() at process-start, causing commands like login() to remain
hidden when mix mode changes mid-session; update the implementation so the
mix-mode gate is applied outside the memoized COMMANDS() (e.g., return the full
memoized list from COMMANDS and filter [...(!isUsing3PServices() ||
isMixModeEnabled() ? [logout, login()] : [])] in the non-memoized
loadAllCommands() or caller), or invalidate the memoization when mix mode
toggles; specifically change where COMMANDS() is referenced (and where
loadAllCommands() consumes it) to apply the isMixModeEnabled() conditional at
runtime rather than inside the memoized COMMANDS function.
---
Nitpick comments:
In `@src/components/ConsoleOAuthFlow.tsx`:
- Around line 97-99: The local getFamilyModelEnvKey duplicates logic already in
mix.ts (see getConfiguredModelEnvKeys); remove the local getFamilyModelEnvKey
and instead import a single exported helper from mix.ts (e.g.
getFamilyEnvKeyForProvider or another targeted export you add) and replace all
uses of getFamilyModelEnvKey with that imported function; ensure the imported
helper signature accepts the same provider prefix type (e.g. 'ANTHROPIC' |
'OPENAI' | 'GEMINI' etc.) and ModelFamily so types line up with existing calls
to getConfiguredModelEnvKeys.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2ba9e62b-1038-4541-af58-54b08398a661
📒 Files selected for processing (10)
src/commands.tssrc/commands/mix.tssrc/components/ConsoleOAuthFlow.tsxsrc/services/api/claude.tssrc/services/api/grok/client.tssrc/services/api/openai/client.tssrc/utils/model/mix.tssrc/utils/model/model.tssrc/utils/settings/settings.tssrc/utils/settings/types.ts
| function buildProviderSettingsPatch( | ||
| mixEnabled: boolean, | ||
| family: ModelFamily | null, | ||
| provider: MixedModelProvider, | ||
| env: Record<string, string>, | ||
| ): SettingsJson { | ||
| if (mixEnabled && family) { | ||
| process.env[MIX_MODE_ENV] = '1'; | ||
| return createMixedModelSettingsPatch(family, provider, env); | ||
| } | ||
| return { | ||
| modelType: provider, | ||
| env, | ||
| }; | ||
| } |
There was a problem hiding this comment.
buildProviderSettingsPatch mutates process.env before the settings write, leaving inconsistent state on failure.
process.env[MIX_MODE_ENV] = '1' (line 108) fires before updateSettingsForSource is called at every call site (lines 748, 956, 1177, 319). If the subsequent settings save returns an error, the env mutation is already committed with no rollback. The process will then believe mix mode is active (CCB_MIX=1) while the persisted settings file does not reflect it.
Move the env assignment to after a confirmed successful save:
🔧 Proposed fix
function buildProviderSettingsPatch(
mixEnabled: boolean,
family: ModelFamily | null,
provider: MixedModelProvider,
env: Record<string, string>,
): SettingsJson {
if (mixEnabled && family) {
- process.env[MIX_MODE_ENV] = '1';
return createMixedModelSettingsPatch(family, provider, env);
}
return {
modelType: provider,
env,
};
}Then at each successful-save branch (e.g. line 765):
} else {
for (const [k, v] of Object.entries(env)) process.env[k] = v;
+ process.env[MIX_MODE_ENV] = '1';
setOAuthStatus({ state: 'success' });
void onDone();
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/components/ConsoleOAuthFlow.tsx` around lines 101 - 115, The function
buildProviderSettingsPatch currently sets process.env[MIX_MODE_ENV] = '1'
prematurely, causing the in-memory env to be mutated before the settings write
via updateSettingsForSource succeeds; move the env mutation out of
buildProviderSettingsPatch and instead set process.env[MIX_MODE_ENV] = '1' only
after a confirmed successful call to updateSettingsForSource in each caller
(references: buildProviderSettingsPatch, createMixedModelSettingsPatch,
updateSettingsForSource, MIX_MODE_ENV), ensuring rollback is not needed because
the mutation happens post-save.
| const apiProvider = | ||
| applyMixedModelConfigForModel(options.model) ?? | ||
| getAPIProviderForModel(options.model) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
mix_file="$(fd -p '^mix\.ts$' src/utils/model | head -n1)"
echo "Inspecting: ${mix_file}"
sed -n '1,260p' "${mix_file}"
echo
echo "Helper definition and env mutation sites:"
rg -n -C3 'applyMixedModelConfigForModel|process\.env|Object\.assign\(process\.env' "${mix_file}" src/services/api/claude.tsRepository: claude-code-best/claude-code
Length of output: 147
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Searching for applyMixedModelConfigForModel function definition ==="
rg -n 'applyMixedModelConfigForModel' --type ts --type tsx
echo
echo "=== Checking src/services/api/claude.ts around lines 1101-1103 ==="
if [ -f "src/services/api/claude.ts" ]; then
sed -n '1095,1110p' src/services/api/claude.ts
fi
echo
echo "=== Listing files in src/utils/model/ ==="
find src/utils/model -type f 2>/dev/null || echo "Directory does not exist"
echo
echo "=== Searching for process.env mutations in the codebase ==="
rg -n 'process\.env\[|process\.env\.' --type ts --type tsx | head -30Repository: claude-code-best/claude-code
Length of output: 190
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Searching for applyMixedModelConfigForModel ==="
rg 'applyMixedModelConfigForModel'
echo
echo "=== Checking src/services/api/claude.ts around lines 1101-1103 ==="
if [ -f "src/services/api/claude.ts" ]; then
wc -l src/services/api/claude.ts
sed -n '1095,1110p' src/services/api/claude.ts
fi
echo
echo "=== Listing all files in src/utils/model/ ==="
find src/utils -type d -name model 2>/dev/null && find src/utils/model -type f 2>/dev/null || echo "No model directory found"
echo
echo "=== Searching for 'applyMixed' ==="
rg 'applyMixed'Repository: claude-code-best/claude-code
Length of output: 2364
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Reading src/utils/model/mix.ts ==="
wc -l src/utils/model/mix.ts
cat -n src/utils/model/mix.tsRepository: claude-code-best/claude-code
Length of output: 9562
Avoid per-request process.env mutation on the async query path.
applyMixedModelConfigForModel() mutates process.env directly (lines 219–244 in src/utils/model/mix.ts) via applyMixedModelConfigForFamily(). When called here before an async request, concurrent queries (main thread, agents, background tasks) will race on API keys, base URLs, and model settings. Request A may set the opus key, then Request B overwrites it with the sonnet key, leaving Request A using the wrong provider. The module-level state (mixedEnvOriginalValues, lastAppliedMixedEnvKeys) is shared across all requests and only restored on subsequent calls when mix mode is disabled—not after the current request completes. Pass the resolved config down explicitly as a parameter, or snapshot and restore around the entire async request, instead of relying on process-global env mutations.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/services/api/claude.ts` around lines 1101 - 1103,
applyMixedModelConfigForModel is mutating process.env via
applyMixedModelConfigForFamily (and using module-level
mixedEnvOriginalValues/lastAppliedMixedEnvKeys), causing races when called
before async requests; change the flow so we do not mutate global env per
request: have applyMixedModelConfigForModel return a resolved config object (API
keys, base URL, model settings) and pass that config into getAPIProviderForModel
and into the async query path, or if returning a config is not feasible,
snapshot process.env/mixedEnvOriginalValues before calling and restore it
immediately after the entire async request completes (ensure restore is done in
finally), and update callers (the call site using applyMixedModelConfigForModel
and getAPIProviderForModel) to accept and use the explicit config instead of
relying on global env mutations.
| function stripModelTags(model: string): string { | ||
| return model | ||
| .toLowerCase() | ||
| .replace(/\[1m\]$/i, '') | ||
| .trim() | ||
| } |
There was a problem hiding this comment.
stripModelTags regex never matches actual ANSI escape sequences.
/\[1m\]$/i matches the literal text [1m] (including a trailing ]) at the end of the string. ANSI bold is \x1b[1m — an ESC byte followed by [1m, with no trailing bracket. The regex either never fires, or silently targets an undocumented custom tag format.
If the intent is ANSI stripping, the fix is:
🔧 Proposed fix
function stripModelTags(model: string): string {
return model
.toLowerCase()
- .replace(/\[1m\]$/i, '')
+ .replace(/\x1b\[[\d;]*m/g, '')
.trim()
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function stripModelTags(model: string): string { | |
| return model | |
| .toLowerCase() | |
| .replace(/\[1m\]$/i, '') | |
| .trim() | |
| } | |
| function stripModelTags(model: string): string { | |
| return model | |
| .toLowerCase() | |
| .replace(/\x1b\[[\d;]*m/g, '') | |
| .trim() | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/utils/model/mix.ts` around lines 126 - 131, stripModelTags currently uses
the literal regex /\[1m\]$/i which never matches ANSI escapes; update
stripModelTags to first strip ANSI SGR sequences using a proper regex like
/\x1b\[[0-9;]*m/g (or /\x1b\[[0-9;]*m$/ if only trimming trailing codes) and
then perform .toLowerCase() and .trim(); modify the replace call in
stripModelTags to use that ANSI regex and reorder operations so ANSI codes are
removed before lowercasing/trimming.
| export function applyMixedModelConfigForFamily( | ||
| family: ModelFamily, | ||
| settings: Pick< | ||
| SettingsJson, | ||
| 'mix' | 'mixedModelConfigs' | ||
| > = getSettings_DEPRECATED() || {}, | ||
| ): APIProvider | undefined { | ||
| if (!isMixModeEnabled(settings)) return undefined | ||
| const config = getMixedModelConfig(family, settings) | ||
| if (!config) return undefined | ||
|
|
||
| const env = config.env || {} | ||
| const keysToManage = getKeysToManage(env) | ||
| for (const key of keysToManage) { | ||
| rememberOriginalEnvValue(key) | ||
| const value = env[key] | ||
| if (value === undefined) { | ||
| delete process.env[key] | ||
| } else { | ||
| process.env[key] = value | ||
| } | ||
| } | ||
| lastAppliedMixedEnvKeys = keysToManage | ||
|
|
||
| return providerToAPIProvider(config.provider) | ||
| } |
There was a problem hiding this comment.
applyMixedModelConfigForFamily unconditionally deletes every MIXED_PROVIDER_ENV_KEYS entry not present in the family's config, silently clearing user-set shell env vars.
getKeysToManage always unions in all 30+ MIXED_PROVIDER_ENV_KEYS. Any key not present in config.env is deleted from process.env (line 236). A user who sets ANTHROPIC_API_KEY in their shell and then configures, say, sonnet→gemini will have their key silently removed for the duration of the call. The restore logic is correct for sequential usage, but any synchronous code between applyMixedModelConfigForFamily and the API call that reads those vars will see them absent.
If the intent is only to isolate the active family, consider narrowing the managed key set to only the keys relevant to the active provider rather than all MIXED_PROVIDER_ENV_KEYS.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/utils/model/mix.ts` around lines 219 - 244,
applyMixedModelConfigForFamily is currently deleting every key from the global
MIXED_PROVIDER_ENV_KEYS set (via getKeysToManage) even when a family's
config.env omits them, which silently clears user shell vars; change the logic
so getKeysToManage for this call only returns keys that are either present in
config.env or are known-to-be-used-by config.provider (i.e., intersect
MIXED_PROVIDER_ENV_KEYS with Object.keys(config.env) or the provider-specific
key subset), then continue to call rememberOriginalEnvValue and set/delete only
that narrowed key list and update lastAppliedMixedEnvKeys accordingly; reference
functions/values: applyMixedModelConfigForFamily, getKeysToManage,
MIXED_PROVIDER_ENV_KEYS, config.env, providerToAPIProvider,
rememberOriginalEnvValue, lastAppliedMixedEnvKeys.
| export function createMixedModelSettingsPatch( | ||
| family: ModelFamily, | ||
| provider: MixedModelProvider, | ||
| env: Record<string, string>, | ||
| ): Pick<SettingsJson, 'mix' | 'mixedModelConfigs'> { | ||
| return { | ||
| mix: true, | ||
| mixedModelConfigs: { | ||
| [family]: { | ||
| provider, | ||
| env, | ||
| }, | ||
| }, | ||
| } | ||
| } |
There was a problem hiding this comment.
createMixedModelSettingsPatch produces a single-family patch — existing family configs will be lost if the settings layer does a shallow merge.
The returned object only contains mixedModelConfigs: { [family]: {...} }. If updateSettingsForSource applies a top-level shallow merge, the entire mixedModelConfigs key is replaced with just the one new entry. A user configuring opus and then sonnet ends up with only the sonnet configuration persisted.
A defensive fix is to spread the existing configs into the patch:
🔧 Proposed fix
export function createMixedModelSettingsPatch(
family: ModelFamily,
provider: MixedModelProvider,
env: Record<string, string>,
+ existingConfigs?: SettingsJson['mixedModelConfigs'],
): Pick<SettingsJson, 'mix' | 'mixedModelConfigs'> {
return {
mix: true,
mixedModelConfigs: {
+ ...existingConfigs,
[family]: {
provider,
env,
},
},
}
}In ConsoleOAuthFlow.tsx buildProviderSettingsPatch, pass the current settings configs:
- return createMixedModelSettingsPatch(family, provider, env);
+ return createMixedModelSettingsPatch(
+ family,
+ provider,
+ env,
+ (getSettings_DEPRECATED() || {}).mixedModelConfigs,
+ );📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export function createMixedModelSettingsPatch( | |
| family: ModelFamily, | |
| provider: MixedModelProvider, | |
| env: Record<string, string>, | |
| ): Pick<SettingsJson, 'mix' | 'mixedModelConfigs'> { | |
| return { | |
| mix: true, | |
| mixedModelConfigs: { | |
| [family]: { | |
| provider, | |
| env, | |
| }, | |
| }, | |
| } | |
| } | |
| export function createMixedModelSettingsPatch( | |
| family: ModelFamily, | |
| provider: MixedModelProvider, | |
| env: Record<string, string>, | |
| existingConfigs?: SettingsJson['mixedModelConfigs'], | |
| ): Pick<SettingsJson, 'mix' | 'mixedModelConfigs'> { | |
| return { | |
| mix: true, | |
| mixedModelConfigs: { | |
| ...(existingConfigs || {}), | |
| [family]: { | |
| provider, | |
| env, | |
| }, | |
| }, | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/utils/model/mix.ts` around lines 265 - 279, createMixedModelSettingsPatch
currently returns mixedModelConfigs containing only the single family, so a
top-level shallow merge (e.g., in updateSettingsForSource) will replace any
existing mixedModelConfigs and drop other family entries; to fix, change
createMixedModelSettingsPatch to accept or retrieve the current
mixedModelConfigs and return a patch that spreads existing configs and then
overrides the single family (i.e., merged = { ...existingMixedModelConfigs,
[family]: { provider, env } }), and update callers such as
ConsoleOAuthFlow.buildProviderSettingsPatch to pass the current settings'
mixedModelConfigs into createMixedModelSettingsPatch so updates are additive
rather than destructive.
| function getUserSettingsFilePath(): string { | ||
| if ( | ||
| getUseCoworkPlugins() || | ||
| isEnvTruthy(process.env.CLAUDE_CODE_USE_COWORK_PLUGINS) | ||
| ) { | ||
| return 'cowork_settings.json' | ||
| } | ||
| return 'settings.json' | ||
| return 'ccbsettings.json' |
There was a problem hiding this comment.
Preserve existing user settings on upgrade.
Line 255 makes userSettings resolve only to ccbsettings.json. That means an upgrade stops reading the current settings.json / cowork_settings.json, so saved auth, provider, model, and permission settings disappear until the user manually recreates them. Please add a fallback or one-time migration when the new file is missing.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/utils/settings/settings.ts` around lines 254 - 255,
getUserSettingsFilePath currently returns only 'ccbsettings.json', causing
existing settings in 'settings.json' or 'cowork_settings.json' to be ignored on
upgrade; update getUserSettingsFilePath to first check for and return an
existing legacy path ('settings.json' or 'cowork_settings.json') before
defaulting to 'ccbsettings.json', and implement a one-time migration routine
(invoked when legacy file exists and ccbsettings.json is missing) that reads
legacy userSettings, writes them into the new format/file, and preserves
auth/provider/model/permission entries; reference the getUserSettingsFilePath
function and the userSettings load/save code paths to locate where to add the
existence checks and migration call.
--修改配置文件为ccbsettings.json避免原配置文件冲突
--增加/mix命令
/mix true 开启模型混合模式
/mix false 关闭
/mix status 查看状态
--mix 模式开启后 Opus / Sonnet / Haiku 可以分别通过 /login 配置各自的 provider、API URL、API key 和模型名
-- 配置写入 ccbsettings.json
-- 配置完成后可以同时使用三个不同厂商的模型
Need help on this PR? Tag
@codesmithwith what you need.Summary by CodeRabbit
Release Notes
New Features
mixcommand to enable, disable, or check mixed-model mode statusImprovements