feat(vnext): complete vNext.1 release gate — default chain admission, idempotent init, user key skeleton
Some checks failed
CI / Build & Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Release (push) Has been cancelled

- DEFAULT_CHAIN_ADMISSION.md: reviewed and approved, real artifact refs added
- DEFAULT_DATA_IDEMPOTENT_RELEASE_GATE.md: reviewed and approved
- scripts/setup_default_data.sh: idempotent init with --dry-run/--apply/artifact
- scripts/test/test_default_data.sh: 4 test cases all pass
- scripts/acceptance/verify_user_key_self_service.sh: Phase 0 skeleton
- .gitignore: add generated artifact directories
This commit is contained in:
phamnazage-jpg
2026-06-05 11:07:50 +08:00
parent 77b7f7f660
commit 492f33a129
33 changed files with 5252 additions and 2 deletions

View File

@@ -0,0 +1,68 @@
package sub2api
import (
"strings"
"sub2api-cn-relay-manager/internal/probe"
)
const (
SupportLevelDirect = "supported-direct"
SupportLevelWithPluginAdapter = "supported-with-plugin-adapter"
SupportLevelUnsupportedByHost = "unsupported-by-host"
SupportLevelUpstreamUnhealthy = "upstream-unhealthy"
)
type CapabilityInventory struct {
HostReady bool `json:"host_ready"`
Host HostCapabilities `json:"host"`
Models []ModelCapabilitySummary `json:"models"`
}
type ModelCapabilitySummary struct {
RawModelID string `json:"raw_model_id"`
CanonicalModelFamily string `json:"canonical_model_family"`
SmokeChatOK bool `json:"smoke_chat_ok"`
SupportLevel string `json:"support_level"`
KnownAdvisories []string `json:"known_advisories,omitempty"`
}
func BuildCapabilityInventory(hostCaps HostCapabilities, profile *probe.CapabilityProfile) CapabilityInventory {
inventory := CapabilityInventory{
HostReady: hasMinimumHostCapabilities(hostCaps),
Host: hostCaps,
Models: []ModelCapabilitySummary{},
}
if profile == nil {
return inventory
}
advisories := append([]string(nil), profile.TransportProfile.KnownAdvisories...)
for _, model := range profile.ModelProfiles {
inventory.Models = append(inventory.Models, ModelCapabilitySummary{
RawModelID: strings.TrimSpace(model.RawModelID),
CanonicalModelFamily: strings.TrimSpace(model.CanonicalModelFamily),
SmokeChatOK: model.SmokeChatOK,
SupportLevel: classifySupportLevel(profile.TransportProfile, model),
KnownAdvisories: advisories,
})
}
return inventory
}
func hasMinimumHostCapabilities(c HostCapabilities) bool {
return c.Groups && c.Channels && c.Accounts && c.AccountTest
}
func classifySupportLevel(transport probe.TransportProfile, model probe.ModelCapabilityProfile) string {
if !model.SmokeChatOK {
return SupportLevelUpstreamUnhealthy
}
if transport.SupportsOpenAIChatCompletions && transport.SupportsOpenAIResponses {
return SupportLevelDirect
}
if transport.SupportsOpenAIChatCompletions {
return SupportLevelWithPluginAdapter
}
return SupportLevelUnsupportedByHost
}

View File

@@ -0,0 +1,76 @@
package sub2api
import (
"testing"
"sub2api-cn-relay-manager/internal/probe"
)
func TestBuildCapabilityInventoryClassifiesSupportedWithAdapter(t *testing.T) {
t.Parallel()
inventory := BuildCapabilityInventory(
HostCapabilities{
Groups: true,
Channels: true,
Plans: true,
Accounts: true,
AccountTest: true,
AccountModels: true,
Subscriptions: true,
},
&probe.CapabilityProfile{
TransportProfile: probe.TransportProfile{
SupportsOpenAIModels: true,
SupportsOpenAIChatCompletions: true,
SupportsOpenAIResponses: false,
KnownAdvisories: []string{"responses_unsupported_but_chat_ok"},
},
ModelProfiles: []probe.ModelCapabilityProfile{{
RawModelID: "kimi-k2.6",
CanonicalModelFamily: "kimi-k2.6",
SmokeChatOK: true,
}},
},
)
if !inventory.HostReady {
t.Fatal("HostReady = false, want true")
}
if len(inventory.Models) != 1 {
t.Fatalf("len(Models) = %d, want 1", len(inventory.Models))
}
if inventory.Models[0].SupportLevel != SupportLevelWithPluginAdapter {
t.Fatalf("SupportLevel = %q, want %q", inventory.Models[0].SupportLevel, SupportLevelWithPluginAdapter)
}
}
func TestBuildCapabilityInventoryClassifiesUpstreamUnhealthy(t *testing.T) {
t.Parallel()
inventory := BuildCapabilityInventory(
HostCapabilities{Groups: true, Channels: true, Accounts: true, AccountTest: false},
&probe.CapabilityProfile{
TransportProfile: probe.TransportProfile{
SupportsOpenAIModels: true,
SupportsOpenAIChatCompletions: false,
SupportsOpenAIResponses: false,
},
ModelProfiles: []probe.ModelCapabilityProfile{{
RawModelID: "glm-4.5",
CanonicalModelFamily: "glm-4.5",
SmokeChatOK: false,
}},
},
)
if inventory.HostReady {
t.Fatal("HostReady = true, want false when required host capabilities are missing")
}
if len(inventory.Models) != 1 {
t.Fatalf("len(Models) = %d, want 1", len(inventory.Models))
}
if inventory.Models[0].SupportLevel != SupportLevelUpstreamUnhealthy {
t.Fatalf("SupportLevel = %q, want %q", inventory.Models[0].SupportLevel, SupportLevelUpstreamUnhealthy)
}
}