fix(grok): resolve recent integration issues

This commit is contained in:
Heatherm Huang committed 2026-07-13 10:09:53 +08:00
1 parent 42f3c22830
commit 038b25c0b1
11 files changed
+388 -6

No files matched your search

+64 -1
View File
@@ -181,6 +181,8 @@ const defaultClientTab = computed(() => {
switch (props.platform) {
case 'openai':
return 'codex'
case 'grok':
return 'grok'
case 'gemini':
return 'gemini'
case 'antigravity':
@@ -288,6 +290,11 @@ const clientTabs = computed((): TabConfig[] => {
{ id: 'gemini', label: t('keys.useKeyModal.cliTabs.geminiCli'), icon: SparkleIcon },
{ id: 'opencode', label: t('keys.useKeyModal.cliTabs.opencode'), icon: TerminalIcon }
]
case 'grok':
return [
{ id: 'grok', label: t('keys.useKeyModal.cliTabs.grokCli'), icon: TerminalIcon },
{ id: 'opencode', label: t('keys.useKeyModal.cliTabs.opencode'), icon: TerminalIcon }
]
default:
return [
{ id: 'claude', label: t('keys.useKeyModal.cliTabs.claudeCode'), icon: TerminalIcon },
@@ -313,7 +320,7 @@ const showShellTabs = computed(() => activeClientTab.value !== 'opencode')
const currentTabs = computed(() => {
if (!showShellTabs.value) return []
if (activeClientTab.value === 'codex' || activeClientTab.value === 'codex-ws') {
if (activeClientTab.value === 'codex' || activeClientTab.value === 'codex-ws' || activeClientTab.value === 'grok') {
return openaiTabs
}
return shellTabs
@@ -330,6 +337,8 @@ const platformDescription = computed(() => {
return t('keys.useKeyModal.gemini.description')
case 'antigravity':
return t('keys.useKeyModal.antigravity.description')
case 'grok':
return t('keys.useKeyModal.grok.description')
default:
return t('keys.useKeyModal.description')
}
@@ -350,6 +359,10 @@ const platformNote = computed(() => {
return activeClientTab.value === 'claude'
? t('keys.useKeyModal.antigravity.claudeNote')
: t('keys.useKeyModal.antigravity.geminiNote')
case 'grok':
return activeTab.value === 'windows'
? t('keys.useKeyModal.grok.noteWindows')
: t('keys.useKeyModal.grok.note')
default:
return t('keys.useKeyModal.note')
}
@@ -407,6 +420,8 @@ const currentFiles = computed((): FileConfig[] => {
generateOpenCodeConfig('antigravity-claude', antigravityBase, apiKey, 'opencode.json (Claude)'),
generateOpenCodeConfig('antigravity-gemini', antigravityGeminiBase, apiKey, 'opencode.json (Gemini)')
]
case 'grok':
return [generateOpenCodeConfig('grok', apiBase, apiKey)]
default:
return [generateOpenCodeConfig('openai', apiBase, apiKey)]
}
@@ -428,6 +443,8 @@ const currentFiles = computed((): FileConfig[] => {
return [generateGeminiCliContent(`${baseUrl}/antigravity`, apiKey)]
}
return generateAnthropicFiles(`${baseUrl}/antigravity`, apiKey)
case 'grok':
return generateGrokFiles(apiBase, apiKey)
default:
return generateAnthropicFiles(baseUrl, apiKey)
}
@@ -568,6 +585,30 @@ goals = true`
]
}
function generateGrokFiles(baseUrl: string, apiKey: string): FileConfig[] {
const isWindows = activeTab.value === 'windows'
const configDir = isWindows ? '%userprofile%\\.grok' : '~/.grok'
const configContent = `[models]
default = "sub2api-grok"
web_search = "sub2api-grok"
[model."sub2api-grok"]
model = "grok-4.5"
base_url = "${baseUrl}"
name = "Grok 4.5 via Sub2API"
description = "Grok 4.5 through a Sub2API Grok group"
api_key = "${apiKey}"
api_backend = "responses"
context_window = 1000000
supports_backend_search = true`
return [{
path: `${configDir}/config.toml`,
content: configContent,
hint: t('keys.useKeyModal.grok.configTomlHint')
}]
}
function generateOpenAIWsFiles(baseUrl: string, apiKey: string): FileConfig[] {
const isWindows = activeTab.value === 'windows'
const configDir = isWindows ? '%userprofile%\\.codex' : '~/.codex'
@@ -1072,6 +1113,24 @@ function generateOpenCodeConfig(platform: string, baseUrl: string, apiKey: strin
}
}
}
const grokModels = {
'grok-4.5': {
name: 'Grok 4.5',
limit: { context: 1000000, output: 128000 }
},
'grok-4.3': {
name: 'Grok 4.3',
limit: { context: 1000000, output: 128000 }
},
'grok-build-0.1': {
name: 'Grok Build 0.1',
limit: { context: 256000, output: 128000 }
},
'grok-composer-2.5-fast': {
name: 'Grok Composer 2.5 Fast',
limit: { context: 500000, output: 128000 }
}
}
if (platform === 'gemini') {
provider[platform].npm = '@ai-sdk/google'
@@ -1088,6 +1147,10 @@ function generateOpenCodeConfig(platform: string, baseUrl: string, apiKey: strin
provider[platform].models = antigravityGeminiModels
} else if (platform === 'openai') {
provider[platform].models = openaiModels
} else if (platform === 'grok') {
provider[platform].npm = '@ai-sdk/openai-compatible'
provider[platform].name = 'Grok via Sub2API'
provider[platform].models = grokModels
}
const agent =
@@ -17,6 +17,59 @@ vi.mock('@/composables/useClipboard', () => ({
import UseKeyModal from '../UseKeyModal.vue'
describe('UseKeyModal', () => {
it('renders Grok Build and OpenCode setup for Grok groups', async () => {
const wrapper = mount(UseKeyModal, {
props: {
show: true,
apiKey: 'sk-grok-test',
baseUrl: 'https://example.com/v1',
platform: 'grok'
},
global: {
stubs: {
BaseDialog: {
template: '<div><slot /><slot name="footer" /></div>'
},
Icon: {
template: '<span />'
}
}
}
})
const grokTab = wrapper.findAll('button').find((button) =>
button.text().includes('keys.useKeyModal.cliTabs.grokCli')
)
expect(grokTab).toBeDefined()
const grokConfig = wrapper.findAll('pre code')
.map((code) => code.text())
.find((content) => content.includes('[model."sub2api-grok"]'))
expect(grokConfig).toBeDefined()
expect(grokConfig).toContain('model = "grok-4.5"')
expect(grokConfig).toContain('base_url = "https://example.com/v1"')
expect(grokConfig).toContain('api_key = "sk-grok-test"')
expect(grokConfig).toContain('api_backend = "responses"')
const opencodeTab = wrapper.findAll('button').find((button) =>
button.text().includes('keys.useKeyModal.cliTabs.opencode')
)
expect(opencodeTab).toBeDefined()
await opencodeTab!.trigger('click')
await nextTick()
const parsed = JSON.parse(wrapper.find('pre code').text())
expect(parsed.provider.grok.npm).toBe('@ai-sdk/openai-compatible')
expect(parsed.provider.grok.options).toEqual({
baseURL: 'https://example.com/v1',
apiKey: 'sk-grok-test'
})
expect(parsed.provider.grok.models['grok-4.5']).toBeDefined()
expect(parsed.provider.grok.models['grok-build-0.1']).toBeDefined()
expect(parsed.provider.grok.models['grok-composer-2.5-fast']).toBeDefined()
expect(parsed.provider.grok.models['gpt-5.6']).toBeUndefined()
})
it('renders GPT-5.5 and goals feature in OpenAI Codex config', () => {
const wrapper = mount(UseKeyModal, {
props: {