fix(frontend): edit grok oauth model mapping

This commit is contained in:
Heatherm Huang
2026-07-03 19:43:54 +08:00
parent 2b462b07de
commit b2687b2258
4 changed files with 86 additions and 11 deletions
@@ -419,9 +419,9 @@
</div>
<!-- OpenAI OAuth Model Mapping (OAuth 类型没有 apikey 容器,需要独立的模型映射区域) -->
<!-- OpenAI/Grok OAuth Model Mapping (OAuth 类型没有 apikey 容器,需要独立的模型映射区域) -->
<div
v-if="account.platform === 'openai' && account.type === 'oauth'"
v-if="(account.platform === 'openai' || account.platform === 'grok') && account.type === 'oauth'"
class="border-t border-gray-200 pt-4 dark:border-dark-600"
>
<label class="input-label">{{ t('admin.accounts.modelRestriction') }}</label>
@@ -3244,8 +3244,8 @@ const syncFormFromAccount = (newAccount: Account | null) => {
: 'https://api.anthropic.com'
editBaseUrl.value = platformDefaultUrl
// Load model mappings for OpenAI OAuth accounts
if (newAccount.platform === 'openai' && newAccount.credentials) {
// Load model mappings for OpenAI/Grok OAuth accounts
if ((newAccount.platform === 'openai' || newAccount.platform === 'grok') && newAccount.credentials) {
const oauthCredentials = newAccount.credentials as Record<string, unknown>
loadModelRestrictionFromMapping(oauthCredentials.model_mapping as Record<string, unknown> | undefined)
} else {
@@ -3972,14 +3972,23 @@ const handleSubmit = async () => {
updatePayload.credentials = newCredentials
}
// OpenAI OAuth: persist model mapping to credentials
if (props.account.platform === 'openai' && props.account.type === 'oauth') {
// OpenAI/Grok OAuth: persist model mapping to credentials
if ((props.account.platform === 'openai' || props.account.platform === 'grok') && props.account.type === 'oauth') {
const currentCredentials = isSparkShadow.value
? {}
: (updatePayload.credentials as Record<string, unknown>) ||
((props.account.credentials as Record<string, unknown>) || {})
const newCredentials: Record<string, unknown> = { ...currentCredentials }
applyOpenAIModelMappingCredentials(newCredentials)
if (props.account.platform === 'openai') {
applyOpenAIModelMappingCredentials(newCredentials)
} else {
const modelMapping = buildModelRestrictionMapping()
if (modelMapping) {
newCredentials.model_mapping = modelMapping
} else {
delete newCredentials.model_mapping
}
}
updatePayload.credentials = newCredentials
}
@@ -241,6 +241,32 @@ function buildAntigravityAccount(projectId = 'configured-project') {
} as any
}
function buildGrokOAuthAccount() {
return {
id: 5,
name: 'Grok OAuth',
notes: '',
platform: 'grok',
type: 'oauth',
credentials: {
refresh_token: 'grok-rt',
base_url: 'https://api.x.ai/v1',
model_mapping: {
'grok-latest': 'grok-4.3'
}
},
extra: {},
proxy_id: null,
concurrency: 1,
priority: 1,
rate_multiplier: 1,
status: 'active',
group_ids: [],
expires_at: null,
auto_pause_on_expired: false
} as any
}
function buildOpenAISetupTokenAccount() {
return {
...buildAccount(),
@@ -357,6 +383,35 @@ describe('EditAccountModal', () => {
})
})
it('loads and submits Grok OAuth model mapping edits', async () => {
const account = buildGrokOAuthAccount()
updateAccountMock.mockReset()
checkMixedChannelRiskMock.mockReset()
checkMixedChannelRiskMock.mockResolvedValue({ has_risk: false })
updateAccountMock.mockResolvedValue(account)
const wrapper = mountModal(account)
expect(wrapper.text()).toContain('Imagine Image')
expect(wrapper.text()).toContain('Imagine Video')
const inputWithValue = (value: string) => {
const input = wrapper
.findAll('input')
.find((input) => (input.element as HTMLInputElement).value === value)
expect(input).toBeTruthy()
return input!
}
await inputWithValue('grok-latest').setValue('grok')
await inputWithValue('grok-4.3').setValue('grok-build-0.1')
await wrapper.get('form#edit-account-form').trigger('submit.prevent')
expect(updateAccountMock).toHaveBeenCalledTimes(1)
expect(updateAccountMock.mock.calls[0]?.[1]?.credentials?.model_mapping).toEqual({
grok: 'grok-build-0.1'
})
})
it('only submits model mapping credentials when saving an OpenAI spark shadow account', async () => {
authIsSimpleMode.value = false
const account = buildOpenAISparkShadowAccount()