refactor backend API structure

This commit is contained in:
CJACK
2026-04-26 06:58:20 +08:00
parent 8a91fef6ab
commit abc96a37d8
207 changed files with 2675 additions and 1344 deletions

View File

@@ -1,87 +0,0 @@
package util
import "ds2api/internal/config"
type StandardRequest struct {
Surface string
RequestedModel string
ResolvedModel string
ResponseModel string
Messages []any
HistoryText string
ToolsRaw any
FinalPrompt string
ToolNames []string
ToolChoice ToolChoicePolicy
Stream bool
Thinking bool
Search bool
RefFileIDs []string
PassThrough map[string]any
}
type ToolChoiceMode string
const (
ToolChoiceAuto ToolChoiceMode = "auto"
ToolChoiceNone ToolChoiceMode = "none"
ToolChoiceRequired ToolChoiceMode = "required"
ToolChoiceForced ToolChoiceMode = "forced"
)
type ToolChoicePolicy struct {
Mode ToolChoiceMode
ForcedName string
Allowed map[string]struct{}
}
func DefaultToolChoicePolicy() ToolChoicePolicy {
return ToolChoicePolicy{Mode: ToolChoiceAuto}
}
func (p ToolChoicePolicy) IsNone() bool {
return p.Mode == ToolChoiceNone
}
func (p ToolChoicePolicy) IsRequired() bool {
return p.Mode == ToolChoiceRequired || p.Mode == ToolChoiceForced
}
func (p ToolChoicePolicy) Allows(name string) bool {
if len(p.Allowed) == 0 {
return true
}
_, ok := p.Allowed[name]
return ok
}
func (r StandardRequest) CompletionPayload(sessionID string) map[string]any {
modelID := r.ResolvedModel
if modelID == "" {
modelID = r.RequestedModel
}
modelType := "default"
if resolvedType, ok := config.GetModelType(modelID); ok {
modelType = resolvedType
}
refFileIDs := make([]any, 0, len(r.RefFileIDs))
for _, fileID := range r.RefFileIDs {
if fileID == "" {
continue
}
refFileIDs = append(refFileIDs, fileID)
}
payload := map[string]any{
"chat_session_id": sessionID,
"model_type": modelType,
"parent_message_id": nil,
"prompt": r.FinalPrompt,
"ref_file_ids": refFileIDs,
"thinking_enabled": r.Thinking,
"search_enabled": r.Search,
}
for k, v := range r.PassThrough {
payload[k] = v
}
return payload
}

View File

@@ -1,57 +0,0 @@
package util
import "testing"
func TestStandardRequestCompletionPayloadSetsModelTypeFromResolvedModel(t *testing.T) {
tests := []struct {
name string
model string
thinking bool
search bool
modelType string
}{
{name: "default", model: "deepseek-v4-flash", thinking: false, search: false, modelType: "default"},
{name: "expert", model: "deepseek-v4-pro", thinking: true, search: false, modelType: "expert"},
{name: "vision", model: "deepseek-v4-vision-search", thinking: false, search: true, modelType: "vision"},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
req := StandardRequest{
ResolvedModel: tc.model,
FinalPrompt: "hello",
Thinking: tc.thinking,
Search: tc.search,
RefFileIDs: []string{"file-a", "file-b"},
PassThrough: map[string]any{
"temperature": 0.3,
},
}
payload := req.CompletionPayload("session-123")
if got := payload["model_type"]; got != tc.modelType {
t.Fatalf("expected model_type %s, got %#v", tc.modelType, got)
}
if got := payload["chat_session_id"]; got != "session-123" {
t.Fatalf("unexpected chat_session_id: %#v", got)
}
if got := payload["thinking_enabled"]; got != tc.thinking {
t.Fatalf("unexpected thinking_enabled: %#v", got)
}
if got := payload["search_enabled"]; got != tc.search {
t.Fatalf("unexpected search_enabled: %#v", got)
}
if got := payload["temperature"]; got != 0.3 {
t.Fatalf("expected passthrough temperature, got %#v", got)
}
refFileIDs, ok := payload["ref_file_ids"].([]any)
if !ok {
t.Fatalf("expected ref_file_ids slice, got %#v", payload["ref_file_ids"])
}
if len(refFileIDs) != 2 || refFileIDs[0] != "file-a" || refFileIDs[1] != "file-b" {
t.Fatalf("unexpected ref_file_ids: %#v", refFileIDs)
}
})
}
}