fix(grok): default client tool caching on for Free accounts

This commit is contained in:
superman2003
2026-07-19 18:59:50 +08:00
parent eea02c38fc
commit c8ff478876
6 changed files with 176 additions and 38 deletions
@@ -2768,7 +2768,9 @@ const headerOverrideCapable = computed(
// Grok OAuth 自定义上游地址(仅转发端点;OAuth 授权/令牌刷新不受影响)
const grokOAuthCustomBaseUrlEnabled = ref(false)
const grokOAuthBaseUrl = ref('')
const grokClientToolCacheEnabled = ref(false)
// Grok Free OAuth accounts use client-tool prompt caching by default. Keep an
// explicit false in the account extra as the opt-out signal.
const grokClientToolCacheEnabled = ref(true)
const interceptWarmupRequests = ref(false)
const autoPauseOnExpired = ref(false)
@@ -3424,10 +3426,14 @@ const syncFormFromAccount = (newAccount: Account | null) => {
// Load Grok OAuth custom upstream URL state(存储的官方地址视同未定制)
grokOAuthCustomBaseUrlEnabled.value = false
grokOAuthBaseUrl.value = ''
const grokClientToolCacheSetting =
newAccount.platform === 'grok' && newAccount.type === 'oauth'
? newAccount.extra?.[GROK_CLIENT_TOOL_CACHE_EXTRA_KEY]
: undefined
grokClientToolCacheEnabled.value =
newAccount.platform === 'grok' &&
newAccount.type === 'oauth' &&
newAccount.extra?.[GROK_CLIENT_TOOL_CACHE_EXTRA_KEY] === true
(grokClientToolCacheSetting === undefined || grokClientToolCacheSetting === true)
if (newAccount.platform === 'grok' && newAccount.type === 'oauth' && newAccount.credentials) {
const grokCreds = newAccount.credentials as Record<string, unknown>
if (isCustomGrokBaseUrl(grokCreds.base_url)) {
@@ -4318,11 +4324,9 @@ const handleSubmit = async () => {
const newExtra: Record<string, unknown> = {
...((props.account.extra as Record<string, unknown>) || {})
}
if (grokClientToolCacheEnabled.value) {
newExtra[GROK_CLIENT_TOOL_CACHE_EXTRA_KEY] = true
} else {
delete newExtra[GROK_CLIENT_TOOL_CACHE_EXTRA_KEY]
}
// Persist both states so a disabled account remains opted out when the
// backend applies the default-enabled policy to missing values.
newExtra[GROK_CLIENT_TOOL_CACHE_EXTRA_KEY] = grokClientToolCacheEnabled.value
updatePayload.extra = newExtra
}
@@ -264,18 +264,17 @@ describe('EditAccountModal Grok OAuth upstream config', () => {
const payload = updateAccountMock.mock.calls[0]?.[1]
expect(payload?.extra?.custom_setting).toBe('keep-me')
expect(payload?.extra).not.toHaveProperty('grok_client_tool_cache_enabled')
expect(payload?.extra?.grok_client_tool_cache_enabled).toBe(false)
})
it('enables client-tool caching while preserving unrelated extra fields', async () => {
it('defaults client-tool caching on when the setting is missing and persists explicit true', async () => {
const account = buildGrokOAuthAccount({}, { custom_setting: 'keep-me' })
updateAccountMock.mockResolvedValue(account)
const wrapper = mountModal(account)
const toggle = wrapper.get('[data-testid="grok-client-tool-cache-toggle"]')
expect(toggle.attributes('aria-checked')).toBe('false')
expect(toggle.attributes('aria-checked')).toBe('true')
await toggle.trigger('click')
await wrapper.get('form#edit-account-form').trigger('submit.prevent')
await vi.waitFor(() => expect(updateAccountMock).toHaveBeenCalledTimes(1))
@@ -285,4 +284,43 @@ describe('EditAccountModal Grok OAuth upstream config', () => {
custom_setting: 'keep-me'
})
})
it('keeps an explicit false opt-out when saving an untouched account', async () => {
const account = buildGrokOAuthAccount(
{},
{
grok_client_tool_cache_enabled: false,
custom_setting: 'keep-me'
}
)
updateAccountMock.mockResolvedValue(account)
const wrapper = mountModal(account)
const toggle = wrapper.get('[data-testid="grok-client-tool-cache-toggle"]')
expect(toggle.attributes('aria-checked')).toBe('false')
await wrapper.get('form#edit-account-form').trigger('submit.prevent')
await vi.waitFor(() => expect(updateAccountMock).toHaveBeenCalledTimes(1))
const payload = updateAccountMock.mock.calls[0]?.[1]
expect(payload?.extra).toMatchObject({
grok_client_tool_cache_enabled: false,
custom_setting: 'keep-me'
})
})
it('shows malformed cache settings as disabled so the UI matches the fail-closed backend', () => {
const account = buildGrokOAuthAccount(
{},
{
grok_client_tool_cache_enabled: 'true',
custom_setting: 'keep-me'
}
)
const wrapper = mountModal(account)
expect(
wrapper.get('[data-testid="grok-client-tool-cache-toggle"]').attributes('aria-checked')
).toBe('false')
})
})
@@ -643,7 +643,7 @@ export default {
},
grokClientToolCache: {
title: 'Client Tool Cache (May Change Automatic Tool Selection)',
hint: 'For detected Grok Free OAuth accounts, enable upstream prompt caching for client function tools such as Codex and Trae. Enable only after confirming the automatic tool-selection behavior is acceptable.'
hint: 'For detected Grok Free OAuth accounts, this is enabled by default for client function tools such as Codex and Trae. Turn it off to opt out if the automatic tool-selection behavior is not acceptable.'
},
autoPauseOnExpired: 'Auto Pause On Expired',
autoPauseOnExpiredDesc: 'When enabled, the account will auto pause scheduling after it expires',
@@ -736,7 +736,7 @@ export default {
},
grokClientToolCache: {
title: '客户端工具缓存(可能改变自动工具选择)',
hint: '仅对已识别为 Free 的 Grok OAuth 账号生效,为 Codex、Trae 等客户端函数工具请求启用上游提示缓存;请确认自动工具选择行为可接受后开启。'
hint: '仅对已识别为 Free 的 Grok OAuth 账号生效,默认会为 Codex、Trae 等客户端函数工具请求启用上游提示缓存;如不接受自动工具选择行为,可关闭此开关退出。'
},
autoPauseOnExpired: '过期自动暂停调度',
autoPauseOnExpiredDesc: '启用后,账号过期将自动暂停调度',