forked from QuantumNous/new-api
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcodex_channel_models.go
More file actions
90 lines (82 loc) · 2.55 KB
/
Copy pathcodex_channel_models.go
File metadata and controls
90 lines (82 loc) · 2.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package service
import (
"context"
"fmt"
"net/http"
"strings"
"time"
"github.com/QuantumNous/new-api/constant"
"github.com/QuantumNous/new-api/model"
"github.com/QuantumNous/new-api/setting/ratio_setting"
)
func FetchCodexChannelModels(channel *model.Channel) ([]string, error) {
if channel == nil || channel.Type != constant.ChannelTypeCodex {
return nil, fmt.Errorf("channel type is not Codex")
}
if channel.ChannelInfo.IsMultiKey {
return nil, fmt.Errorf("codex channel does not support multi-key model discovery")
}
client, err := NewProxyHttpClient(channel.GetSetting().Proxy)
if err != nil {
return nil, err
}
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
clientVersion, err := GetLatestCodexClientVersion(ctx, client)
if err != nil {
return nil, fmt.Errorf("failed to get Codex client version: %w", err)
}
baseURL := channel.GetBaseURL()
if baseURL == "" {
baseURL = constant.ChannelBaseURLs[constant.ChannelTypeCodex]
}
return fetchCodexChannelModels(ctx, channel, baseURL, client, clientVersion)
}
func fetchCodexChannelModels(
ctx context.Context,
channel *model.Channel,
baseURL string,
client *http.Client,
clientVersion string,
) ([]string, error) {
oauthKey, err := parseCodexOAuthKey(strings.TrimSpace(channel.Key))
if err != nil {
return nil, err
}
statusCode, models, err := FetchCodexModels(ctx, client, baseURL, oauthKey, clientVersion)
if err != nil {
return nil, err
}
if statusCode == http.StatusUnauthorized {
if channel.Id <= 0 {
return nil, fmt.Errorf("codex channel credential expired; save the channel before retrying model fetch")
}
refreshedKey, _, refreshErr := RefreshCodexChannelCredential(
ctx,
channel.Id,
CodexCredentialRefreshOptions{ResetCaches: true},
)
if refreshErr != nil {
return nil, fmt.Errorf("failed to refresh Codex channel credential: %w", refreshErr)
}
statusCode, models, err = FetchCodexModels(ctx, client, baseURL, &CodexOAuthKey{
AccessToken: refreshedKey.AccessToken,
AccountID: refreshedKey.AccountID,
}, clientVersion)
if err != nil {
return nil, err
}
}
if statusCode < http.StatusOK || statusCode >= http.StatusMultipleChoices {
return nil, fmt.Errorf("upstream status: %d", statusCode)
}
modelVariants := make([]string, 0, len(models)*2)
modelVariants = append(modelVariants, models...)
for _, modelName := range models {
if modelName == "codex-auto-review" {
continue
}
modelVariants = append(modelVariants, ratio_setting.WithCompactModelSuffix(modelName))
}
return modelVariants, nil
}