mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-15 12:55:51 +00:00
provider指令切换模型类型
This commit is contained in:
@@ -150,6 +150,7 @@ import sandboxToggle from './commands/sandbox-toggle/index.js'
|
||||
import chrome from './commands/chrome/index.js'
|
||||
import stickers from './commands/stickers/index.js'
|
||||
import advisor from './commands/advisor.js'
|
||||
import provider from './commands/provider.js'
|
||||
import { logError } from './utils/log.js'
|
||||
import { toError } from './utils/errors.js'
|
||||
import { logForDebugging } from './utils/debug.js'
|
||||
@@ -258,6 +259,7 @@ export const INTERNAL_ONLY_COMMANDS = [
|
||||
const COMMANDS = memoize((): Command[] => [
|
||||
addDir,
|
||||
advisor,
|
||||
provider,
|
||||
agents,
|
||||
branch,
|
||||
btw,
|
||||
|
||||
111
src/commands/provider.ts
Normal file
111
src/commands/provider.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import type { Command } from '../commands.js'
|
||||
import type { LocalCommandCall } from '../types/command.js'
|
||||
import { getAPIProvider } from '../utils/model/providers.js'
|
||||
import { updateSettingsForSource } from '../utils/settings/settings.js'
|
||||
import { getSettings_DEPRECATED } from '../utils/settings/settings.js'
|
||||
import { applyConfigEnvironmentVariables } from '../utils/managedEnv.js'
|
||||
|
||||
function getEnvVarForProvider(provider: string): string {
|
||||
switch (provider) {
|
||||
case 'bedrock':
|
||||
return 'CLAUDE_CODE_USE_BEDROCK'
|
||||
case 'vertex':
|
||||
return 'CLAUDE_CODE_USE_VERTEX'
|
||||
case 'foundry':
|
||||
return 'CLAUDE_CODE_USE_FOUNDRY'
|
||||
default:
|
||||
throw new Error(`Unknown provider: ${provider}`)
|
||||
}
|
||||
}
|
||||
|
||||
// Get merged env: process.env + settings.env (from userSettings)
|
||||
function getMergedEnv(): Record<string, string> {
|
||||
const settings = getSettings_DEPRECATED()
|
||||
const merged = { ...process.env }
|
||||
if (settings?.env) {
|
||||
Object.assign(merged, settings.env)
|
||||
}
|
||||
return merged
|
||||
}
|
||||
|
||||
const call: LocalCommandCall = async (args, context) => {
|
||||
const arg = args.trim().toLowerCase()
|
||||
|
||||
// No argument: show current provider
|
||||
if (!arg) {
|
||||
const current = getAPIProvider()
|
||||
return { type: 'text', value: `Current API provider: ${current}` }
|
||||
}
|
||||
|
||||
// unset - clear settings, fallback to env vars
|
||||
if (arg === 'unset') {
|
||||
updateSettingsForSource('userSettings', { modelType: undefined })
|
||||
// Also clear all provider-specific env vars to prevent conflicts
|
||||
delete process.env.CLAUDE_CODE_USE_BEDROCK
|
||||
delete process.env.CLAUDE_CODE_USE_VERTEX
|
||||
delete process.env.CLAUDE_CODE_USE_FOUNDRY
|
||||
delete process.env.CLAUDE_CODE_USE_OPENAI
|
||||
return { type: 'text', value: 'API provider cleared (will use environment variables).' }
|
||||
}
|
||||
|
||||
// Validate provider
|
||||
const validProviders = ['anthropic', 'openai', 'bedrock', 'vertex', 'foundry']
|
||||
if (!validProviders.includes(arg)) {
|
||||
return { type: 'text', value: `Invalid provider: ${arg}\nValid: ${validProviders.join(', ')}` }
|
||||
}
|
||||
|
||||
// Check env vars when switching to openai (including settings.env)
|
||||
if (arg === 'openai') {
|
||||
const mergedEnv = getMergedEnv()
|
||||
const hasKey = !!mergedEnv.OPENAI_API_KEY
|
||||
const hasUrl = !!mergedEnv.OPENAI_BASE_URL
|
||||
if (!hasKey || !hasUrl) {
|
||||
updateSettingsForSource('userSettings', { modelType: 'openai' })
|
||||
const missing = []
|
||||
if (!hasKey) missing.push('OPENAI_API_KEY')
|
||||
if (!hasUrl) missing.push('OPENAI_BASE_URL')
|
||||
return {
|
||||
type: 'text',
|
||||
value: `Switched to OpenAI provider.\nWarning: Missing env vars: ${missing.join(', ')}\nConfigure them via /login or set manually.`,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle different provider types
|
||||
// - 'anthropic' and 'openai' are stored in settings.json (persistent)
|
||||
// - 'bedrock', 'vertex', 'foundry' are env-only (do NOT touch settings.json)
|
||||
if (arg === 'anthropic' || arg === 'openai') {
|
||||
// Clear any cloud provider env vars to avoid conflicts
|
||||
delete process.env.CLAUDE_CODE_USE_BEDROCK
|
||||
delete process.env.CLAUDE_CODE_USE_VERTEX
|
||||
delete process.env.CLAUDE_CODE_USE_FOUNDRY
|
||||
// Update settings.json
|
||||
updateSettingsForSource('userSettings', { modelType: arg })
|
||||
// Ensure settings.env gets applied to process.env
|
||||
applyConfigEnvironmentVariables()
|
||||
return { type: 'text', value: `API provider set to ${arg}.` }
|
||||
} else {
|
||||
// Cloud providers: set env vars only, clear settings.modelType
|
||||
delete process.env.CLAUDE_CODE_USE_OPENAI
|
||||
delete process.env.OPENAI_API_KEY
|
||||
delete process.env.OPENAI_BASE_URL
|
||||
process.env[getEnvVarForProvider(arg)] = '1'
|
||||
// Clear settings.json to 'anthropic' to avoid validation errors
|
||||
updateSettingsForSource('userSettings', { modelType: 'anthropic' })
|
||||
// Ensure settings.env gets applied to process.env (in case it contains provider-specific creds)
|
||||
applyConfigEnvironmentVariables()
|
||||
return { type: 'text', value: `API provider set to ${arg} (via environment variable).` }
|
||||
}
|
||||
}
|
||||
|
||||
const provider = {
|
||||
type: 'local',
|
||||
name: 'provider',
|
||||
description: 'Switch API provider (anthropic/openai/bedrock/vertex/foundry)',
|
||||
aliases: ['api'],
|
||||
argumentHint: '[anthropic|openai|bedrock|vertex|foundry|unset]',
|
||||
supportsNonInteractive: true,
|
||||
load: () => Promise.resolve({ call }),
|
||||
} satisfies Command
|
||||
|
||||
export default provider
|
||||
@@ -8,6 +8,9 @@ export function getAPIProvider(): APIProvider {
|
||||
// 1. Check settings.json modelType field (highest priority)
|
||||
const modelType = getInitialSettings().modelType
|
||||
if (modelType === 'openai') return 'openai'
|
||||
if (modelType === 'bedrock') return 'bedrock'
|
||||
if (modelType === 'vertex') return 'vertex'
|
||||
if (modelType === 'foundry') return 'foundry'
|
||||
|
||||
// 2. Check environment variables (backward compatibility)
|
||||
return isEnvTruthy(process.env.CLAUDE_CODE_USE_OPENAI)
|
||||
|
||||
Reference in New Issue
Block a user