Sub2API v1.0 - AI API 网关(二开初始版本,基于上游 Wei-Shaw/sub2api)
Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/Wei-Shaw/sub2api/internal/config"
|
||||
)
|
||||
|
||||
// DiagnoseModelAvailabilityForPlatform reports whether the requested model
|
||||
// is configured to be served by any persistently eligible OpenAI-compatible
|
||||
// account in the group for the given platform (e.g. PlatformOpenAI,
|
||||
// PlatformGrok). The platform scopes the candidate pool so distinct
|
||||
// OpenAI-compatible platforms do not cross-contaminate diagnosis results.
|
||||
// The query bypasses scheduler snapshots and ignores transient runtime state.
|
||||
//
|
||||
// Safe to call on the error path: returns {true,true} on any internal
|
||||
// failure or when the inputs preclude meaningful diagnosis (empty model,
|
||||
// nil service), so callers stay on the 503 fallback branch.
|
||||
func (s *OpenAIGatewayService) DiagnoseModelAvailabilityForPlatform(
|
||||
ctx context.Context,
|
||||
groupID *int64,
|
||||
requestedModel string,
|
||||
platform string,
|
||||
) ModelAvailabilityDiagnosis {
|
||||
if s == nil {
|
||||
return ModelAvailabilityDiagnosis{HasAccountsInPool: true, HasModelSupport: true}
|
||||
}
|
||||
requestedModel = strings.TrimSpace(requestedModel)
|
||||
if requestedModel == "" {
|
||||
return ModelAvailabilityDiagnosis{HasAccountsInPool: true, HasModelSupport: true}
|
||||
}
|
||||
if s.accountRepo == nil {
|
||||
return ModelAvailabilityDiagnosis{HasAccountsInPool: true, HasModelSupport: true}
|
||||
}
|
||||
|
||||
platform = NormalizeOpenAICompatiblePlatform(platform)
|
||||
queryGroupID := groupID
|
||||
includeGrouped := false
|
||||
if s.cfg != nil && s.cfg.RunMode == config.RunModeSimple {
|
||||
queryGroupID = nil
|
||||
includeGrouped = true
|
||||
}
|
||||
accounts, err := s.accountRepo.ListModelAvailabilityCandidates(
|
||||
ctx,
|
||||
queryGroupID,
|
||||
[]string{platform},
|
||||
includeGrouped,
|
||||
)
|
||||
if err != nil {
|
||||
// Conservative fallback so the caller keeps returning 503; we do not
|
||||
// want a transient lookup failure to flip into 404 model_not_found.
|
||||
return ModelAvailabilityDiagnosis{HasAccountsInPool: true, HasModelSupport: true}
|
||||
}
|
||||
|
||||
diag := ModelAvailabilityDiagnosis{}
|
||||
for i := range accounts {
|
||||
diag.HasAccountsInPool = true
|
||||
// Mirrors the per-candidate filter used during account selection
|
||||
// (openai_account_scheduler.isAccountRequestCompatible): empty
|
||||
// model_mapping accepts everything; otherwise the explicit / wildcard
|
||||
// mapping must match.
|
||||
if accounts[i].IsModelSupported(requestedModel) {
|
||||
diag.HasModelSupport = true
|
||||
return diag
|
||||
}
|
||||
}
|
||||
return diag
|
||||
}
|
||||
Reference in New Issue
Block a user