Compare commits
6
Commits
dev
..
1f5e1c221c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f5e1c221c | ||
|
|
24bac8e38d | ||
|
|
fb5b1a55ae | ||
|
|
07bcabc5d4 | ||
|
|
8f6f3313f5 | ||
|
|
f8b364a052 |
@@ -77,9 +77,6 @@ wget https://github.com/mirrors2/opencatd-open/raw/main/docker/docker-compose.ym
|
|||||||
- [Fly.io](https://fly.io/)
|
- [Fly.io](https://fly.io/)
|
||||||
- 或者其他
|
- 或者其他
|
||||||
|
|
||||||
修改openai的endpoint地址?使用任意上游地址(套娃代理)
|
|
||||||
- 设置环境变量 openai_endpoint
|
|
||||||
|
|
||||||
使用Nginx + Docker部署
|
使用Nginx + Docker部署
|
||||||
- [使用Nginx + Docker部署](./doc/deploy.md)
|
- [使用Nginx + Docker部署](./doc/deploy.md)
|
||||||
|
|
||||||
@@ -87,12 +84,13 @@ pandora for team
|
|||||||
- [pandora for team](./doc/pandora.md)
|
- [pandora for team](./doc/pandora.md)
|
||||||
|
|
||||||
如何自定义HOST地址? (仅OpenAI)
|
如何自定义HOST地址? (仅OpenAI)
|
||||||
- 需修改环境变量,优先级递增
|
- 需修改环境变量,优先级递增(全局配置谨慎修改)
|
||||||
- Cloudflare AI Gateway地址 `AIGateWay_Endpoint=https://gateway.ai.cloudflare.com/v1/123456789/xxxx/openai/chat/completions`
|
- Cloudflare AI Gateway地址 `AIGateWay_Endpoint=https://gateway.ai.cloudflare.com/v1/123456789/xxxx/openai/chat/completions`
|
||||||
- 自定义的endpoint `$CUSTOM_ENDPOINT=true && $OpenAI_Endpoint=https://your.domain/v1/chat/completions`
|
- 自定义的endpoint `OpenAI_Endpoint=https://your.domain/v1/chat/completions`
|
||||||
|
|
||||||
设置主页跳转地址?
|
设置主页跳转地址?
|
||||||
- 修改环境变量 `CUSTOM_REDIRECT=https://your.domain`
|
- 修改环境变量 `CUSTOM_REDIRECT=https://your.domain`
|
||||||
|
|
||||||
## 获取更多信息
|
## 获取更多信息
|
||||||
[](https://t.me/OpenTeamLLM)
|
[](https://t.me/OpenTeamLLM)
|
||||||
|
|
||||||
|
|||||||
+38
-32
@@ -143,51 +143,57 @@ func ChatMessages(c *gin.Context, chatReq *openai.ChatCompletionRequest) {
|
|||||||
claudReq.Model = ""
|
claudReq.Model = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
var prompt string
|
|
||||||
|
|
||||||
var claudecontent []VisionContent
|
var claudecontent []VisionContent
|
||||||
|
var prompt string
|
||||||
for _, msg := range chatReq.Messages {
|
for _, msg := range chatReq.Messages {
|
||||||
|
switch ct := msg.Content.(type) {
|
||||||
|
case string:
|
||||||
|
prompt += "<" + msg.Role + ">: " + msg.Content.(string) + "\n"
|
||||||
if msg.Role == "system" {
|
if msg.Role == "system" {
|
||||||
claudReq.System = string(msg.Content)
|
claudReq.System = msg.Content.(string)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
claudecontent = append(claudecontent, VisionContent{Type: "text", Text: msg.Role + ":" + msg.Content.(string)})
|
||||||
var oaivisioncontent []openai.VisionContent
|
case []any:
|
||||||
if err := json.Unmarshal(msg.Content, &oaivisioncontent); err != nil {
|
for _, item := range ct {
|
||||||
prompt += "<" + msg.Role + ">: " + string(msg.Content) + "\n"
|
if m, ok := item.(map[string]interface{}); ok {
|
||||||
|
if m["type"] == "text" {
|
||||||
claudecontent = append(claudecontent, VisionContent{Type: "text", Text: msg.Role + ":" + string(msg.Content)})
|
prompt += "<" + msg.Role + ">: " + m["text"].(string) + "\n"
|
||||||
} else {
|
claudecontent = append(claudecontent, VisionContent{Type: "text", Text: msg.Role + ":" + m["text"].(string)})
|
||||||
if len(oaivisioncontent) > 0 {
|
} else if m["type"] == "image_url" {
|
||||||
for _, content := range oaivisioncontent {
|
if url, ok := m["image_url"].(map[string]interface{}); ok {
|
||||||
if content.Type == "text" {
|
fmt.Printf(" URL: %v\n", url["url"])
|
||||||
prompt += "<" + msg.Role + ">: " + content.Text + "\n"
|
if strings.HasPrefix(url["url"].(string), "http") {
|
||||||
claudecontent = append(claudecontent, VisionContent{Type: "text", Text: msg.Role + ":" + content.Text})
|
fmt.Println("网络图片:", url["url"].(string))
|
||||||
} else if content.Type == "image_url" {
|
} else if strings.HasPrefix(url["url"].(string), "data:image") {
|
||||||
if strings.HasPrefix(content.ImageURL.URL, "http") {
|
fmt.Println("base64:", url["url"].(string)[:20])
|
||||||
fmt.Println("链接:", content.ImageURL.URL)
|
|
||||||
} else if strings.HasPrefix(content.ImageURL.URL, "data:image") {
|
|
||||||
fmt.Println("base64:", content.ImageURL.URL[:20])
|
|
||||||
}
|
|
||||||
// todo image tokens
|
|
||||||
var mediaType string
|
var mediaType string
|
||||||
if strings.HasPrefix(content.ImageURL.URL, "data:image/jpeg") {
|
if strings.HasPrefix(url["url"].(string), "data:image/jpeg") {
|
||||||
mediaType = "image/jpeg"
|
mediaType = "image/jpeg"
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(content.ImageURL.URL, "data:image/png") {
|
if strings.HasPrefix(url["url"].(string), "data:image/png") {
|
||||||
mediaType = "image/png"
|
mediaType = "image/png"
|
||||||
}
|
}
|
||||||
claudecontent = append(claudecontent, VisionContent{Type: "image", Source: &VisionSource{Type: "base64", MediaType: mediaType, Data: strings.Split(content.ImageURL.URL, ",")[1]}})
|
claudecontent = append(claudecontent, VisionContent{Type: "image", Source: &VisionSource{Type: "base64", MediaType: mediaType, Data: strings.Split(url["url"].(string), ",")[1]}})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{
|
||||||
|
"error": gin.H{
|
||||||
|
"message": "Invalid content type",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(chatReq.Tools) > 0 {
|
||||||
|
tooljson, _ := json.Marshal(chatReq.Tools)
|
||||||
|
prompt += "<tools>: " + string(tooljson) + "\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if len(chatReq.Tools) > 0 {
|
|
||||||
// tooljson, _ := json.Marshal(chatReq.Tools)
|
|
||||||
// prompt += "<tools>: " + string(tooljson) + "\n"
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
claudReq.Messages = []VisionMessages{{Role: "user", Content: claudecontent}}
|
claudReq.Messages = []VisionMessages{{Role: "user", Content: claudecontent}}
|
||||||
|
|
||||||
usagelog.PromptCount = tokenizer.NumTokensFromStr(prompt, chatReq.Model)
|
usagelog.PromptCount = tokenizer.NumTokensFromStr(prompt, chatReq.Model)
|
||||||
|
|||||||
+28
-31
@@ -97,36 +97,33 @@ func ChatProxy(c *gin.Context, chatReq *openai.ChatCompletionRequest) {
|
|||||||
var prompts []genai.Part
|
var prompts []genai.Part
|
||||||
var prompt string
|
var prompt string
|
||||||
for _, msg := range chatReq.Messages {
|
for _, msg := range chatReq.Messages {
|
||||||
var visioncontent []openai.VisionContent
|
switch ct := msg.Content.(type) {
|
||||||
if err := json.Unmarshal(msg.Content, &visioncontent); err != nil {
|
case string:
|
||||||
prompt += "<" + msg.Role + ">: " + string(msg.Content) + "\n"
|
prompt += "<" + msg.Role + ">: " + msg.Content.(string) + "\n"
|
||||||
prompts = append(prompts, genai.Text("<"+msg.Role+">: "+string(msg.Content)))
|
prompts = append(prompts, genai.Text("<"+msg.Role+">: "+msg.Content.(string)))
|
||||||
} else {
|
case []any:
|
||||||
if len(visioncontent) > 0 {
|
for _, item := range ct {
|
||||||
for _, content := range visioncontent {
|
if m, ok := item.(map[string]interface{}); ok {
|
||||||
if content.Type == "text" {
|
if m["type"] == "text" {
|
||||||
prompt += "<" + msg.Role + ">: " + content.Text + "\n"
|
prompt += "<" + msg.Role + ">: " + m["text"].(string) + "\n"
|
||||||
prompts = append(prompts, genai.Text("<"+msg.Role+">: "+content.Text))
|
prompts = append(prompts, genai.Text("<"+msg.Role+">: "+m["text"].(string)))
|
||||||
} else if content.Type == "image_url" {
|
} else if m["type"] == "image_url" {
|
||||||
if strings.HasPrefix(content.ImageURL.URL, "http") {
|
if url, ok := m["image_url"].(map[string]interface{}); ok {
|
||||||
fmt.Println("链接:", content.ImageURL.URL)
|
if strings.HasPrefix(url["url"].(string), "http") {
|
||||||
} else if strings.HasPrefix(content.ImageURL.URL, "data:image") {
|
fmt.Println("网络图片:", url["url"].(string))
|
||||||
fmt.Println("base64:", content.ImageURL.URL[:20])
|
} else if strings.HasPrefix(url["url"].(string), "data:image") {
|
||||||
if chatReq.Model != "gemini-pro-vision" {
|
fmt.Println("base64:", url["url"].(string)[:20])
|
||||||
chatReq.Model = "gemini-pro-vision"
|
|
||||||
}
|
|
||||||
|
|
||||||
var mime string
|
var mime string
|
||||||
// openai 会以 data:image 开头,则去掉 data:image/png;base64, 和 data:image/jpeg;base64,
|
// openai 会以 data:image 开头,则去掉 data:image/png;base64, 和 data:image/jpeg;base64,
|
||||||
if strings.HasPrefix(content.ImageURL.URL, "data:image/png") {
|
if strings.HasPrefix(url["url"].(string), "data:image/png") {
|
||||||
mime = "image/png"
|
mime = "image/png"
|
||||||
} else if strings.HasPrefix(content.ImageURL.URL, "data:image/jpeg") {
|
} else if strings.HasPrefix(url["url"].(string), "data:image/jpeg") {
|
||||||
mime = "image/jpeg"
|
mime = "image/jpeg"
|
||||||
} else {
|
} else {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Unsupported image format"})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Unsupported image format"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
imageString := strings.Split(content.ImageURL.URL, ",")[1]
|
imageString := strings.Split(url["url"].(string), ",")[1]
|
||||||
imageBytes, err := base64.StdEncoding.DecodeString(imageString)
|
imageBytes, err := base64.StdEncoding.DecodeString(imageString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
@@ -134,22 +131,21 @@ func ChatProxy(c *gin.Context, chatReq *openai.ChatCompletionRequest) {
|
|||||||
}
|
}
|
||||||
prompts = append(prompts, genai.Blob{MIMEType: mime, Data: imageBytes})
|
prompts = append(prompts, genai.Blob{MIMEType: mime, Data: imageBytes})
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo image tokens
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{
|
||||||
|
"error": gin.H{
|
||||||
|
"message": "Invalid content type",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
if len(chatReq.Tools) > 0 {
|
if len(chatReq.Tools) > 0 {
|
||||||
tooljson, _ := json.Marshal(chatReq.Tools)
|
tooljson, _ := json.Marshal(chatReq.Tools)
|
||||||
prompt += "<tools>: " + string(tooljson) + "\n"
|
prompt += "<tools>: " + string(tooljson) + "\n"
|
||||||
|
|
||||||
// for _, tool := range chatReq.Tools {
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,6 +167,7 @@ func ChatProxy(c *gin.Context, chatReq *openai.ChatCompletionRequest) {
|
|||||||
defer client.Close()
|
defer client.Close()
|
||||||
|
|
||||||
model := client.GenerativeModel(chatReq.Model)
|
model := client.GenerativeModel(chatReq.Model)
|
||||||
|
model.Tools = []*genai.Tool{}
|
||||||
|
|
||||||
iter := model.GenerateContentStream(ctx, prompts...)
|
iter := model.GenerateContentStream(ctx, prompts...)
|
||||||
datachan := make(chan string)
|
datachan := make(chan string)
|
||||||
|
|||||||
+32
-28
@@ -25,13 +25,13 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
BaseURL string // "https://api.openai.com"
|
Custom_Endpoint string
|
||||||
AIGateWay_Endpoint = "https://gateway.ai.cloudflare.com/v1/431ba10f11200d544922fbca177aaa7f/openai/openai/chat/completions"
|
AIGateWay_Endpoint string // "https://gateway.ai.cloudflare.com/v1/431ba10f11200d544922fbca177aaa7f/openai/openai/chat/completions"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if os.Getenv("OpenAI_Endpoint") != "" {
|
if os.Getenv("OpenAI_Endpoint") != "" {
|
||||||
BaseURL = os.Getenv("OpenAI_Endpoint")
|
Custom_Endpoint = os.Getenv("OpenAI_Endpoint")
|
||||||
}
|
}
|
||||||
if os.Getenv("AIGateWay_Endpoint") != "" {
|
if os.Getenv("AIGateWay_Endpoint") != "" {
|
||||||
AIGateWay_Endpoint = os.Getenv("AIGateWay_Endpoint")
|
AIGateWay_Endpoint = os.Getenv("AIGateWay_Endpoint")
|
||||||
@@ -51,7 +51,7 @@ type VisionImageURL struct {
|
|||||||
|
|
||||||
type ChatCompletionMessage struct {
|
type ChatCompletionMessage struct {
|
||||||
Role string `json:"role"`
|
Role string `json:"role"`
|
||||||
Content json.RawMessage `json:"content"`
|
Content any `json:"content"`
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
// MultiContent []VisionContent
|
// MultiContent []VisionContent
|
||||||
}
|
}
|
||||||
@@ -185,28 +185,32 @@ func ChatProxy(c *gin.Context, chatReq *ChatCompletionRequest) {
|
|||||||
|
|
||||||
var prompt string
|
var prompt string
|
||||||
for _, msg := range chatReq.Messages {
|
for _, msg := range chatReq.Messages {
|
||||||
// prompt += "<" + msg.Role + ">: " + msg.Content + "\n"
|
switch ct := msg.Content.(type) {
|
||||||
var visioncontent []VisionContent
|
case string:
|
||||||
if err := json.Unmarshal(msg.Content, &visioncontent); err != nil {
|
prompt += "<" + msg.Role + ">: " + msg.Content.(string) + "\n"
|
||||||
prompt += "<" + msg.Role + ">: " + string(msg.Content) + "\n"
|
case []any:
|
||||||
} else {
|
for _, item := range ct {
|
||||||
if len(visioncontent) > 0 {
|
if m, ok := item.(map[string]interface{}); ok {
|
||||||
for _, content := range visioncontent {
|
if m["type"] == "text" {
|
||||||
if content.Type == "text" {
|
prompt += "<" + msg.Role + ">: " + m["text"].(string) + "\n"
|
||||||
prompt += "<" + msg.Role + ">: " + content.Text + "\n"
|
} else if m["type"] == "image_url" {
|
||||||
} else if content.Type == "image_url" {
|
if url, ok := m["image_url"].(map[string]interface{}); ok {
|
||||||
if strings.HasPrefix(content.ImageURL.URL, "http") {
|
fmt.Printf(" URL: %v\n", url["url"])
|
||||||
fmt.Println("链接:", content.ImageURL.URL)
|
if strings.HasPrefix(url["url"].(string), "http") {
|
||||||
} else if strings.HasPrefix(content.ImageURL.URL, "data:image") {
|
fmt.Println("网络图片:", url["url"].(string))
|
||||||
fmt.Println("base64:", content.ImageURL.URL[:20])
|
|
||||||
}
|
}
|
||||||
// todo image tokens
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{
|
||||||
|
"error": gin.H{
|
||||||
|
"message": "Invalid content type",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
if len(chatReq.Tools) > 0 {
|
if len(chatReq.Tools) > 0 {
|
||||||
tooljson, _ := json.Marshal(chatReq.Tools)
|
tooljson, _ := json.Marshal(chatReq.Tools)
|
||||||
prompt += "<tools>: " + string(tooljson) + "\n"
|
prompt += "<tools>: " + string(tooljson) + "\n"
|
||||||
@@ -247,16 +251,16 @@ func ChatProxy(c *gin.Context, chatReq *ChatCompletionRequest) {
|
|||||||
req.Header = c.Request.Header
|
req.Header = c.Request.Header
|
||||||
req.Header.Set("api-key", onekey.Key)
|
req.Header.Set("api-key", onekey.Key)
|
||||||
default:
|
default:
|
||||||
req, err = http.NewRequest(c.Request.Method, OpenAI_Endpoint, bytes.NewReader(chatReq.ToByteJson()))
|
req, err = http.NewRequest(c.Request.Method, OpenAI_Endpoint, bytes.NewReader(chatReq.ToByteJson())) // default endpoint
|
||||||
if onekey.EndPoint != "" { // 优先key的endpoint
|
|
||||||
req, err = http.NewRequest(c.Request.Method, onekey.EndPoint+c.Request.RequestURI, bytes.NewReader(chatReq.ToByteJson()))
|
|
||||||
}
|
|
||||||
if AIGateWay_Endpoint != "" { // cloudflare gateway的endpoint
|
if AIGateWay_Endpoint != "" { // cloudflare gateway的endpoint
|
||||||
req, err = http.NewRequest(c.Request.Method, AIGateWay_Endpoint, bytes.NewReader(chatReq.ToByteJson()))
|
req, err = http.NewRequest(c.Request.Method, AIGateWay_Endpoint, bytes.NewReader(chatReq.ToByteJson()))
|
||||||
}
|
}
|
||||||
customEndpoint := os.Getenv("CUSTOM_ENDPOINT") // 最后是用户自定义的endpoint CUSTOM_ENDPOINT=true OpenAI_Endpoint
|
if Custom_Endpoint != "" { // 自定义endpoint
|
||||||
if customEndpoint == "true" && OpenAI_Endpoint != "" {
|
req, err = http.NewRequest(c.Request.Method, Custom_Endpoint, bytes.NewReader(chatReq.ToByteJson()))
|
||||||
req, err = http.NewRequest(c.Request.Method, BaseURL, bytes.NewReader(chatReq.ToByteJson()))
|
}
|
||||||
|
if onekey.EndPoint != "" { // 优先key的endpoint
|
||||||
|
req, err = http.NewRequest(c.Request.Method, onekey.EndPoint+c.Request.RequestURI, bytes.NewReader(chatReq.ToByteJson()))
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header = c.Request.Header
|
req.Header = c.Request.Header
|
||||||
|
|||||||
@@ -183,6 +183,8 @@ func Cost(model string, promptCount, completionCount int) float64 {
|
|||||||
cost = (0.00035/1000)*float64(prompt) + (0.00053/1000)*float64(completion)
|
cost = (0.00035/1000)*float64(prompt) + (0.00053/1000)*float64(completion)
|
||||||
case "gemini-2.0-flash-exp":
|
case "gemini-2.0-flash-exp":
|
||||||
cost = (0.00035/1000)*float64(prompt) + (0.00053/1000)*float64(completion)
|
cost = (0.00035/1000)*float64(prompt) + (0.00053/1000)*float64(completion)
|
||||||
|
case "gemini-2.0-flash-thinking-exp-1219":
|
||||||
|
cost = (0.00035/1000)*float64(prompt) + (0.00053/1000)*float64(completion)
|
||||||
case "learnlm-1.5-pro-experimental", " gemini-exp-1114", "gemini-exp-1121", "gemini-exp-1206":
|
case "learnlm-1.5-pro-experimental", " gemini-exp-1114", "gemini-exp-1121", "gemini-exp-1206":
|
||||||
cost = (0.00035/1000)*float64(prompt) + (0.00053/1000)*float64(completion)
|
cost = (0.00035/1000)*float64(prompt) + (0.00053/1000)*float64(completion)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ func ChatHandler(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(chatreq.Model, "gpt") || strings.HasPrefix(chatreq.Model, "o1-") {
|
if strings.Contains(chatreq.Model, "gpt") || strings.HasPrefix(chatreq.Model, "o1-") {
|
||||||
openai.ChatProxy(c, &chatreq)
|
openai.ChatProxy(c, &chatreq)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,22 +2,18 @@ package router
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
"opencatd-open/pkg/claude"
|
"opencatd-open/pkg/claude"
|
||||||
oai "opencatd-open/pkg/openai"
|
oai "opencatd-open/pkg/openai"
|
||||||
"opencatd-open/store"
|
"opencatd-open/store"
|
||||||
"os"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
baseUrl = "https://api.openai.com"
|
|
||||||
GPT3Dot5Turbo = "gpt-3.5-turbo"
|
GPT3Dot5Turbo = "gpt-3.5-turbo"
|
||||||
GPT4 = "gpt-4"
|
GPT4 = "gpt-4"
|
||||||
)
|
)
|
||||||
@@ -62,13 +58,6 @@ var (
|
|||||||
// } `json:"usage"`
|
// } `json:"usage"`
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func init() {
|
|
||||||
if openai_endpoint := os.Getenv("openai_endpoint"); openai_endpoint != "" {
|
|
||||||
log.Println(fmt.Sprintf("replace %s to %s", baseUrl, openai_endpoint))
|
|
||||||
baseUrl = openai_endpoint
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func HandleProxy(c *gin.Context) {
|
func HandleProxy(c *gin.Context) {
|
||||||
var (
|
var (
|
||||||
localuser bool
|
localuser bool
|
||||||
|
|||||||
+5
-1
@@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -76,6 +77,9 @@ func SelectKeyCache(apitype string) (Key, error) {
|
|||||||
|
|
||||||
func SelectKeyCacheByModel(model string) (Key, error) {
|
func SelectKeyCacheByModel(model string) (Key, error) {
|
||||||
var keys []Key
|
var keys []Key
|
||||||
|
if os.Getenv("OPENAI_API_KEY") != "" {
|
||||||
|
keys = append(keys, Key{ApiType: "openai", Key: os.Getenv("OPENAI_API_KEY")})
|
||||||
|
}
|
||||||
items := KeysCache.Items()
|
items := KeysCache.Items()
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
if strings.Contains(model, "realtime") {
|
if strings.Contains(model, "realtime") {
|
||||||
@@ -97,7 +101,7 @@ func SelectKeyCacheByModel(model string) (Key, error) {
|
|||||||
keys = append(keys, item.Object.(Key))
|
keys = append(keys, item.Object.(Key))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(model, "o1-") || model == "chatgpt-4o-latest" {
|
if strings.HasPrefix(model, "o1-") || strings.HasPrefix(model, "chatgpt-") {
|
||||||
if item.Object.(Key).ApiType == "openai" {
|
if item.Object.(Key).ApiType == "openai" {
|
||||||
keys = append(keys, item.Object.(Key))
|
keys = append(keys, item.Object.(Key))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user