mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-21 15:55:50 +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 chrome from './commands/chrome/index.js'
|
||||||
import stickers from './commands/stickers/index.js'
|
import stickers from './commands/stickers/index.js'
|
||||||
import advisor from './commands/advisor.js'
|
import advisor from './commands/advisor.js'
|
||||||
|
import provider from './commands/provider.js'
|
||||||
import { logError } from './utils/log.js'
|
import { logError } from './utils/log.js'
|
||||||
import { toError } from './utils/errors.js'
|
import { toError } from './utils/errors.js'
|
||||||
import { logForDebugging } from './utils/debug.js'
|
import { logForDebugging } from './utils/debug.js'
|
||||||
@@ -258,6 +259,7 @@ export const INTERNAL_ONLY_COMMANDS = [
|
|||||||
const COMMANDS = memoize((): Command[] => [
|
const COMMANDS = memoize((): Command[] => [
|
||||||
addDir,
|
addDir,
|
||||||
advisor,
|
advisor,
|
||||||
|
provider,
|
||||||
agents,
|
agents,
|
||||||
branch,
|
branch,
|
||||||
btw,
|
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)
|
// 1. Check settings.json modelType field (highest priority)
|
||||||
const modelType = getInitialSettings().modelType
|
const modelType = getInitialSettings().modelType
|
||||||
if (modelType === 'openai') return 'openai'
|
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)
|
// 2. Check environment variables (backward compatibility)
|
||||||
return isEnvTruthy(process.env.CLAUDE_CODE_USE_OPENAI)
|
return isEnvTruthy(process.env.CLAUDE_CODE_USE_OPENAI)
|
||||||
|
|||||||
Reference in New Issue
Block a user