87 lines
2.5 KiB
Go
87 lines
2.5 KiB
Go
package access
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"sub2api-cn-relay-manager/internal/host/sub2api"
|
|
)
|
|
|
|
func SuspectsOpenAIResponsesCapabilityMismatch(probe sub2api.ProbeResult) bool {
|
|
if probe.OK {
|
|
return false
|
|
}
|
|
message := strings.ToLower(strings.TrimSpace(probe.Message))
|
|
if message == "" {
|
|
return false
|
|
}
|
|
if strings.Contains(message, "api returned 403: forbidden") {
|
|
return true
|
|
}
|
|
return strings.Contains(message, "responses api") &&
|
|
(strings.Contains(message, "当前测试接口仅支持") ||
|
|
strings.Contains(message, "账号本身可正常使用") ||
|
|
strings.Contains(message, "please directly") ||
|
|
strings.Contains(message, "actual api"))
|
|
}
|
|
|
|
func ShouldAttemptOpenAIResponsesCapabilityRepair(suspect bool, completion sub2api.GatewayCompletionResult) bool {
|
|
if !suspect || completion.OK {
|
|
return false
|
|
}
|
|
if completion.StatusCode != 502 && completion.StatusCode != 503 {
|
|
return false
|
|
}
|
|
body := strings.ToLower(strings.TrimSpace(completion.BodyPreview))
|
|
return strings.Contains(body, "service temporarily unavailable") ||
|
|
strings.Contains(body, "no available accounts")
|
|
}
|
|
|
|
func (s *Service) maybeRepairOpenAIResponsesCapability(ctx context.Context, req ClosureRequest, completionReq sub2api.GatewayCompletionCheckRequest, completion sub2api.GatewayCompletionResult) (sub2api.GatewayCompletionResult, error) {
|
|
if !ShouldAttemptOpenAIResponsesCapabilityRepair(req.ResponsesCapabilitySuspect, completion) {
|
|
return completion, nil
|
|
}
|
|
accountIDs := normalizedAccountIDs(req.AccountIDs)
|
|
if len(accountIDs) == 0 {
|
|
return completion, nil
|
|
}
|
|
if err := RepairOpenAIResponsesCapability(ctx, s.host, accountIDs); err != nil {
|
|
return completion, nil
|
|
}
|
|
return s.checkGatewayCompletionWithRetry(ctx, completionReq)
|
|
}
|
|
|
|
func RepairOpenAIResponsesCapability(ctx context.Context, host Host, accountIDs []string) error {
|
|
if host == nil {
|
|
return nil
|
|
}
|
|
normalized := normalizedAccountIDs(accountIDs)
|
|
if len(normalized) == 0 {
|
|
return nil
|
|
}
|
|
if err := host.DisableOpenAIResponsesAPI(ctx, normalized); err != nil {
|
|
return err
|
|
}
|
|
if err := host.ClearTempUnschedulable(ctx, normalized); err != nil {
|
|
return nil
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func normalizedAccountIDs(accountIDs []string) []string {
|
|
seen := map[string]struct{}{}
|
|
values := make([]string, 0, len(accountIDs))
|
|
for _, rawID := range accountIDs {
|
|
accountID := strings.TrimSpace(rawID)
|
|
if accountID == "" {
|
|
continue
|
|
}
|
|
if _, ok := seen[accountID]; ok {
|
|
continue
|
|
}
|
|
seen[accountID] = struct{}{}
|
|
values = append(values, accountID)
|
|
}
|
|
return values
|
|
}
|