-
Notifications
You must be signed in to change notification settings - Fork 16.4k
尝试provider(api)指令切换模型类型 #122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 14 commits
c9f95fc
fa5329d
21b2854
dfe25b1
affc826
4fa7582
7631c0f
3ae973c
e548369
ad10444
b5d1dbc
0c9fd37
c33d5dc
ec5dfed
130e4fb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,109 @@ | ||||||||||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+22
to
+29
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Type mismatch:
🛡️ Suggested fix-function getMergedEnv(): Record<string, string> {
+function getMergedEnv(): Record<string, string | undefined> {
const settings = getSettings_DEPRECATED()
- const merged = { ...process.env }
+ const merged: Record<string, string | undefined> = { ...process.env }
if (settings?.env) {
Object.assign(merged, settings.env)
}
return merged
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+42
to
+43
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle All writes ignore 🛠️ Proposed fix pattern- updateSettingsForSource('userSettings', { modelType: undefined })
+ const unsetResult = updateSettingsForSource('userSettings', {
+ modelType: undefined,
+ })
+ if (unsetResult.error) {
+ return {
+ type: 'text',
+ value: `Failed to clear API provider: ${unsetResult.error.message}`,
+ }
+ }Also applies to: 63-64, 83-85 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
| 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.`, | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+68
to
+77
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clear cloud-provider toggles in the early OpenAI warning path. When env vars are missing, this branch returns early and leaves prior cloud flags intact, which can keep the effective provider on bedrock/vertex/foundry. 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // 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}.` } | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+83
to
+92
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Provider env toggles can be overwritten by You mutate Also applies to: 92-95 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||
| // Cloud providers: set env vars only, do NOT touch 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' | ||||||||||||||||||||||||||||||||||
| // Do not modify settings.json - cloud providers controlled solely by env vars | ||||||||||||||||||||||||||||||||||
| applyConfigEnvironmentVariables() | ||||||||||||||||||||||||||||||||||
| return { type: 'text', value: `API provider set to ${arg} (via environment variable).` } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
coderabbitai[bot] marked this conversation as resolved.
|
||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Use
src/*alias imports in this TypeScript file.These relative imports violate the repository import rule for TS files.
♻️ Proposed fix
As per coding guidelines, "
Usesrc/*path alias for imports in TypeScript files."📝 Committable suggestion
🤖 Prompt for AI Agents