Spaces:
Paused
Paused
add deepseek direct via userToken
Browse files- internal/handler/chat.go +6 -0
- internal/handler/deepseek.go +58 -0
- internal/model/mapping.go +8 -0
internal/handler/chat.go
CHANGED
|
@@ -49,6 +49,12 @@ func HandleChatCompletions(w http.ResponseWriter, r *http.Request) {
|
|
| 49 |
r.Body = io.NopCloser(bytes.NewReader(body))
|
| 50 |
var tempReq map[string]interface{}
|
| 51 |
json.Unmarshal(body, &tempReq)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
if m, ok := tempReq["model"].(string); ok && IsOpenRouterModel(m) {
|
| 53 |
ok2, reason := CheckAndTrack(apiKey, 0)
|
| 54 |
if !ok2 { http.Error(w, reason, 429); return }
|
|
|
|
| 49 |
r.Body = io.NopCloser(bytes.NewReader(body))
|
| 50 |
var tempReq map[string]interface{}
|
| 51 |
json.Unmarshal(body, &tempReq)
|
| 52 |
+
if m, ok := tempReq["model"].(string); ok && IsDeepSeekModel(m) {
|
| 53 |
+
ok2, reason := CheckAndTrack(apiKey, 0)
|
| 54 |
+
if !ok2 { http.Error(w, reason, 429); return }
|
| 55 |
+
HandleDeepSeek(w, r, body, apiKey)
|
| 56 |
+
return
|
| 57 |
+
}
|
| 58 |
if m, ok := tempReq["model"].(string); ok && IsOpenRouterModel(m) {
|
| 59 |
ok2, reason := CheckAndTrack(apiKey, 0)
|
| 60 |
if !ok2 { http.Error(w, reason, 429); return }
|
internal/handler/deepseek.go
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package handler
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"bytes"
|
| 5 |
+
"encoding/json"
|
| 6 |
+
"io"
|
| 7 |
+
"net/http"
|
| 8 |
+
"os"
|
| 9 |
+
"strings"
|
| 10 |
+
)
|
| 11 |
+
|
| 12 |
+
var deepseekToken = os.Getenv("DEEPSEEK_TOKEN")
|
| 13 |
+
|
| 14 |
+
var deepseekModels = map[string]bool{
|
| 15 |
+
"deepseek": true,
|
| 16 |
+
"deepseek-expert": true,
|
| 17 |
+
"deepseek-r1": true,
|
| 18 |
+
"deepseek-search": true,
|
| 19 |
+
"deepseek-expert-r1": true,
|
| 20 |
+
"deepseek-expert-search": true,
|
| 21 |
+
"deepseek-r1-search": true,
|
| 22 |
+
"deepseek-expert-r1-search": true,
|
| 23 |
+
"deepseek-v4": true,
|
| 24 |
+
"deepseek-v4-flash": true,
|
| 25 |
+
"deepseek-v4-pro": true,
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
func IsDeepSeekModel(model string) bool {
|
| 29 |
+
_, ok := deepseekModels[strings.ToLower(model)]
|
| 30 |
+
return ok
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
func HandleDeepSeek(w http.ResponseWriter, r *http.Request, body []byte, apiKey string) {
|
| 34 |
+
var req map[string]interface{}
|
| 35 |
+
json.Unmarshal(body, &req)
|
| 36 |
+
newBody, _ := json.Marshal(req)
|
| 37 |
+
proxyReq, _ := http.NewRequest("POST", "https://chat.deepseek.com/api/v0/chat/completions", bytes.NewReader(newBody))
|
| 38 |
+
proxyReq.Header.Set("Authorization", "Bearer "+deepseekToken)
|
| 39 |
+
proxyReq.Header.Set("Content-Type", "application/json")
|
| 40 |
+
proxyReq.Header.Set("User-Agent", "Mozilla/5.0")
|
| 41 |
+
proxyReq.Header.Set("Referer", "https://chat.deepseek.com/")
|
| 42 |
+
client := &http.Client{}
|
| 43 |
+
resp, err := client.Do(proxyReq)
|
| 44 |
+
if err != nil { http.Error(w, "DeepSeek error", 500); return }
|
| 45 |
+
defer resp.Body.Close()
|
| 46 |
+
respBody, _ := io.ReadAll(resp.Body)
|
| 47 |
+
w.Header().Set("Content-Type", "application/json")
|
| 48 |
+
w.WriteHeader(resp.StatusCode)
|
| 49 |
+
w.Write(respBody)
|
| 50 |
+
var result map[string]interface{}
|
| 51 |
+
if json.Unmarshal(respBody, &result) == nil {
|
| 52 |
+
if usage, ok := result["usage"].(map[string]interface{}); ok {
|
| 53 |
+
if total, ok := usage["total_tokens"].(float64); ok {
|
| 54 |
+
TrackUsage(apiKey, int(total))
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
}
|
| 58 |
+
}
|
internal/model/mapping.go
CHANGED
|
@@ -48,6 +48,14 @@ func ResolveClaudeModel(model string, thinkingEnabled bool) (resolvedModel strin
|
|
| 48 |
|
| 49 |
// v1/models 返回的模型列表(全部小写)
|
| 50 |
var ModelList = []string{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
// DEEPSEEK via OpenRouter
|
| 52 |
"deepseek-r1",
|
| 53 |
"deepseek-v3",
|
|
|
|
| 48 |
|
| 49 |
// v1/models 返回的模型列表(全部小写)
|
| 50 |
var ModelList = []string{
|
| 51 |
+
// DEEPSEEK directo
|
| 52 |
+
"deepseek",
|
| 53 |
+
"deepseek-expert",
|
| 54 |
+
"deepseek-r1",
|
| 55 |
+
"deepseek-search",
|
| 56 |
+
"deepseek-expert-r1",
|
| 57 |
+
"deepseek-v4",
|
| 58 |
+
"deepseek-v4-pro",
|
| 59 |
// DEEPSEEK via OpenRouter
|
| 60 |
"deepseek-r1",
|
| 61 |
"deepseek-v3",
|