Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions common/endpoint_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ func GetEndpointTypesByChannelType(channelType int, modelName string) []constant
endpointTypes = []constant.EndpointType{constant.EndpointTypeGemini, constant.EndpointTypeOpenAI}
case constant.ChannelTypeOpenRouter: // OpenRouter 只支持 OpenAI 端点
endpointTypes = []constant.EndpointType{constant.EndpointTypeOpenAI}
case constant.ChannelTypeXai:
endpointTypes = []constant.EndpointType{constant.EndpointTypeOpenAI, constant.EndpointTypeOpenAIResponse}
case constant.ChannelTypeSora:
endpointTypes = []constant.EndpointType{constant.EndpointTypeOpenAIVideo}
default:
Expand Down
33 changes: 10 additions & 23 deletions relay/channel/xai/adaptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,32 +63,11 @@ func (a *Adaptor) ConvertOpenAIRequest(c *gin.Context, info *relaycommon.RelayIn
if request == nil {
return nil, errors.New("request is nil")
}
if strings.HasSuffix(info.UpstreamModelName, "-search") {
info.UpstreamModelName = strings.TrimSuffix(info.UpstreamModelName, "-search")
request.Model = info.UpstreamModelName
toMap := request.ToMap()
toMap["search_parameters"] = map[string]any{
"mode": "on",
}
return toMap, nil
}
if strings.HasPrefix(request.Model, "grok-3-mini") {
if request.MaxCompletionTokens == 0 && request.MaxTokens != 0 {
request.MaxCompletionTokens = request.MaxTokens
request.MaxTokens = 0
}
if strings.HasSuffix(request.Model, "-high") {
request.ReasoningEffort = "high"
request.Model = strings.TrimSuffix(request.Model, "-high")
} else if strings.HasSuffix(request.Model, "-low") {
request.ReasoningEffort = "low"
request.Model = strings.TrimSuffix(request.Model, "-low")
} else if strings.HasSuffix(request.Model, "-medium") {
request.ReasoningEffort = "medium"
request.Model = strings.TrimSuffix(request.Model, "-medium")
}
info.ReasoningEffort = request.ReasoningEffort
info.UpstreamModelName = request.Model
}
return request, nil
}
Expand All @@ -103,8 +82,10 @@ func (a *Adaptor) ConvertEmbeddingRequest(c *gin.Context, info *relaycommon.Rela
}

func (a *Adaptor) ConvertOpenAIResponsesRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.OpenAIResponsesRequest) (any, error) {
// TODO implement me
return nil, errors.New("not implemented")
if request.Model == "" && info != nil {
request.Model = info.UpstreamModelName
}
return request, nil
}

func (a *Adaptor) DoRequest(c *gin.Context, info *relaycommon.RelayInfo, requestBody io.Reader) (any, error) {
Expand All @@ -115,6 +96,12 @@ func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycom
switch info.RelayMode {
case constant.RelayModeImagesGenerations, constant.RelayModeImagesEdits:
usage, err = openai.OpenaiHandlerWithUsage(c, info, resp)
case constant.RelayModeResponses:
if info.IsStream {
usage, err = openai.OaiResponsesStreamHandler(c, info, resp)
} else {
usage, err = openai.OaiResponsesHandler(c, info, resp)
}
default:
if info.IsStream {
usage, err = xAIStreamHandler(c, info, resp)
Expand Down
30 changes: 16 additions & 14 deletions relay/channel/xai/constants.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
package xai

var ModelList = []string{
// grok-4
"grok-4", "grok-4-0709", "grok-4-0709-search",
// grok-3
"grok-3-beta", "grok-3-mini-beta",
// grok-3 mini
"grok-3-fast-beta", "grok-3-mini-fast-beta",
// extend grok-3-mini reasoning
"grok-3-mini-beta-high", "grok-3-mini-beta-low", "grok-3-mini-beta-medium",
"grok-3-mini-fast-beta-high", "grok-3-mini-fast-beta-low", "grok-3-mini-fast-beta-medium",
// image model
"grok-2-image",
// legacy models
"grok-2", "grok-2-vision",
"grok-beta", "grok-vision-beta",
// language models
"grok-4-1-fast-reasoning",
"grok-4-1-fast-non-reasoning",
"grok-code-fast-1",
"grok-4-fast-reasoning",
"grok-4-fast-non-reasoning",
"grok-4-0709",
"grok-3-mini",
"grok-3",
"grok-2-vision-1212",
// image generation models
"grok-imagine-image-pro",
"grok-imagine-image",
"grok-2-image-1212",
// video generation model
"grok-imagine-video"
}
Comment on lines 3 to 30

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

xAI grok API supported models 2026

💡 Result:

As of February 2026, the xAI (Grok) API supports these model IDs (as shown in xAI’s API models/pricing UI and docs):

Language (text) models

  • grok-4-1-fast-reasoning [1]
  • grok-4-1-fast-non-reasoning [1]
  • grok-4-fast-reasoning [1]
  • grok-4-fast-non-reasoning [1]
  • grok-code-fast-1 [1]
  • grok-4 [1]
  • grok-3 (aliases include grok-3-latest, grok-3-beta, grok-3-fast, grok-3-fast-latest, grok-3-fast-beta) [2]
  • grok-3-mini [1]
  • grok-2-vision-1212 [1]
  • grok-2-1212 [1]
  • grok-vision-beta [1]
  • grok-beta [1]

Image generation

  • grok-2-image-1212 [1]
  • grok-imagine-image [3]

Video generation

  • grok-imagine-video [4]

Source list: xAI API models/pricing page [1], xAI Grok-3 model doc (aliases) [2], xAI Image Generations guide [3], xAI Video Generations guide [4].


Remove unsupported models and update to match current xAI API.

Two models in this list are not currently supported by the xAI API and will cause request failures:

  • grok-4-0709 (deprecated)
  • grok-imagine-image-pro (not available; only grok-imagine-image is supported)

Additionally, the following currently available models are missing:

  • Language models: grok-4, grok-2-1212, grok-vision-beta, grok-beta
  • Video generation: grok-imagine-video

Update this list to reflect the current xAI API as of February 2026.

🤖 Prompt for AI Agents
In `@relay/channel/xai/constants.go` around lines 3 - 18, Update the ModelList
slice in constants.go to match the current xAI API: remove the deprecated
"grok-4-0709" and the unavailable "grok-imagine-image-pro", and add the missing
models "grok-4", "grok-2-1212", "grok-vision-beta", "grok-beta", and the video
model "grok-imagine-video"; ensure the list keeps language models grouped
together and image/video models grouped together and that the variable ModelList
is updated accordingly so callers of ModelList use only supported model names.


var ChannelName = "xai"
3 changes: 1 addition & 2 deletions relay/channel/xai/text.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package xai

import (
"encoding/json"
"io"
"net/http"
"strings"
Expand Down Expand Up @@ -46,7 +45,7 @@ func xAIStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Re

helper.StreamScannerHandler(c, resp, info, func(data string) bool {
var xAIResp *dto.ChatCompletionsStreamResponse
err := json.Unmarshal([]byte(data), &xAIResp)
err := common.UnmarshalJsonStr(data, &xAIResp)
if err != nil {
common.SysLog("error unmarshalling stream response: " + err.Error())
return true
Expand Down