mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-14 12:02:27 +08:00
Merge pull request #7466 from nagi330/add_grok4-7_support-0922
feat(grok):add grok 4.7 support
This commit is contained in:
@@ -1375,7 +1375,7 @@ func writeGrokModelsList(c *gin.Context, modelIDs []string) {
|
||||
|
||||
func grokModelSupportsConfigurableReasoning(modelID string) bool {
|
||||
switch strings.ToLower(strings.TrimSpace(modelID)) {
|
||||
case "grok-4.6", "grok-4.6-latest", "grok-4.5", "grok-4.5-latest", "grok", "grok-latest", "grok-build", "grok-build-latest", "grok-build-0.1":
|
||||
case "grok-4.7", "grok-4.7-latest", "grok-4.6", "grok-4.6-latest", "grok-4.5", "grok-4.5-latest", "grok", "grok-latest", "grok-build", "grok-build-latest", "grok-build-0.1":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
||||
@@ -84,6 +84,7 @@ func (o ModelMappingOptions) defaultText() string {
|
||||
|
||||
var defaultModels = []Model{
|
||||
// Text
|
||||
{ID: "grok-4.7", Object: "model", Type: "model", OwnedBy: "xai", DisplayName: "Grok 4.7"},
|
||||
{ID: "grok-4.6", Object: "model", Type: "model", OwnedBy: "xai", DisplayName: "Grok 4.6"},
|
||||
{ID: "grok-4.5", Object: "model", Type: "model", OwnedBy: "xai", DisplayName: "Grok 4.5"},
|
||||
{ID: "grok-4.3", Object: "model", Type: "model", OwnedBy: "xai", DisplayName: "Grok 4.3"},
|
||||
@@ -106,6 +107,8 @@ var defaultModels = []Model{
|
||||
var grokTextResponsesModelAliases = map[string]string{
|
||||
"grok": DefaultTextModel,
|
||||
"grok-latest": DefaultTextModel,
|
||||
"grok-4.7": "grok-4.7",
|
||||
"grok-4.7-latest": "grok-4.7",
|
||||
"grok-4.6": "grok-4.6",
|
||||
"grok-4.6-latest": "grok-4.6",
|
||||
"grok-4.5": "grok-4.5",
|
||||
|
||||
@@ -68,9 +68,14 @@ func TestIsGrokImagineModel(t *testing.T) {
|
||||
require.False(t, IsGrokImagineModel("grok-build-0.1"))
|
||||
}
|
||||
|
||||
func TestDefaultModelsIncludesGrok46(t *testing.T) {
|
||||
func TestDefaultModelsIncludesGrok46And47(t *testing.T) {
|
||||
t.Parallel()
|
||||
ids := DefaultModelIDs()
|
||||
require.Contains(t, ids, "grok-4.7")
|
||||
require.Equal(t, "grok-4.7", ResolveGrokTextResponsesModelID("grok-4.7"))
|
||||
require.Equal(t, "grok-4.7", ResolveGrokTextResponsesModelID("grok-4.7-latest"))
|
||||
|
||||
// Keep the existing assertions for the previous current model as well.
|
||||
require.Contains(t, ids, "grok-4.6")
|
||||
require.Equal(t, "grok-4.6", ResolveGrokTextResponsesModelID("grok-4.6"))
|
||||
require.Equal(t, "grok-4.6", ResolveGrokTextResponsesModelID("grok-4.6-latest"))
|
||||
|
||||
@@ -855,6 +855,19 @@ func (s *BillingService) initFallbackPricing() {
|
||||
LongContextOutputMultiplier: 2,
|
||||
}
|
||||
|
||||
// xAI Grok 4.7: $2 input / $0.50 cached input / $6 output below 200k;
|
||||
// long-context rates are $4 / $1 / $12 (>=200k prompt tokens).
|
||||
s.fallbackPrices["grok-4.7"] = &ModelPricing{
|
||||
InputPricePerToken: 2e-6,
|
||||
OutputPricePerToken: 6e-6,
|
||||
CacheReadPricePerToken: 0.5e-6,
|
||||
SupportsCacheBreakdown: false,
|
||||
LongContextInputThreshold: 200000,
|
||||
LongContextThresholdInclusive: true,
|
||||
LongContextInputMultiplier: 2,
|
||||
LongContextOutputMultiplier: 2,
|
||||
}
|
||||
|
||||
// xAI Grok 4.3: $1.25 input / $0.20 cached / $2.50 output below 200k;
|
||||
// long-context rates are $2.50 / $0.40 / $5.
|
||||
s.fallbackPrices["grok-4.3"] = &ModelPricing{
|
||||
@@ -1128,6 +1141,8 @@ func (s *BillingService) getFallbackPricing(model string) *ModelPricing {
|
||||
switch modelLower {
|
||||
case "grok", "grok-latest", "grok-4.6", "grok-4.6-latest":
|
||||
return s.fallbackPrices["grok-4.6"]
|
||||
case "grok-4.7", "grok-4.7-latest":
|
||||
return s.fallbackPrices["grok-4.7"]
|
||||
case "grok-4.5", "grok-4.5-latest":
|
||||
return s.fallbackPrices["grok-4.5"]
|
||||
case "grok-3-mini":
|
||||
|
||||
@@ -1169,6 +1169,25 @@ func TestGetModelPricing_Grok46OfficialFallback(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetModelPricing_Grok47OfficialFallback(t *testing.T) {
|
||||
svc := newTestBillingService()
|
||||
|
||||
for _, model := range []string{"grok-4.7", "grok-4.7-latest"} {
|
||||
model := model
|
||||
t.Run(model, func(t *testing.T) {
|
||||
pricing, err := svc.GetModelPricing(model)
|
||||
require.NoError(t, err)
|
||||
require.InDelta(t, 2e-6, pricing.InputPricePerToken, 1e-12)
|
||||
require.InDelta(t, 6e-6, pricing.OutputPricePerToken, 1e-12)
|
||||
require.InDelta(t, 0.5e-6, pricing.CacheReadPricePerToken, 1e-12)
|
||||
require.Equal(t, 200000, pricing.LongContextInputThreshold)
|
||||
require.InDelta(t, 2.0, pricing.LongContextInputMultiplier, 1e-12)
|
||||
require.InDelta(t, 2.0, pricing.LongContextOutputMultiplier, 1e-12)
|
||||
require.False(t, pricing.SupportsCacheBreakdown)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetModelPricing_GrokOfficialFamilyCards(t *testing.T) {
|
||||
svc := newTestBillingService()
|
||||
for _, tc := range []struct {
|
||||
|
||||
@@ -1268,6 +1268,7 @@ func isGrokCodexImageInputModel(model string) bool {
|
||||
case "grok-4.3",
|
||||
"grok-4.5",
|
||||
"grok-4.6",
|
||||
"grok-4.7",
|
||||
"grok-build-0.1",
|
||||
"grok-4.20-0309-reasoning",
|
||||
"grok-4.20-0309-non-reasoning",
|
||||
|
||||
@@ -744,16 +744,18 @@ func normalizeGrokReasoningEffortValue(raw, model string) (string, bool) {
|
||||
}
|
||||
|
||||
// GrokSupportsXHighReasoningEffort reports whether the model advertises and
|
||||
// forwards the xhigh reasoning effort (Grok 4.6 and its undated alias).
|
||||
// forwards the xhigh reasoning effort (Grok 4.6/4.7 and their aliases).
|
||||
func GrokSupportsXHighReasoningEffort(model string) bool {
|
||||
model = strings.ToLower(xai.StripGrokProviderPrefix(strings.TrimSpace(model)))
|
||||
return model == "grok-4.6" || model == "grok-4.6-latest"
|
||||
return model == "grok-4.7" || model == "grok-4.7-latest" ||
|
||||
model == "grok-4.6" || model == "grok-4.6-latest"
|
||||
}
|
||||
|
||||
func grokSupportsReasoningEffort(model string) bool {
|
||||
model = strings.ToLower(xai.StripGrokProviderPrefix(strings.TrimSpace(model)))
|
||||
switch model {
|
||||
case "grok-4.5", "grok-4.5-latest", "grok-4.6", "grok-4.6-latest",
|
||||
"grok-4.7", "grok-4.7-latest",
|
||||
"grok-4.3", "grok-4.3-latest",
|
||||
"grok-3-mini", "grok-3-mini-fast", "grok-4.20-0309-reasoning",
|
||||
"grok-4.20-reasoning", "grok-4.20-multi-agent-0309":
|
||||
|
||||
@@ -498,7 +498,7 @@ func grokChatResponsesCacheIntentBody(body []byte) ([]byte, error) {
|
||||
|
||||
func grokChatResponsesBridgeModel(model string) bool {
|
||||
switch strings.ToLower(xai.StripGrokProviderPrefix(strings.TrimSpace(model))) {
|
||||
case "grok-4.5", "grok-4.6", "grok-4.6-latest":
|
||||
case "grok-4.5", "grok-4.6", "grok-4.6-latest", "grok-4.7", "grok-4.7-latest":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
||||
@@ -27,6 +27,7 @@ const (
|
||||
// 供 /v1/models 在尚未同步上游列表时回退,以及账号白名单预填。
|
||||
func DefaultOpenCodeGoModelIDs() []string {
|
||||
return []string{
|
||||
"grok-4.7",
|
||||
"grok-4.6",
|
||||
"gpt-5.6-luna",
|
||||
"glm-5.3-flash",
|
||||
|
||||
@@ -299,6 +299,8 @@ func canonicalGrokBuildRuntimeModel(model string) string {
|
||||
return "grok-4.5-build"
|
||||
case "grok-4.6", "grok-4.6-latest", "grok-4.6-build":
|
||||
return "grok-4.6-build"
|
||||
case "grok-4.7", "grok-4.7-latest", "grok-4.7-build":
|
||||
return "grok-4.7-build"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
{
|
||||
"grok-4.7": {
|
||||
"cache_read_input_token_cost": 5e-07,
|
||||
"input_cost_per_token": 2e-06,
|
||||
"input_cost_per_token_above_200k_tokens": 4e-06,
|
||||
"litellm_provider": "xai",
|
||||
"max_input_tokens": 500000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 6e-06,
|
||||
"output_cost_per_token_above_200k_tokens": 1.2e-05,
|
||||
"supports_prompt_caching": true
|
||||
},
|
||||
"claude-3-7-sonnet-20250219": {
|
||||
"cache_creation_input_token_cost": 3.75e-06,
|
||||
"cache_creation_input_token_cost_above_1hr": 6e-06,
|
||||
|
||||
@@ -144,6 +144,7 @@ const metaModels = [
|
||||
|
||||
// xAI Grok
|
||||
const xaiModels = [
|
||||
'grok-4.7',
|
||||
'grok-4.6',
|
||||
'grok-4.5',
|
||||
'grok-4.3',
|
||||
@@ -326,6 +327,7 @@ const geminiPresetMappings = [
|
||||
]
|
||||
|
||||
const grokPresetMappings = [
|
||||
{ label: 'Grok 4.7', from: 'grok-4.7', to: 'grok-4.7', color: 'bg-slate-100 text-slate-700 hover:bg-slate-200 dark:bg-slate-800/50 dark:text-slate-300' },
|
||||
{ label: 'Grok 4.6', from: 'grok-4.6', to: 'grok-4.6', color: 'bg-slate-100 text-slate-700 hover:bg-slate-200 dark:bg-slate-800/50 dark:text-slate-300' },
|
||||
{ label: 'Grok 4.5', from: 'grok-4.5', to: 'grok-4.5', color: 'bg-slate-100 text-slate-700 hover:bg-slate-200 dark:bg-slate-800/50 dark:text-slate-300' },
|
||||
{ label: 'Grok 4.3', from: 'grok-4.3', to: 'grok-4.3', color: 'bg-slate-100 text-slate-700 hover:bg-slate-200 dark:bg-slate-800/50 dark:text-slate-300' },
|
||||
@@ -454,7 +456,7 @@ export function getModelsByPlatform(platform: string): string[] {
|
||||
case 'moonshot':
|
||||
case 'kimi': return moonshotModels
|
||||
case 'opencode_go': return [
|
||||
'grok-4.6', 'gpt-5.6-luna',
|
||||
'grok-4.7', 'grok-4.6', 'gpt-5.6-luna',
|
||||
'glm-5.3-flash', 'glm-5.3', 'glm-5.2', 'glm-5.1',
|
||||
'kimi-k3', 'kimi-k2.7-code', 'kimi-k2.6',
|
||||
'longcat-2.0',
|
||||
|
||||
Reference in New Issue
Block a user