Merge pull request #7473 from lzfxxx/fix/codex-manifest-opencode-go

fix(codex): include OpenCode Go in model capability resolution
This commit is contained in:
Wesley Liddick
2026-09-22 18:13:00 +08:00
committed by GitHub
3 changed files with 77 additions and 2 deletions
@@ -192,6 +192,79 @@ func TestBuildCodexModelsManifestForGroupUsesSyncedAccountMetadata(t *testing.T)
require.EqualValues(t, 1_000_000, models[0]["context_window"])
}
type openCodeGoCodexCatalogRepo struct {
AccountRepository
groupID int64
accounts []Account
platforms []string
}
func (r *openCodeGoCodexCatalogRepo) ListSchedulableByGroupID(_ context.Context, _ int64) ([]Account, error) {
return nil, nil
}
func (r *openCodeGoCodexCatalogRepo) ListModelAvailabilityCandidates(_ context.Context, groupID *int64, platforms []string, _ bool) ([]Account, error) {
r.platforms = append([]string(nil), platforms...)
if groupID == nil || *groupID != r.groupID {
return nil, nil
}
for _, platform := range platforms {
if platform == PlatformOpenCodeGo {
return append([]Account(nil), r.accounts...), nil
}
}
return nil, nil
}
// Scenario: OpenCode Go accounts contribute synced capabilities to a Composite
// manifest only when they are selected by the catalog candidate query.
func TestBuildCodexModelsManifestForGroupMergesOpenCodeGoSyncedMetadata(t *testing.T) {
t.Parallel()
const groupID int64 = 742
const publicModel = "oc/muse-spark-1.3-contributor"
const upstreamModel = "muse-spark-1.3-contributor"
reasoning := true
account := Account{
ID: 43,
Platform: PlatformOpenCodeGo,
Type: AccountTypeAPIKey,
Credentials: map[string]any{
"base_url": "https://opencode.ai/zen/go/v1",
"model_mapping": map[string]any{publicModel: upstreamModel},
},
}
account.SetUpstreamModelMetadataSnapshot(UpstreamModelMetadataSnapshot{Models: map[string]UpstreamModelMetadata{
upstreamModel: {
ID: upstreamModel,
Reasoning: &reasoning,
DefaultReasoningLevel: "medium",
SupportedReasoningLevels: []string{"minimal", "low", "medium", "high", "xhigh"},
InputModalities: []string{"text", "image"},
ContextWindow: 1_048_576,
},
}})
repo := &openCodeGoCodexCatalogRepo{groupID: groupID, accounts: []Account{account}}
svc := &GatewayService{accountRepo: repo}
body, err := svc.BuildCodexModelsManifestForGroup(
context.Background(),
&Group{ID: groupID, Platform: PlatformComposite},
"",
[]string{publicModel},
)
require.NoError(t, err)
require.Contains(t, repo.platforms, PlatformOpenCodeGo)
models := decodeCodexManifestModels(t, body)
require.Len(t, models, 1)
require.Equal(t, []any{"text", "image"}, models[0]["input_modalities"])
require.Equal(t, "medium", models[0]["default_reasoning_level"])
require.Equal(t, []string{"minimal", "low", "medium", "high", "xhigh"}, effortsFromManifestModel(t, models[0]))
require.EqualValues(t, 1_048_576, models[0]["context_window"])
}
// Scenario: an explicitly non-reasoning model remains directly selectable in Codex.
func TestBuildCodexModelsManifestForGroupUsesNoneForExplicitNonReasoningMetadata(t *testing.T) {
t.Parallel()
@@ -262,6 +262,7 @@ func loadCodexGroupCatalogAccounts(ctx context.Context, repo AccountRepository,
PlatformZhipu,
PlatformDeepseek,
PlatformMiniMax,
PlatformOpenCodeGo,
},
false,
)
@@ -1074,7 +1075,7 @@ func groupCodexModelSupportsImageInput(
return false
}
}
if platform != PlatformOpenAI && platform != PlatformGrok && platform != PlatformDeepseek {
if platform != PlatformOpenAI && platform != PlatformGrok && platform != PlatformDeepseek && platform != PlatformOpenCodeGo {
return false
}
@@ -1213,7 +1214,7 @@ func accountCodexModelSupportsImageInput(account *Account, upstreamModel string)
return false
}
switch account.Platform {
case PlatformOpenAI, PlatformDeepseek:
case PlatformOpenAI, PlatformDeepseek, PlatformOpenCodeGo:
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
@@ -1114,6 +1114,7 @@ func TestBuildCodexModelsManifestForGroupLoadsAccountsOnce(t *testing.T) {
require.Contains(t, repo.platforms, PlatformGrok)
require.Contains(t, repo.platforms, PlatformDeepseek)
require.Contains(t, repo.platforms, PlatformMiniMax)
require.Contains(t, repo.platforms, PlatformOpenCodeGo)
require.NotContains(t, repo.platforms, PlatformComposite)
}