💄 style: add grok-4.20 series early support (#12743)

* style: add grok-4.20 series early support

* chore: disable browser request due to CORS

* style: update ability tag
This commit is contained in:
Zhijie He
2026-03-09 10:23:16 +08:00
committed by GitHub
parent 4363994945
commit e4f8ed78ba
13 changed files with 219 additions and 24 deletions

View File

@@ -223,6 +223,7 @@
"providerModels.item.modelConfig.extendParams.options.gpt5_1ReasoningEffort.hint": "For GPT-5.1 series; controls reasoning intensity.",
"providerModels.item.modelConfig.extendParams.options.gpt5_2ProReasoningEffort.hint": "For GPT-5.2 Pro series; controls reasoning intensity.",
"providerModels.item.modelConfig.extendParams.options.gpt5_2ReasoningEffort.hint": "For GPT-5.2 series; controls reasoning intensity.",
"providerModels.item.modelConfig.extendParams.options.grok4_20ReasoningEffort.hint": "For Grok 4.20 series; controls reasoning intensity. Low/Medium uses 4 agents, High/XHigh uses 16 agents.",
"providerModels.item.modelConfig.extendParams.options.imageAspectRatio.hint": "For Gemini image generation models; controls aspect ratio of generated images.",
"providerModels.item.modelConfig.extendParams.options.imageAspectRatio2.hint": "For Nano Banana 2; controls aspect ratio of generated images (supports extra-wide 1:4, 4:1, 1:8, 8:1).",
"providerModels.item.modelConfig.extendParams.options.imageResolution.hint": "For Gemini 3 image generation models; controls resolution of generated images.",

View File

@@ -223,6 +223,7 @@
"providerModels.item.modelConfig.extendParams.options.gpt5_1ReasoningEffort.hint": "适用于 GPT-5.1 系列;控制推理强度。",
"providerModels.item.modelConfig.extendParams.options.gpt5_2ProReasoningEffort.hint": "适用于 GPT-5.2 Pro 系列;控制推理强度。",
"providerModels.item.modelConfig.extendParams.options.gpt5_2ReasoningEffort.hint": "适用于 GPT-5.2 系列;控制推理强度。",
"providerModels.item.modelConfig.extendParams.options.grok4_20ReasoningEffort.hint": "适用于 Grok 4.20 系列;控制推理强度。低/中档使用 4 个代理,高/超高使用 16 个代理。",
"providerModels.item.modelConfig.extendParams.options.imageAspectRatio.hint": "适用于 Gemini 图像生成模型;控制生成图像的宽高比。",
"providerModels.item.modelConfig.extendParams.options.imageAspectRatio2.hint": "适用于 Nano Banana 2控制生成图像的宽高比支持超宽 1:4、4:1、1:8、8:1。",
"providerModels.item.modelConfig.extendParams.options.imageResolution.hint": "适用于 Gemini 3 图像生成模型;控制生成图像的分辨率。",

View File

@@ -2,6 +2,157 @@ import type { AIChatModelCard, AIImageModelCard } from '../types/aiModel';
// https://docs.x.ai/docs/models
const xaiChatModels: AIChatModelCard[] = [
{
abilities: {
functionCall: true,
reasoning: true,
search: true,
structuredOutput: true,
vision: true,
},
contextWindowTokens: 2_000_000,
description:
'A team of 4 or 16 agents, Excels at research use cases, Does not currently support client-side tools. Only supports xAI server side tools (eg X Search, Web Search tools) and remote MCP tools.',
displayName: 'Grok 4.20 Multi-Agent Experimental Beta',
enabled: true,
id: 'grok-4.20-multi-agent-experimental-beta-0304',
pricing: {
units: [
{
name: 'textInput_cacheRead',
strategy: 'tiered',
tiers: [
{ rate: 0.2, upTo: 0.2 },
{ rate: 0.4, upTo: 'infinity' },
],
unit: 'millionTokens',
},
{
name: 'textInput',
strategy: 'tiered',
tiers: [
{ rate: 2, upTo: 0.2 },
{ rate: 4, upTo: 'infinity' },
],
unit: 'millionTokens',
},
{
name: 'textOutput',
strategy: 'tiered',
tiers: [
{ rate: 6, upTo: 0.2 },
{ rate: 12, upTo: 'infinity' },
],
unit: 'millionTokens',
},
],
},
releasedAt: '2026-03-04',
settings: {
extendParams: ['grok4_20ReasoningEffort'],
searchImpl: 'params',
},
type: 'chat',
},
{
abilities: {
functionCall: true,
search: true,
structuredOutput: true,
vision: true,
},
contextWindowTokens: 2_000_000,
description: 'A non-reasoning variant for simple use cases',
displayName: 'Grok 4.20 Experimental Beta (Non-Reasoning)',
enabled: true,
id: 'grok-4.20-experimental-beta-0304-non-reasoning',
pricing: {
units: [
{
name: 'textInput_cacheRead',
strategy: 'tiered',
tiers: [
{ rate: 0.2, upTo: 0.2 },
{ rate: 0.4, upTo: 'infinity' },
],
unit: 'millionTokens',
},
{
name: 'textInput',
strategy: 'tiered',
tiers: [
{ rate: 2, upTo: 0.2 },
{ rate: 4, upTo: 'infinity' },
],
unit: 'millionTokens',
},
{
name: 'textOutput',
strategy: 'tiered',
tiers: [
{ rate: 6, upTo: 0.2 },
{ rate: 12, upTo: 'infinity' },
],
unit: 'millionTokens',
},
],
},
releasedAt: '2026-03-04',
settings: {
searchImpl: 'params',
},
type: 'chat',
},
{
abilities: {
functionCall: true,
reasoning: true,
search: true,
structuredOutput: true,
vision: true,
},
contextWindowTokens: 2_000_000,
description: 'Intelligent, blazing-fast model that reasons before responding',
displayName: 'Grok 4.20 Experimental Beta',
enabled: true,
id: 'grok-4.20-experimental-beta-0304-reasoning',
pricing: {
units: [
{
name: 'textInput_cacheRead',
strategy: 'tiered',
tiers: [
{ rate: 0.2, upTo: 0.2 },
{ rate: 0.4, upTo: 'infinity' },
],
unit: 'millionTokens',
},
{
name: 'textInput',
strategy: 'tiered',
tiers: [
{ rate: 2, upTo: 0.2 },
{ rate: 4, upTo: 'infinity' },
],
unit: 'millionTokens',
},
{
name: 'textOutput',
strategy: 'tiered',
tiers: [
{ rate: 6, upTo: 0.2 },
{ rate: 12, upTo: 'infinity' },
],
unit: 'millionTokens',
},
],
},
releasedAt: '2026-03-04',
settings: {
searchImpl: 'params',
},
type: 'chat',
},
{
abilities: {
functionCall: true,
@@ -89,6 +240,7 @@ const xaiChatModels: AIChatModelCard[] = [
abilities: {
functionCall: true,
search: true,
structuredOutput: true,
vision: true,
},
contextWindowTokens: 2_000_000,
@@ -130,6 +282,7 @@ const xaiChatModels: AIChatModelCard[] = [
functionCall: true,
reasoning: true,
search: true,
structuredOutput: true,
vision: true,
},
contextWindowTokens: 2_000_000,
@@ -170,6 +323,7 @@ const xaiChatModels: AIChatModelCard[] = [
abilities: {
functionCall: true,
reasoning: true,
structuredOutput: true,
},
contextWindowTokens: 256_000,
description:
@@ -195,13 +349,13 @@ const xaiChatModels: AIChatModelCard[] = [
functionCall: true,
reasoning: true,
search: true,
structuredOutput: true,
vision: true,
},
contextWindowTokens: 256_000,
description:
'Our newest and strongest flagship model, excelling in NLP, math, and reasoning—an ideal all-rounder.',
displayName: 'Grok 4 0709',
enabled: true,
id: 'grok-4',
pricing: {
units: [
@@ -222,6 +376,7 @@ const xaiChatModels: AIChatModelCard[] = [
abilities: {
functionCall: true,
search: true,
structuredOutput: true,
},
contextWindowTokens: 131_072,
description:
@@ -246,6 +401,7 @@ const xaiChatModels: AIChatModelCard[] = [
functionCall: true,
reasoning: true,
search: true,
structuredOutput: true,
},
contextWindowTokens: 131_072,
description:
@@ -266,28 +422,6 @@ const xaiChatModels: AIChatModelCard[] = [
},
type: 'chat',
},
{
abilities: {
functionCall: true,
search: true,
vision: true,
},
contextWindowTokens: 32_768,
description: 'Improved accuracy, instruction following, and multilingual capability.',
displayName: 'Grok 2 Vision 1212',
id: 'grok-2-vision-1212', // legacy
pricing: {
units: [
{ name: 'textInput', rate: 2, strategy: 'fixed', unit: 'millionTokens' },
{ name: 'textOutput', rate: 10, strategy: 'fixed', unit: 'millionTokens' },
],
},
releasedAt: '2024-12-12',
settings: {
searchImpl: 'params',
},
type: 'chat',
},
];
const xaiImageModels: AIImageModelCard[] = [

View File

@@ -11,11 +11,13 @@ const XAI: ModelProviderCard = {
modelsUrl: 'https://docs.x.ai/docs#models',
name: 'xAI (Grok)',
settings: {
disableBrowserRequest: true,
proxyUrl: {
placeholder: 'https://api.x.ai/v1',
},
sdkType: 'openai',
showModelFetcher: true,
supportResponsesApi: true,
},
url: 'https://x.ai/api',
};

View File

@@ -250,6 +250,7 @@ export type ExtendParamsType =
| 'gpt5_1ReasoningEffort'
| 'gpt5_2ReasoningEffort'
| 'gpt5_2ProReasoningEffort'
| 'grok4_20ReasoningEffort'
| 'textVerbosity'
| 'thinking'
| 'thinkingBudget'
@@ -284,6 +285,7 @@ export const ExtendParamsTypeSchema = z.enum([
'gpt5_1ReasoningEffort',
'gpt5_2ReasoningEffort',
'gpt5_2ProReasoningEffort',
'grok4_20ReasoningEffort',
'textVerbosity',
'thinking',
'thinkingBudget',

View File

@@ -47,6 +47,11 @@ export const responsesAPIModels = new Set([
'gpt-5.4-pro',
]);
/**
* Grok models use Responses API only
*/
export const responsesAPIGrokModels = new Set(['grok-4.20-multi-agent-experimental-beta-0304']);
/**
* Regex patterns for models that support context caching (3.5+)
*/

View File

@@ -1,5 +1,6 @@
import { ModelProvider } from 'model-bank';
import { responsesAPIGrokModels } from '../../const/models';
import { createOpenAICompatibleRuntime } from '../../core/openaiCompatibleFactory';
import type { ChatStreamPayload } from '../../types';
import { MODEL_LIST_CONFIGS, processModelList } from '../../utils/modelParse';
@@ -21,7 +22,7 @@ export const LobeXAI = createOpenAICompatibleRuntime({
handlePayload: (payload) => {
const { enabledSearch, frequency_penalty, model, presence_penalty, ...rest } = payload;
if (enabledSearch) {
if (responsesAPIGrokModels.has(model) || enabledSearch) {
return { ...rest, apiMode: 'responses', enabledSearch, model } as ChatStreamPayload;
}
@@ -57,6 +58,7 @@ export const LobeXAI = createOpenAICompatibleRuntime({
...rest,
stream: payload.stream ?? true,
tools: xaiTools,
include: ['reasoning.encrypted_content'],
} as any;
},
},

View File

@@ -72,6 +72,7 @@ export interface LobeAgentChatConfig extends AgentMemoryChatConfig {
gpt5_2ProReasoningEffort?: 'medium' | 'high' | 'xhigh';
gpt5_2ReasoningEffort?: 'none' | 'low' | 'medium' | 'high' | 'xhigh';
gpt5ReasoningEffort?: 'minimal' | 'low' | 'medium' | 'high';
grok4_20ReasoningEffort?: 'low' | 'medium' | 'high' | 'xhigh';
/**
* Number of historical messages
*/
@@ -164,6 +165,7 @@ export const AgentChatConfigSchema = z
gpt5_1ReasoningEffort: z.enum(['none', 'low', 'medium', 'high']).optional(),
gpt5_2ProReasoningEffort: z.enum(['medium', 'high', 'xhigh']).optional(),
gpt5_2ReasoningEffort: z.enum(['none', 'low', 'medium', 'high', 'xhigh']).optional(),
grok4_20ReasoningEffort: z.enum(['low', 'medium', 'high', 'xhigh']).optional(),
historyCount: z.number().optional(),
imageAspectRatio: z.string().optional(),
imageAspectRatio2: z.string().optional(),

View File

@@ -17,6 +17,7 @@ import GPT5ReasoningEffortSlider from './GPT5ReasoningEffortSlider';
import GPT51ReasoningEffortSlider from './GPT51ReasoningEffortSlider';
import GPT52ProReasoningEffortSlider from './GPT52ProReasoningEffortSlider';
import GPT52ReasoningEffortSlider from './GPT52ReasoningEffortSlider';
import Grok420ReasoningEffortSlider from './Grok420ReasoningEffortSlider';
import ImageAspectRatio2Select from './ImageAspectRatio2Select';
import ImageAspectRatioSelect from './ImageAspectRatioSelect';
import ImageResolution2Slider from './ImageResolution2Slider';
@@ -206,6 +207,17 @@ const ControlsForm = memo<ControlsFormProps>(({ model: modelProp, provider: prov
paddingBottom: 0,
},
},
{
children: <Grok420ReasoningEffortSlider />,
desc: 'reasoning_effort',
label: t('extendParams.reasoningEffort.title'),
layout: 'horizontal',
minWidth: undefined,
name: 'grok4_20ReasoningEffort',
style: {
paddingBottom: 0,
},
},
{
children: <TextVerbositySlider />,
desc: 'text_verbosity',

View File

@@ -0,0 +1,16 @@
import { type CreatedLevelSliderProps } from './createLevelSlider';
import { createLevelSliderComponent } from './createLevelSlider';
const GROK4_20_REASONING_EFFORT_LEVELS = ['low', 'medium', 'high', 'xhigh'] as const;
type Grok420ReasoningEffort = (typeof GROK4_20_REASONING_EFFORT_LEVELS)[number];
export type Grok420ReasoningEffortSliderProps = CreatedLevelSliderProps<Grok420ReasoningEffort>;
const Grok420ReasoningEffortSlider = createLevelSliderComponent<Grok420ReasoningEffort>({
configKey: 'grok4_20ReasoningEffort',
defaultValue: 'medium',
levels: GROK4_20_REASONING_EFFORT_LEVELS,
style: { minWidth: 200 },
});
export default Grok420ReasoningEffortSlider;

View File

@@ -261,6 +261,8 @@ export default {
'For GPT-5.2 Pro series; controls reasoning intensity.',
'providerModels.item.modelConfig.extendParams.options.gpt5_2ReasoningEffort.hint':
'For GPT-5.2 series; controls reasoning intensity.',
'providerModels.item.modelConfig.extendParams.options.grok4_20ReasoningEffort.hint':
'For Grok 4.20 series; controls reasoning intensity. Low/Medium uses 4 agents, High/XHigh uses 16 agents.',
'providerModels.item.modelConfig.extendParams.options.imageAspectRatio.hint':
'For Gemini image generation models; controls aspect ratio of generated images.',
'providerModels.item.modelConfig.extendParams.options.imageAspectRatio2.hint':

View File

@@ -10,6 +10,7 @@ import GPT5ReasoningEffortSlider from '@/features/ModelSwitchPanel/components/Co
import GPT51ReasoningEffortSlider from '@/features/ModelSwitchPanel/components/ControlsForm/GPT51ReasoningEffortSlider';
import GPT52ProReasoningEffortSlider from '@/features/ModelSwitchPanel/components/ControlsForm/GPT52ProReasoningEffortSlider';
import GPT52ReasoningEffortSlider from '@/features/ModelSwitchPanel/components/ControlsForm/GPT52ReasoningEffortSlider';
import Grok420ReasoningEffortSlider from '@/features/ModelSwitchPanel/components/ControlsForm/Grok420ReasoningEffortSlider';
import ImageAspectRatio2Select from '@/features/ModelSwitchPanel/components/ControlsForm/ImageAspectRatio2Select';
import ImageAspectRatioSelect from '@/features/ModelSwitchPanel/components/ControlsForm/ImageAspectRatioSelect';
import ImageResolution2Slider from '@/features/ModelSwitchPanel/components/ControlsForm/ImageResolution2Slider';
@@ -71,6 +72,10 @@ const EXTEND_PARAMS_OPTIONS: ExtendParamsOption[] = [
hintKey: 'providerModels.item.modelConfig.extendParams.options.gpt5_2ProReasoningEffort.hint',
key: 'gpt5_2ProReasoningEffort',
},
{
hintKey: 'providerModels.item.modelConfig.extendParams.options.grok4_20ReasoningEffort.hint',
key: 'grok4_20ReasoningEffort',
},
{
hintKey: 'providerModels.item.modelConfig.extendParams.options.textVerbosity.hint',
key: 'textVerbosity',
@@ -132,6 +137,7 @@ const TITLE_KEY_ALIASES: Partial<Record<ExtendParamsType, ExtendParamsType>> = {
gpt5_1ReasoningEffort: 'reasoningEffort',
gpt5_2ProReasoningEffort: 'reasoningEffort',
gpt5_2ReasoningEffort: 'reasoningEffort',
grok4_20ReasoningEffort: 'reasoningEffort',
imageAspectRatio2: 'imageAspectRatio',
thinkingLevel2: 'thinkingLevel',
thinkingLevel3: 'thinkingLevel',
@@ -163,6 +169,11 @@ const PREVIEW_META: Partial<Record<ExtendParamsType, PreviewMeta>> = {
tag: 'reasoning_effort',
},
gpt5_2ReasoningEffort: { labelSuffix: ' (GPT-5.2)', previewWidth: 300, tag: 'reasoning_effort' },
grok4_20ReasoningEffort: {
labelSuffix: ' (Grok 4.20)',
previewWidth: 300,
tag: 'reasoning_effort',
},
imageAspectRatio: { labelSuffix: '', previewWidth: 350, tag: 'aspect_ratio' },
imageAspectRatio2: { labelSuffix: ' (Nano Banana 2)', previewWidth: 350, tag: 'aspect_ratio' },
imageResolution: { labelSuffix: '', previewWidth: 250, tag: 'resolution' },
@@ -268,6 +279,7 @@ const ExtendParamsSelect = memo<ExtendParamsSelectProps>(({ value, onChange }) =
gpt5_1ReasoningEffort: <GPT51ReasoningEffortSlider value="none" />,
gpt5_2ProReasoningEffort: <GPT52ProReasoningEffortSlider value="medium" />,
gpt5_2ReasoningEffort: <GPT52ReasoningEffortSlider value="none" />,
grok4_20ReasoningEffort: <Grok420ReasoningEffortSlider value="medium" />,
imageAspectRatio: <ImageAspectRatioSelect value="1:1" />,
imageAspectRatio2: <ImageAspectRatio2Select value="1:1" />,
imageResolution: <ImageResolutionSlider value="1K" />,

View File

@@ -122,6 +122,10 @@ export const resolveModelExtendParams = (ctx: ModelParamsContext): ModelExtendPa
extendParams.reasoning_effort = chatConfig.gpt5_2ProReasoningEffort;
}
if (modelExtendParams.includes('grok4_20ReasoningEffort') && chatConfig.grok4_20ReasoningEffort) {
extendParams.reasoning_effort = chatConfig.grok4_20ReasoningEffort;
}
if (modelExtendParams.includes('effort') && chatConfig.effort) {
extendParams.effort = chatConfig.effort;
}