Add projects
This commit is contained in:
parent
2d3a9ad623
commit
8b607dd700
1802 changed files with 503346 additions and 2 deletions
|
|
@ -0,0 +1,237 @@
|
|||
package openai
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/internal/registry"
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/internal/thinking"
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/internal/util"
|
||||
coreauth "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/auth"
|
||||
)
|
||||
|
||||
func websocketUpstreamSupportsIncrementalInput(attributes map[string]string, metadata map[string]any) bool {
|
||||
if len(attributes) > 0 {
|
||||
if raw := strings.TrimSpace(attributes["websockets"]); raw != "" {
|
||||
parsed, errParse := strconv.ParseBool(raw)
|
||||
if errParse == nil {
|
||||
return parsed
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(metadata) == 0 {
|
||||
return false
|
||||
}
|
||||
raw, ok := metadata["websockets"]
|
||||
if !ok || raw == nil {
|
||||
return false
|
||||
}
|
||||
switch value := raw.(type) {
|
||||
case bool:
|
||||
return value
|
||||
case string:
|
||||
parsed, errParse := strconv.ParseBool(strings.TrimSpace(value))
|
||||
if errParse == nil {
|
||||
return parsed
|
||||
}
|
||||
default:
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *OpenAIResponsesAPIHandler) websocketUpstreamSupportsIncrementalInputForModel(modelName string) bool {
|
||||
auths, _ := h.responsesWebsocketAvailableAuthsForModel(modelName)
|
||||
for _, auth := range auths {
|
||||
if responsesWebsocketAuthSupportsIncrementalInput(auth) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *OpenAIResponsesAPIHandler) websocketUpstreamSupportsCompactionReplayForModel(modelName string) bool {
|
||||
auths, _ := h.responsesWebsocketAvailableAuthsForModel(modelName)
|
||||
if len(auths) == 0 {
|
||||
return false
|
||||
}
|
||||
for _, auth := range auths {
|
||||
if !responsesWebsocketAuthSupportsCompactionReplay(auth) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *OpenAIResponsesAPIHandler) responsesWebsocketAvailableAuthsForModel(modelName string) ([]*coreauth.Auth, string) {
|
||||
if h == nil || h.AuthManager == nil {
|
||||
return nil, ""
|
||||
}
|
||||
resolvedModelName := responsesWebsocketResolvedModelName(modelName)
|
||||
providerSet, modelKey := responsesWebsocketProviderSetForModel(resolvedModelName)
|
||||
if len(providerSet) == 0 {
|
||||
return nil, modelKey
|
||||
}
|
||||
|
||||
registryRef := registry.GetGlobalRegistry()
|
||||
now := time.Now()
|
||||
auths := h.AuthManager.List()
|
||||
available := make([]*coreauth.Auth, 0, len(auths))
|
||||
for _, auth := range auths {
|
||||
if !responsesWebsocketAuthMatchesModel(auth, providerSet, modelKey, registryRef, now) {
|
||||
continue
|
||||
}
|
||||
available = append(available, auth)
|
||||
}
|
||||
return available, modelKey
|
||||
}
|
||||
|
||||
func (h *OpenAIResponsesAPIHandler) responsesWebsocketUsesCodexWebsocketPassthrough(modelName string) bool {
|
||||
return h.responsesWebsocketUsesUpstreamWebsocketPassthrough(modelName)
|
||||
}
|
||||
|
||||
func (h *OpenAIResponsesAPIHandler) responsesWebsocketUsesUpstreamWebsocketPassthrough(modelName string) bool {
|
||||
modelName = strings.TrimSpace(modelName)
|
||||
if h == nil || h.AuthManager == nil || modelName == "" {
|
||||
return false
|
||||
}
|
||||
auths, _ := h.responsesWebsocketAvailableAuthsForModel(modelName)
|
||||
if len(auths) == 0 {
|
||||
return false
|
||||
}
|
||||
provider := ""
|
||||
for _, auth := range auths {
|
||||
if auth == nil {
|
||||
return false
|
||||
}
|
||||
authProvider := strings.ToLower(strings.TrimSpace(auth.Provider))
|
||||
if authProvider != "codex" && authProvider != "xai" {
|
||||
return false
|
||||
}
|
||||
if provider == "" {
|
||||
provider = authProvider
|
||||
if _, ok := h.AuthManager.Executor(provider); !ok {
|
||||
return false
|
||||
}
|
||||
} else if authProvider != provider {
|
||||
return false
|
||||
}
|
||||
if !websocketUpstreamSupportsIncrementalInput(auth.Attributes, auth.Metadata) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return provider != ""
|
||||
}
|
||||
|
||||
func responsesWebsocketAuthSupportsIncrementalInput(auth *coreauth.Auth) bool {
|
||||
if auth == nil {
|
||||
return false
|
||||
}
|
||||
return websocketUpstreamSupportsIncrementalInput(auth.Attributes, auth.Metadata)
|
||||
}
|
||||
|
||||
func responsesWebsocketPinnedAuthMatchesModel(auth *coreauth.Auth, modelName string, pinnedModelKey string, homeRuntime bool) bool {
|
||||
if auth == nil {
|
||||
return false
|
||||
}
|
||||
providerSet, modelKey := responsesWebsocketProviderSetForModel(responsesWebsocketResolvedModelName(modelName))
|
||||
providerKey := strings.ToLower(strings.TrimSpace(auth.Provider))
|
||||
if _, ok := providerSet[providerKey]; !ok {
|
||||
return false
|
||||
}
|
||||
if !responsesWebsocketAuthAvailableForModel(auth, modelKey, time.Now()) {
|
||||
return false
|
||||
}
|
||||
|
||||
if homeRuntime {
|
||||
return strings.EqualFold(strings.TrimSpace(pinnedModelKey), strings.TrimSpace(modelKey))
|
||||
}
|
||||
return registry.GetGlobalRegistry().ClientSupportsModel(auth.ID, modelKey)
|
||||
}
|
||||
|
||||
func responsesWebsocketResolvedModelName(modelName string) string {
|
||||
initialSuffix := thinking.ParseSuffix(modelName)
|
||||
if initialSuffix.ModelName == "auto" {
|
||||
resolvedBase := util.ResolveAutoModel(initialSuffix.ModelName)
|
||||
if initialSuffix.HasSuffix {
|
||||
return fmt.Sprintf("%s(%s)", resolvedBase, initialSuffix.RawSuffix)
|
||||
}
|
||||
return resolvedBase
|
||||
}
|
||||
return util.ResolveAutoModel(modelName)
|
||||
}
|
||||
|
||||
func responsesWebsocketProviderSetForModel(resolvedModelName string) (map[string]struct{}, string) {
|
||||
parsed := thinking.ParseSuffix(resolvedModelName)
|
||||
baseModel := strings.TrimSpace(parsed.ModelName)
|
||||
providers := util.GetProviderName(baseModel)
|
||||
if len(providers) == 0 && baseModel != resolvedModelName {
|
||||
providers = util.GetProviderName(resolvedModelName)
|
||||
}
|
||||
providerSet := make(map[string]struct{}, len(providers))
|
||||
for _, provider := range providers {
|
||||
providerKey := strings.TrimSpace(strings.ToLower(provider))
|
||||
if providerKey == "" {
|
||||
continue
|
||||
}
|
||||
providerSet[providerKey] = struct{}{}
|
||||
}
|
||||
modelKey := baseModel
|
||||
if modelKey == "" {
|
||||
modelKey = strings.TrimSpace(resolvedModelName)
|
||||
}
|
||||
return providerSet, modelKey
|
||||
}
|
||||
|
||||
func responsesWebsocketAuthMatchesModel(auth *coreauth.Auth, providerSet map[string]struct{}, modelKey string, registryRef *registry.ModelRegistry, now time.Time) bool {
|
||||
if auth == nil {
|
||||
return false
|
||||
}
|
||||
providerKey := strings.TrimSpace(strings.ToLower(auth.Provider))
|
||||
if _, ok := providerSet[providerKey]; !ok {
|
||||
return false
|
||||
}
|
||||
if modelKey != "" && registryRef != nil && !registryRef.ClientSupportsModel(auth.ID, modelKey) {
|
||||
return false
|
||||
}
|
||||
return responsesWebsocketAuthAvailableForModel(auth, modelKey, now)
|
||||
}
|
||||
|
||||
func responsesWebsocketAuthSupportsCompactionReplay(auth *coreauth.Auth) bool {
|
||||
if auth == nil {
|
||||
return false
|
||||
}
|
||||
return strings.EqualFold(strings.TrimSpace(auth.Provider), "codex")
|
||||
}
|
||||
|
||||
func responsesWebsocketAuthAvailableForModel(auth *coreauth.Auth, modelName string, now time.Time) bool {
|
||||
if auth == nil {
|
||||
return false
|
||||
}
|
||||
if auth.Disabled || auth.Status == coreauth.StatusDisabled {
|
||||
return false
|
||||
}
|
||||
if modelName != "" && len(auth.ModelStates) > 0 {
|
||||
state, ok := auth.ModelStates[modelName]
|
||||
if (!ok || state == nil) && modelName != "" {
|
||||
baseModel := strings.TrimSpace(thinking.ParseSuffix(modelName).ModelName)
|
||||
if baseModel != "" && baseModel != modelName {
|
||||
state, ok = auth.ModelStates[baseModel]
|
||||
}
|
||||
}
|
||||
if ok && state != nil {
|
||||
if state.Status == coreauth.StatusDisabled {
|
||||
return false
|
||||
}
|
||||
if state.Unavailable && !state.NextRetryAfter.IsZero() && state.NextRetryAfter.After(now) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
if auth.Unavailable && !auth.NextRetryAfter.IsZero() && auth.NextRetryAfter.After(now) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
Loading…
Reference in a new issue