From 84232747e20e09871f9996601dad9e627a47448f Mon Sep 17 00:00:00 2001 From: oscarbrey <188580177+oscarbrey@users.noreply.github.com> Date: Wed, 29 Jul 2026 23:28:53 +0200 Subject: [PATCH] fix(xai): register video preview alias --- internal/registry/model_definitions.go | 16 +++++++++- internal/registry/model_definitions_test.go | 10 +++++-- .../openai/openai_videos_handlers_test.go | 30 ++++++++++++++++++- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/internal/registry/model_definitions.go b/internal/registry/model_definitions.go index 41e52de2..3567f67c 100644 --- a/internal/registry/model_definitions.go +++ b/internal/registry/model_definitions.go @@ -13,6 +13,7 @@ const ( xaiBuiltinImageQualityModelID = "grok-imagine-image-quality" xaiBuiltinVideoModelID = "grok-imagine-video" xaiBuiltinVideo15ModelID = "grok-imagine-video-1.5" + xaiBuiltinVideo15PreviewID = "grok-imagine-video-1.5-preview" ) // staticModelsJSON mirrors the top-level structure of models.json. @@ -120,7 +121,7 @@ func WithCodexBuiltins(models []*ModelInfo) []*ModelInfo { // WithXAIBuiltins injects hard-coded xAI image/video model definitions that should // not depend on remote models.json updates. func WithXAIBuiltins(models []*ModelInfo) []*ModelInfo { - return upsertModelInfos(models, xaiBuiltinImageModelInfo(), xaiBuiltinImageQualityModelInfo(), xaiBuiltinVideoModelInfo(), xaiBuiltinVideo15ModelInfo()) + return upsertModelInfos(models, xaiBuiltinImageModelInfo(), xaiBuiltinImageQualityModelInfo(), xaiBuiltinVideoModelInfo(), xaiBuiltinVideo15ModelInfo(), xaiBuiltinVideo15PreviewModelInfo()) } func normalizeAntigravityCapabilityModelID(modelID string) string { @@ -207,6 +208,19 @@ func xaiBuiltinVideo15ModelInfo() *ModelInfo { } } +func xaiBuiltinVideo15PreviewModelInfo() *ModelInfo { + return &ModelInfo{ + ID: xaiBuiltinVideo15PreviewID, + Object: "model", + Created: 1735689600, // 2025-01-01 + OwnedBy: "xai", + Type: "xai", + DisplayName: "Grok Imagine Video 1.5 Preview", + Name: xaiBuiltinVideo15PreviewID, + Description: "Compatibility alias for the xAI Grok video generation model.", + } +} + func upsertModelInfos(models []*ModelInfo, extras ...*ModelInfo) []*ModelInfo { if len(extras) == 0 { return models diff --git a/internal/registry/model_definitions_test.go b/internal/registry/model_definitions_test.go index c256e0dc..2c577773 100644 --- a/internal/registry/model_definitions_test.go +++ b/internal/registry/model_definitions_test.go @@ -35,9 +35,10 @@ func TestGeminiVertexModelsUseFlashLiteReleaseID(t *testing.T) { t.Fatalf("Vertex models do not contain %q", releaseID) } -func TestWithXAIBuiltinsUsesVideo15GAModel(t *testing.T) { +func TestWithXAIBuiltinsIncludesVideo15GAAndPreviewAlias(t *testing.T) { models := WithXAIBuiltins(nil) foundGA := false + foundPreviewAlias := false for _, model := range models { if model == nil { @@ -46,14 +47,17 @@ func TestWithXAIBuiltinsUsesVideo15GAModel(t *testing.T) { if model.ID == xaiBuiltinVideo15ModelID { foundGA = true } - if model.ID == "grok-imagine-video-1.5-preview" { - t.Fatal("xAI builtins must not advertise the retired preview alias") + if model.ID == xaiBuiltinVideo15PreviewID { + foundPreviewAlias = true } } if !foundGA { t.Fatalf("expected xAI builtin model %s", xaiBuiltinVideo15ModelID) } + if !foundPreviewAlias { + t.Fatalf("expected xAI builtin compatibility alias %s", xaiBuiltinVideo15PreviewID) + } } func TestAntigravityWebSearchModelForRequiresRequestedModelCapability(t *testing.T) { diff --git a/sdk/api/handlers/openai/openai_videos_handlers_test.go b/sdk/api/handlers/openai/openai_videos_handlers_test.go index 8b2a7afa..29666d88 100644 --- a/sdk/api/handlers/openai/openai_videos_handlers_test.go +++ b/sdk/api/handlers/openai/openai_videos_handlers_test.go @@ -870,6 +870,28 @@ func TestVideosCreatePreviewAliasUsesPreviewAuthWithGAPayload(t *testing.T) { assertPreviewAliasRouting(t, executor, videoID, "video-openai-preview-auth") } +func TestVideosCreatePreviewAliasUsesDefaultXAIModelsWithGAPayload(t *testing.T) { + resetVideoAuthBindingsForTest(t) + executor := &videoAuthCaptureExecutor{requestID: "video-openai-preview-default-models"} + handler := newVideoAuthTestHandler(t, executor, "video-openai-preview-default-auth", registry.GetXAIModels()) + + createResp := performVideosEndpointRequest(t, http.MethodPost, openAIVideosPath, "application/json", strings.NewReader(`{"model":"grok-imagine-video-1.5-preview","prompt":"make a video"}`), handler.VideosCreate) + if createResp.Code != http.StatusOK { + t.Fatalf("create status = %d, want %d: %s", createResp.Code, http.StatusOK, createResp.Body.String()) + } + videoID := gjson.GetBytes(createResp.Body.Bytes(), "id").String() + if got := gjson.GetBytes(createResp.Body.Bytes(), "model").String(); got != xaiVideos15Model { + t.Fatalf("response model = %q, want %s", got, xaiVideos15Model) + } + + retrieveResp := performVideosRouteRequest(t, http.MethodGet, openAIVideosPath+"/:video_id", openAIVideosPath+"/"+videoID, "", nil, handler.VideosRetrieve) + if retrieveResp.Code != http.StatusOK { + t.Fatalf("retrieve status = %d, want %d: %s", retrieveResp.Code, http.StatusOK, retrieveResp.Body.String()) + } + + assertPreviewAliasRouting(t, executor, videoID, "video-openai-preview-default-auth") +} + func TestXAIVideosNativePreviewAliasUsesPreviewAuthWithGAPayload(t *testing.T) { resetVideoAuthBindingsForTest(t) executor := &videoAuthCaptureExecutor{requestID: "video-native-preview-alias"} @@ -892,6 +914,12 @@ func TestXAIVideosNativePreviewAliasUsesPreviewAuthWithGAPayload(t *testing.T) { func newVideoSingleModelAuthTestHandler(t *testing.T, executor *videoAuthCaptureExecutor, authID string, model string) *OpenAIAPIHandler { t.Helper() + return newVideoAuthTestHandler(t, executor, authID, []*registry.ModelInfo{{ID: model}}) +} + +func newVideoAuthTestHandler(t *testing.T, executor *videoAuthCaptureExecutor, authID string, models []*registry.ModelInfo) *OpenAIAPIHandler { + t.Helper() + manager := coreauth.NewManager(nil, &coreauth.RoundRobinSelector{}, nil) manager.RegisterExecutor(executor) auth := &coreauth.Auth{ @@ -902,7 +930,7 @@ func newVideoSingleModelAuthTestHandler(t *testing.T, executor *videoAuthCapture if _, errRegister := manager.Register(context.Background(), auth); errRegister != nil { t.Fatalf("manager.Register(%s): %v", authID, errRegister) } - registry.GetGlobalRegistry().RegisterClient(authID, auth.Provider, []*registry.ModelInfo{{ID: model}}) + registry.GetGlobalRegistry().RegisterClient(authID, auth.Provider, models) manager.RefreshSchedulerEntry(authID) t.Cleanup(func() { registry.GetGlobalRegistry().UnregisterClient(authID) -- 2.51.2