mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-10 19:27:41 +08:00
Add default, expert, and vision DeepSeek model families
This commit is contained in:
@@ -15,8 +15,17 @@ import (
|
||||
"ds2api/internal/config"
|
||||
"ds2api/internal/deepseek"
|
||||
"ds2api/internal/sse"
|
||||
"ds2api/internal/util"
|
||||
)
|
||||
|
||||
type modelAliasSnapshotReader struct {
|
||||
aliases map[string]string
|
||||
}
|
||||
|
||||
func (m modelAliasSnapshotReader) ModelAliases() map[string]string {
|
||||
return m.aliases
|
||||
}
|
||||
|
||||
func (h *Handler) testSingleAccount(w http.ResponseWriter, r *http.Request) {
|
||||
var req map[string]any
|
||||
_ = json.NewDecoder(r.Body).Decode(&req)
|
||||
@@ -150,16 +159,27 @@ func (h *Handler) testAccount(ctx context.Context, acc config.Account, model, me
|
||||
return result
|
||||
}
|
||||
thinking, search, ok := config.GetModelConfig(model)
|
||||
resolvedModel, resolved := config.ResolveModel(modelAliasSnapshotReader{
|
||||
aliases: h.Store.Snapshot().ModelAliases,
|
||||
}, model)
|
||||
if resolved {
|
||||
model = resolvedModel
|
||||
thinking, search, ok = config.GetModelConfig(model)
|
||||
}
|
||||
if !ok {
|
||||
thinking, search = false, false
|
||||
}
|
||||
_ = search
|
||||
pow, err := h.DS.GetPow(proxyCtx, authCtx, 1)
|
||||
if err != nil {
|
||||
result["message"] = "获取 PoW 失败: " + err.Error()
|
||||
return result
|
||||
}
|
||||
payload := map[string]any{"chat_session_id": sessionID, "prompt": deepseek.MessagesPrepare([]map[string]any{{"role": "user", "content": message}}), "ref_file_ids": []any{}, "thinking_enabled": thinking, "search_enabled": search}
|
||||
payload := util.StandardRequest{
|
||||
ResolvedModel: model,
|
||||
FinalPrompt: deepseek.MessagesPrepare([]map[string]any{{"role": "user", "content": message}}),
|
||||
Thinking: thinking,
|
||||
Search: search,
|
||||
}.CompletionPayload(sessionID)
|
||||
resp, err := h.DS.CallCompletion(proxyCtx, authCtx, payload, pow, 1)
|
||||
if err != nil {
|
||||
result["message"] = "请求失败: " + err.Error()
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
@@ -133,3 +134,78 @@ func TestDeleteAllSessions_RetryWithReloginOnDeleteFailure(t *testing.T) {
|
||||
t.Fatalf("expected refreshed token persisted, got %q", updated.Token)
|
||||
}
|
||||
}
|
||||
|
||||
type completionPayloadDSMock struct {
|
||||
payload map[string]any
|
||||
}
|
||||
|
||||
func (m *completionPayloadDSMock) Login(_ context.Context, _ config.Account) (string, error) {
|
||||
return "new-token", nil
|
||||
}
|
||||
|
||||
func (m *completionPayloadDSMock) CreateSession(_ context.Context, _ *auth.RequestAuth, _ int) (string, error) {
|
||||
return "session-id", nil
|
||||
}
|
||||
|
||||
func (m *completionPayloadDSMock) GetPow(_ context.Context, _ *auth.RequestAuth, _ int) (string, error) {
|
||||
return "pow-ok", nil
|
||||
}
|
||||
|
||||
func (m *completionPayloadDSMock) CallCompletion(_ context.Context, _ *auth.RequestAuth, payload map[string]any, _ string, _ int) (*http.Response, error) {
|
||||
m.payload = payload
|
||||
return &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: io.NopCloser(strings.NewReader("data: {\"v\":\"ok\"}\n\ndata: [DONE]\n\n")),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *completionPayloadDSMock) DeleteAllSessionsForToken(_ context.Context, _ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *completionPayloadDSMock) GetSessionCountForToken(_ context.Context, _ string) (*deepseek.SessionStats, error) {
|
||||
return &deepseek.SessionStats{Success: true}, nil
|
||||
}
|
||||
|
||||
func TestTestAccount_MessageModeUsesExpertModelTypeForExpertModel(t *testing.T) {
|
||||
t.Setenv("DS2API_CONFIG_JSON", `{"accounts":[{"email":"batch@example.com","password":"pwd","token":"seed-token"}]}`)
|
||||
store := config.LoadStore()
|
||||
ds := &completionPayloadDSMock{}
|
||||
h := &Handler{Store: store, DS: ds}
|
||||
acc, ok := store.FindAccount("batch@example.com")
|
||||
if !ok {
|
||||
t.Fatal("expected test account")
|
||||
}
|
||||
|
||||
result := h.testAccount(context.Background(), acc, "deepseek-expert-chat", "hello")
|
||||
|
||||
if ok, _ := result["success"].(bool); !ok {
|
||||
t.Fatalf("expected success=true, got %#v", result)
|
||||
}
|
||||
if got := ds.payload["model_type"]; got != "expert" {
|
||||
t.Fatalf("expected model_type expert, got %#v", got)
|
||||
}
|
||||
if got := ds.payload["chat_session_id"]; got != "session-id" {
|
||||
t.Fatalf("unexpected chat_session_id: %#v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTestAccount_MessageModeUsesVisionModelTypeForVisionModel(t *testing.T) {
|
||||
t.Setenv("DS2API_CONFIG_JSON", `{"accounts":[{"email":"batch@example.com","password":"pwd","token":"seed-token"}]}`)
|
||||
store := config.LoadStore()
|
||||
ds := &completionPayloadDSMock{}
|
||||
h := &Handler{Store: store, DS: ds}
|
||||
acc, ok := store.FindAccount("batch@example.com")
|
||||
if !ok {
|
||||
t.Fatal("expected test account")
|
||||
}
|
||||
|
||||
result := h.testAccount(context.Background(), acc, "deepseek-vision-chat", "hello")
|
||||
|
||||
if ok, _ := result["success"].(bool); !ok {
|
||||
t.Fatalf("expected success=true, got %#v", result)
|
||||
}
|
||||
if got := ds.payload["model_type"]; got != "vision" {
|
||||
t.Fatalf("expected model_type vision, got %#v", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user