mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-31 16:26:30 +00:00
fix(anthropic): 支持 API Key Bearer 认证方式
This commit is contained in:
@@ -2653,6 +2653,24 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="form.platform === 'anthropic' && accountCategory === 'apikey'"
|
||||
class="border-t border-gray-200 pt-4 dark:border-dark-600"
|
||||
>
|
||||
<div class="flex items-center justify-between gap-4">
|
||||
<div>
|
||||
<label class="input-label mb-0">{{ t('admin.accounts.anthropic.apiKeyAuthScheme') }}</label>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
{{ t('admin.accounts.anthropic.apiKeyAuthSchemeDesc') }}
|
||||
</p>
|
||||
</div>
|
||||
<select v-model="anthropicAPIKeyAuthScheme" class="input w-52 text-sm">
|
||||
<option value="x_api_key">{{ t('admin.accounts.anthropic.apiKeyAuthSchemeXApiKey') }}</option>
|
||||
<option value="authorization_bearer">{{ t('admin.accounts.anthropic.apiKeyAuthSchemeBearer') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Anthropic API Key: Web Search Emulation (hidden when global disabled) -->
|
||||
<div
|
||||
v-if="form.platform === 'anthropic' && accountCategory === 'apikey' && webSearchGlobalEnabled"
|
||||
@@ -3503,7 +3521,9 @@ const openaiOAuthResponsesWebSocketV2Mode = ref<OpenAIWSMode>(OPENAI_WS_MODE_OFF
|
||||
const openaiAPIKeyResponsesWebSocketV2Mode = ref<OpenAIWSMode>(OPENAI_WS_MODE_OFF)
|
||||
const codexCLIOnlyEnabled = ref(false)
|
||||
const codexCLIOnlyAppServerEnabled = ref(false)
|
||||
type AnthropicAPIKeyAuthScheme = 'x_api_key' | 'authorization_bearer'
|
||||
const anthropicPassthroughEnabled = ref(false)
|
||||
const anthropicAPIKeyAuthScheme = ref<AnthropicAPIKeyAuthScheme>('x_api_key')
|
||||
const webSearchEmulationMode = ref('default')
|
||||
const webSearchGlobalEnabled = ref(false)
|
||||
const {
|
||||
@@ -3945,6 +3965,7 @@ watch(
|
||||
}
|
||||
if (newPlatform !== 'anthropic') {
|
||||
anthropicPassthroughEnabled.value = false
|
||||
anthropicAPIKeyAuthScheme.value = 'x_api_key'
|
||||
webSearchEmulationMode.value = 'default'
|
||||
}
|
||||
// Reset OAuth states
|
||||
@@ -3967,6 +3988,7 @@ watch(
|
||||
}
|
||||
if (platform !== 'anthropic' || category !== 'apikey') {
|
||||
anthropicPassthroughEnabled.value = false
|
||||
anthropicAPIKeyAuthScheme.value = 'x_api_key'
|
||||
webSearchEmulationMode.value = 'default'
|
||||
}
|
||||
}
|
||||
@@ -4346,6 +4368,7 @@ const resetForm = () => {
|
||||
codexCLIOnlyEnabled.value = false
|
||||
codexCLIOnlyAppServerEnabled.value = false
|
||||
anthropicPassthroughEnabled.value = false
|
||||
anthropicAPIKeyAuthScheme.value = 'x_api_key'
|
||||
webSearchEmulationMode.value = 'default'
|
||||
// Reset quota control state
|
||||
windowCostEnabled.value = false
|
||||
@@ -4465,6 +4488,11 @@ const buildAnthropicExtra = (base?: Record<string, unknown>): Record<string, unk
|
||||
} else {
|
||||
delete extra.anthropic_passthrough
|
||||
}
|
||||
if (anthropicAPIKeyAuthScheme.value === 'authorization_bearer') {
|
||||
extra.anthropic_apikey_auth_scheme = 'authorization_bearer'
|
||||
} else {
|
||||
delete extra.anthropic_apikey_auth_scheme
|
||||
}
|
||||
if (webSearchEmulationMode.value === 'default') {
|
||||
delete extra.web_search_emulation
|
||||
} else {
|
||||
|
||||
@@ -1537,6 +1537,24 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="account?.platform === 'anthropic' && account?.type === 'apikey'"
|
||||
class="border-t border-gray-200 pt-4 dark:border-dark-600"
|
||||
>
|
||||
<div class="flex items-center justify-between gap-4">
|
||||
<div>
|
||||
<label class="input-label mb-0">{{ t('admin.accounts.anthropic.apiKeyAuthScheme') }}</label>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
{{ t('admin.accounts.anthropic.apiKeyAuthSchemeDesc') }}
|
||||
</p>
|
||||
</div>
|
||||
<select v-model="anthropicAPIKeyAuthScheme" class="input w-52 text-sm">
|
||||
<option value="x_api_key">{{ t('admin.accounts.anthropic.apiKeyAuthSchemeXApiKey') }}</option>
|
||||
<option value="authorization_bearer">{{ t('admin.accounts.anthropic.apiKeyAuthSchemeBearer') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Anthropic API Key: Web Search Emulation (hidden when global disabled) -->
|
||||
<div
|
||||
v-if="account?.platform === 'anthropic' && account?.type === 'apikey' && webSearchGlobalEnabled"
|
||||
@@ -2610,7 +2628,9 @@ const codexCLIOnlyEnabled = ref(false)
|
||||
const codexCLIOnlyAppServerEnabled = ref(false)
|
||||
type CodexImageGenerationBridgeMode = 'inherit' | 'enabled' | 'disabled'
|
||||
const codexImageGenerationBridgeMode = ref<CodexImageGenerationBridgeMode>('inherit')
|
||||
type AnthropicAPIKeyAuthScheme = 'x_api_key' | 'authorization_bearer'
|
||||
const anthropicPassthroughEnabled = ref(false)
|
||||
const anthropicAPIKeyAuthScheme = ref<AnthropicAPIKeyAuthScheme>('x_api_key')
|
||||
const webSearchEmulationMode = ref('default')
|
||||
const webSearchGlobalEnabled = ref(false)
|
||||
const {
|
||||
@@ -3015,6 +3035,7 @@ const syncFormFromAccount = (newAccount: Account | null) => {
|
||||
codexCLIOnlyAppServerEnabled.value = false
|
||||
codexImageGenerationBridgeMode.value = 'inherit'
|
||||
anthropicPassthroughEnabled.value = false
|
||||
anthropicAPIKeyAuthScheme.value = 'x_api_key'
|
||||
webSearchEmulationMode.value = 'default'
|
||||
if (newAccount.platform === 'openai' && (newAccount.type === 'oauth' || newAccount.type === 'apikey')) {
|
||||
openaiPassthroughEnabled.value = extra?.openai_passthrough === true || extra?.openai_oauth_passthrough === true
|
||||
@@ -3061,6 +3082,9 @@ const syncFormFromAccount = (newAccount: Account | null) => {
|
||||
}
|
||||
if (newAccount.platform === 'anthropic' && newAccount.type === 'apikey') {
|
||||
anthropicPassthroughEnabled.value = extra?.anthropic_passthrough === true
|
||||
anthropicAPIKeyAuthScheme.value = extra?.anthropic_apikey_auth_scheme === 'authorization_bearer'
|
||||
? 'authorization_bearer'
|
||||
: 'x_api_key'
|
||||
// 三态:string "default"/"enabled"/"disabled",向后兼容旧 bool
|
||||
const wsVal = extra?.web_search_emulation
|
||||
if (wsVal === 'enabled' || wsVal === 'disabled') {
|
||||
@@ -4101,6 +4125,11 @@ const handleSubmit = async () => {
|
||||
} else {
|
||||
delete newExtra.anthropic_passthrough
|
||||
}
|
||||
if (anthropicAPIKeyAuthScheme.value === 'authorization_bearer') {
|
||||
newExtra.anthropic_apikey_auth_scheme = 'authorization_bearer'
|
||||
} else {
|
||||
delete newExtra.anthropic_apikey_auth_scheme
|
||||
}
|
||||
if (webSearchEmulationMode.value === 'default') {
|
||||
delete newExtra.web_search_emulation
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user