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 }