feat(api): add OpenAI compatibility for image models
- Introduced OpenAI-compatible image model support in the API, enabling integration through image generation and editing endpoints. - Added registry type for OpenAIImageModelType to classify and validate compatibility. - Implemented request handling for OpenAI-compatible image models, including JSON and multipart formats. - Enhanced executor methods to support OpenAI-compatible image streaming and non-streaming requests. - Included tests to validate model registration, streaming behavior, and multipart payload formatting.
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
internalregistry "github.com/router-for-me/CLIProxyAPI/v7/internal/registry"
|
||||
coreauth "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/auth"
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/sdk/config"
|
||||
)
|
||||
@@ -63,3 +64,71 @@ func TestRegisterModelsForAuth_UsesPreMergedExcludedModelsAttribute(t *testing.T
|
||||
t.Fatal("expected global excluded model to be present when attribute override is set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterModelsForAuth_OpenAICompatibilityImageModelType(t *testing.T) {
|
||||
service := &Service{
|
||||
cfg: &config.Config{
|
||||
OpenAICompatibility: []config.OpenAICompatibility{
|
||||
{
|
||||
Name: "images",
|
||||
BaseURL: "https://example.com/v1",
|
||||
Models: []config.OpenAICompatibilityModel{
|
||||
{Name: "upstream-image", Alias: "compat-image", Image: true},
|
||||
{Name: "upstream-chat", Alias: "compat-chat"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
auth := &coreauth.Auth{
|
||||
ID: "auth-openai-compat-image",
|
||||
Provider: "openai-compatibility",
|
||||
Status: coreauth.StatusActive,
|
||||
Attributes: map[string]string{
|
||||
"auth_kind": "api_key",
|
||||
"compat_name": "images",
|
||||
"provider_key": "images",
|
||||
},
|
||||
}
|
||||
|
||||
modelRegistry := internalregistry.GetGlobalRegistry()
|
||||
modelRegistry.UnregisterClient(auth.ID)
|
||||
t.Cleanup(func() {
|
||||
modelRegistry.UnregisterClient(auth.ID)
|
||||
})
|
||||
|
||||
service.registerModelsForAuth(auth)
|
||||
|
||||
models := modelRegistry.GetModelsForClient(auth.ID)
|
||||
var imageModel *internalregistry.ModelInfo
|
||||
var chatModel *internalregistry.ModelInfo
|
||||
for _, model := range models {
|
||||
if model == nil {
|
||||
continue
|
||||
}
|
||||
switch strings.TrimSpace(model.ID) {
|
||||
case "compat-image":
|
||||
imageModel = model
|
||||
case "compat-chat":
|
||||
chatModel = model
|
||||
}
|
||||
}
|
||||
if imageModel == nil {
|
||||
t.Fatal("expected compat-image to be registered")
|
||||
}
|
||||
if imageModel.Type != internalregistry.OpenAIImageModelType {
|
||||
t.Fatalf("image model type = %q, want %q", imageModel.Type, internalregistry.OpenAIImageModelType)
|
||||
}
|
||||
if imageModel.Thinking != nil {
|
||||
t.Fatalf("image model thinking = %+v, want nil", imageModel.Thinking)
|
||||
}
|
||||
if chatModel == nil {
|
||||
t.Fatal("expected compat-chat to be registered")
|
||||
}
|
||||
if chatModel.Type != "openai-compatibility" {
|
||||
t.Fatalf("chat model type = %q, want openai-compatibility", chatModel.Type)
|
||||
}
|
||||
if chatModel.Thinking == nil {
|
||||
t.Fatal("expected chat model to keep default thinking support")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user