diff --git a/server/cmd/api/main.go b/server/cmd/api/main.go index 0557a33..51fb0bc 100644 --- a/server/cmd/api/main.go +++ b/server/cmd/api/main.go @@ -170,11 +170,11 @@ func main() { modelGroup := r.Group("/model") { modelGroup.GET("/list", modelHandler.List) - modelGroup.GET("/:id", modelHandler.GetByID) + modelGroup.POST("/test", modelHandler.Test) modelGroup.POST("/add", modelHandler.Create) + modelGroup.GET("/:id", modelHandler.GetByID) modelGroup.PUT("/:id", modelHandler.Update) modelGroup.DELETE("/:id", modelHandler.Delete) - modelGroup.POST("/test", modelHandler.Test) } // 系统信息模块 diff --git a/server/internal/model/model_info.go b/server/internal/model/model_info.go index 2845b65..38da606 100644 --- a/server/internal/model/model_info.go +++ b/server/internal/model/model_info.go @@ -39,6 +39,7 @@ type CreateModelRequest struct { APIKey string `json:"api_key" binding:"required"` BaseURL string `json:"base_url" binding:"required"` APIEndpoint string `json:"api_endpoint"` + Status string `json:"status"` } // UpdateModelRequest 更新模型请求 diff --git a/server/internal/service/model_service.go b/server/internal/service/model_service.go index e1634fd..7410caf 100644 --- a/server/internal/service/model_service.go +++ b/server/internal/service/model_service.go @@ -5,7 +5,10 @@ import ( "encoding/json" "fmt" "io" + "log" "net/http" + "strings" + "time" "x-agents/server/internal/model" "x-agents/server/internal/repository" @@ -33,6 +36,12 @@ func (s *ModelService) GetByID(id string) (*model.ModelInfo, error) { // Create 创建模型 func (s *ModelService) Create(req model.CreateModelRequest) (*model.ModelInfo, error) { + // 如果没有提供状态,默认设置为 inactive + status := req.Status + if status == "" { + status = "inactive" + } + info := &model.ModelInfo{ ID: uuid.New().String(), Name: req.Name, @@ -42,7 +51,7 @@ func (s *ModelService) Create(req model.CreateModelRequest) (*model.ModelInfo, e APIKey: req.APIKey, BaseURL: req.BaseURL, APIEndpoint: req.APIEndpoint, - Status: "active", + Status: status, } if err := s.repo.Create(info); err != nil { @@ -105,20 +114,36 @@ func (s *ModelService) Delete(id string) error { // TestConnection 测试模型连接 func (s *ModelService) TestConnection(req model.TestModelRequest) (*model.TestModelResponse, error) { + log.Printf("[TestConnection] 开始测试连接: provider=%s, model=%s, base_url=%s, api_endpoint=%s", req.Provider, req.Model, req.BaseURL, req.APIEndpoint) + // 构建请求 URL baseURL := req.BaseURL + // 去掉 base_url 末尾的斜杠 + baseURL = strings.TrimRight(baseURL, "/") + if req.APIEndpoint != "" { - baseURL = baseURL + req.APIEndpoint + // 去掉 api_endpoint 开头的斜杠 + apiEndpoint := strings.TrimLeft(req.APIEndpoint, "/") + baseURL = baseURL + "/" + apiEndpoint } else { - // 默认端点 + // 默认端点 - 根据不同 provider 设置 switch req.Provider { case "OpenAI": baseURL = baseURL + "/v1/chat/completions" case "Ollama": baseURL = baseURL + "/api/chat" + case "ali", "Ali", "aliyun", "Aliyun": + // 阿里云 DashScope 兼容 OpenAI 格式,需要添加 /chat/completions + // base_url 格式: https://dashscope.aliyuncs.com/compatible-mode/v1 + baseURL = baseURL + "/chat/completions" + default: + // 默认使用 OpenAI 兼容格式 + baseURL = baseURL + "/v1/chat/completions" } } + log.Printf("[TestConnection] 请求 URL: %s", baseURL) + // 构建请求体 requestBody := map[string]interface{}{ "model": req.Model, @@ -141,11 +166,19 @@ func (s *ModelService) TestConnection(req model.TestModelRequest) (*model.TestMo httpReq.Header.Set("Content-Type", "application/json") if req.APIKey != "" { - httpReq.Header.Set("Authorization", "Bearer "+req.APIKey) + // 根据不同 provider 使用不同的认证方式 + switch req.Provider { + case "ali", "Ali", "aliyun", "Aliyun": + // 阿里云使用 x-api-key 头部 + httpReq.Header.Set("Authorization", "Bearer "+req.APIKey) + httpReq.Header.Set("x-api-key", req.APIKey) + default: + httpReq.Header.Set("Authorization", "Bearer "+req.APIKey) + } } - // 发送请求 - client := &http.Client{} + // 发送请求,设置 10 秒超时 + client := &http.Client{Timeout: 10 * time.Second} resp, err := client.Do(httpReq) if err != nil { return &model.TestModelResponse{Success: false, Message: err.Error()}, nil @@ -158,6 +191,8 @@ func (s *ModelService) TestConnection(req model.TestModelRequest) (*model.TestMo return &model.TestModelResponse{Success: false, Message: err.Error()}, nil } + log.Printf("[TestConnection] 响应状态码: %d, 响应体: %s", resp.StatusCode, string(respBody)) + if resp.StatusCode >= 200 && resp.StatusCode < 300 { return &model.TestModelResponse{Success: true, Message: "Connection successful"}, nil }