mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-30 08:22:34 +00:00
Fix stale official Astra input modalities
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestBuildCodexModelsManifestForGroupCorrectsOfficialAstraStaleModalities(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const groupID int64 = 780
|
||||
account := Account{
|
||||
ID: 1,
|
||||
Platform: PlatformOpenAI,
|
||||
Type: AccountTypeAPIKey,
|
||||
Credentials: map[string]any{"api_key": "sk-test"},
|
||||
}
|
||||
account.SetUpstreamModelMetadataSnapshot(UpstreamModelMetadataSnapshot{
|
||||
Models: map[string]UpstreamModelMetadata{
|
||||
"gpt-6-astra": {ID: "gpt-6-astra", InputModalities: []string{"text"}},
|
||||
},
|
||||
})
|
||||
|
||||
svc := &GatewayService{accountRepo: codexModelsVisibilityAccountRepo{
|
||||
byGroup: map[int64][]Account{groupID: {account}},
|
||||
}}
|
||||
|
||||
body, err := svc.BuildCodexModelsManifestForGroup(
|
||||
context.Background(),
|
||||
&Group{ID: groupID, Platform: PlatformOpenAI},
|
||||
"",
|
||||
[]string{"gpt-6-astra"},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
models := decodeCodexManifestModels(t, body)
|
||||
require.Len(t, models, 1)
|
||||
require.Equal(t, []any{"text", "image"}, models[0]["input_modalities"])
|
||||
}
|
||||
|
||||
func TestBuildCodexModelsManifestForGroupPreservesCompatibleAstraTextOnlyMetadata(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const groupID int64 = 781
|
||||
account := Account{
|
||||
ID: 2,
|
||||
Platform: PlatformOpenAI,
|
||||
Type: AccountTypeAPIKey,
|
||||
Credentials: map[string]any{"api_key": "sk-test", "base_url": "https://relay.example.test/v1"},
|
||||
}
|
||||
account.SetUpstreamModelMetadataSnapshot(UpstreamModelMetadataSnapshot{
|
||||
Models: map[string]UpstreamModelMetadata{
|
||||
"gpt-6-astra": {ID: "gpt-6-astra", InputModalities: []string{"text"}},
|
||||
},
|
||||
})
|
||||
|
||||
svc := &GatewayService{accountRepo: codexModelsVisibilityAccountRepo{
|
||||
byGroup: map[int64][]Account{groupID: {account}},
|
||||
}}
|
||||
|
||||
body, err := svc.BuildCodexModelsManifestForGroup(
|
||||
context.Background(),
|
||||
&Group{ID: groupID, Platform: PlatformOpenAI},
|
||||
"",
|
||||
[]string{"gpt-6-astra"},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
models := decodeCodexManifestModels(t, body)
|
||||
require.Len(t, models, 1)
|
||||
require.Equal(t, []any{"text"}, models[0]["input_modalities"])
|
||||
}
|
||||
@@ -888,13 +888,15 @@ func buildCodexModelsManifest(
|
||||
seen[modelID] = struct{}{}
|
||||
descriptor := newConfiguredCodexModelDescriptor(metadataModelID)
|
||||
descriptor.Slug = modelID
|
||||
if imageInputModels[modelID] {
|
||||
descriptor.InputModalities = []string{"text", "image"}
|
||||
}
|
||||
descriptor.SupportsSearchTool = searchToolModels[modelID]
|
||||
if metadata, ok := modelMetadata[modelID]; ok {
|
||||
applyUpstreamModelMetadataToCodexDescriptor(&descriptor, metadata)
|
||||
}
|
||||
if imageInputModels[modelID] {
|
||||
// Apply the capability-derived modality after upstream metadata so
|
||||
// a stale official Astra snapshot cannot downgrade the catalog.
|
||||
descriptor.InputModalities = []string{"text", "image"}
|
||||
}
|
||||
if metadataModelID != modelID {
|
||||
descriptor.DisplayName = modelID
|
||||
descriptor.Description = configuredCodexCustomDescription
|
||||
@@ -1186,6 +1188,13 @@ func accountCodexModelSupportsImageInput(account *Account, upstreamModel string)
|
||||
case PlatformOpenAI:
|
||||
if metadata, ok := account.GetUpstreamModelMetadata(upstreamModel); ok {
|
||||
if modalities := normalizeCodexInputModalities(metadata.InputModalities); len(modalities) > 0 {
|
||||
// Official GPT-6 Astra metadata briefly shipped with a stale
|
||||
// text-only modality list. Keep explicit provider metadata
|
||||
// authoritative for compatible hosts, but repair that stale
|
||||
// official snapshot at the capability boundary.
|
||||
if isOpenAIGPT6AstraModel(upstreamModel) && isOfficialOpenAICodexAccount(account) {
|
||||
return true
|
||||
}
|
||||
return stringSliceContains(modalities, "image")
|
||||
}
|
||||
}
|
||||
@@ -1212,6 +1221,16 @@ func accountCodexModelSupportsImageInput(account *Account, upstreamModel string)
|
||||
}
|
||||
}
|
||||
|
||||
func isOfficialOpenAICodexAccount(account *Account) bool {
|
||||
if account == nil || account.Platform != PlatformOpenAI {
|
||||
return false
|
||||
}
|
||||
if account.IsOpenAIOAuth() {
|
||||
return true
|
||||
}
|
||||
return account.IsOpenAIApiKey() && isOfficialOpenAIModelsBaseURL(account.GetOpenAIBaseURL())
|
||||
}
|
||||
|
||||
func isGrokCodexImageInputModel(model string) bool {
|
||||
switch strings.ToLower(strings.TrimSpace(model)) {
|
||||
case "grok-4.3",
|
||||
|
||||
Reference in New Issue
Block a user