Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/cheel98_aichat.json
T

1 line
56 KiB
JSON

{"repo": "cheel98/aichat", "files": {"backend/services/ai_service.go": {"6c49a3d14913d217c7cf28251bf4c0c28d17899d": {"t": 1785746102.8395522, "n": 8371, "h": "8135cf97905c9819", "c": "package services\n\nimport (\n\t\"aiChat/backend/config\"\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n)\n\n// DeepSeekConfig 保存DeepSeek API的配置信息\ntype DeepSeekConfig struct {\n\tAPIKey string\n\tBaseURL string\n\tModel string\n\tReasonerModel string\n}\n\n// DeepSeekService 处理与DeepSeek API的交互\ntype DeepSeekService struct {\n\tConfig DeepSeekConfig\n}\n\n// 创建默认DeepSeek服务实例\nvar defaultDeepSeekService = NewDeepSeekService(DeepSeekConfig{\n\tBaseURL: \"https://api.deepseek.com/chat/completions\",\n\tModel: \"deepseek-chat\", // 默认使用v3模型\n\tReasonerModel: \"deepseek-reasoner\", // 用于思考模式的模型\n})\n\n// NewDeepSeekService 创建一个新的DeepSeekService实例\nfunc NewDeepSeekService(config DeepSeekConfig) *DeepSeekService {\n\treturn &DeepSeekService{\n\t\tConfig: config,\n\t}\n}\n\n// GetDefaultDeepSeekService 获取默认DeepSeek服务实例\nfunc GetDefaultDeepSeekService() *DeepSeekService {\n\treturn defaultDeepSeekService\n}\n\n// SetAPIKey 设置API密钥\nfunc (s *DeepSeekService) SetAPIKey(apiKey string) {\n\ts.Config.APIKey = apiKey\n}\n\n// SetModel 设置要使用的模型\nfunc (s *DeepSeekService) SetModel(model string) {\n\ts.Config.Model = model\n}\n\n// SetReasonerModel 设置要使用的思考模型\nfunc (s *DeepSeekService) SetReasonerModel(model string) {\n\ts.Config.ReasonerModel = model\n}\n\n// ChatRequest DeepSeek API聊天请求\ntype ChatRequest struct {\n\tModel string `json:\"model\"`\n\tMessages []ChatMessage `json:\"messages\"`\n\tTemperature float64 `json:\"temperature,omitempty\"`\n\tMaxTokens int `json:\"max_tokens,omitempty\"`\n\tStream bool `json:\"stream\"`\n}\n\n// ChatMessage 聊天消息\ntype ChatMessage struct {\n\tRole string `json:\"role\"`\n\tContent string `json:\"content\"`\n}\n\n// ChatResponse DeepSeek API聊天响应\ntype ChatResponse struct {\n\tID string `json:\"id\"`\n\tObject string `json:\"object\"`\n\tCreated int64 `json:\"created\"`\n\tModel string `json:\"model\"`\n\tChoices []struct {\n\t\tMessage ChatMessage `json:\"message\"`\n\t\tFinishReason string `json:\"finish_reason\"`\n\t} `json:\"choices\"`\n\tUsage struct {\n\t\tPromptTokens int `json:\"prompt_tokens\"`\n\t\tCompletionTokens int `json:\"completion_tokens\"`\n\t\tTotalTokens int `json:\"total_tokens\"`\n\t} `json:\"usage\"`\n}\n\n// StreamChatResponse 流式获取聊天回复,同时返回完整的响应文本\nfunc (s *DeepSeekService) StreamChatResponse(userMessage string, writer io.Writer, deepThinking bool) (string, string, error) {\n\tif s.Config.APIKey == \"\" {\n\t\tresponse := \"未配置API密钥,无法连接DeepSeek服务\"\n\t\twriter.Write([]byte(response))\n\t\treturn response, \"\", nil\n\t}\n\n\t// 根据deepThinking标志选择使用的模型\n\tmodelToUse := s.Config.Model\n\tif deepThinking && s.Config.ReasonerModel != \"\" {\n\t\tmodelToUse = s.Config.ReasonerModel\n\t}\n\n\t// 构建请求体\n\trequestBody := ChatRequest{\n\t\tModel: modelToUse,\n\t\tMessages: []ChatMessage{\n\t\t\t{\n\t\t\t\tRole: \"user\",\n\t\t\t\tContent: userMessage,\n\t\t\t},\n\t\t},\n\t\tTemperature: 0.7,\n\t\tMaxTokens: int(config.AppConfig.DeepSeek.MaxTokens),\n\t\tStream: true, // 启用流式响应\n\t}\n\n\t// 转换为JSON\n\tjsonData, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"序列化请求失败: %v\", err)\n\t}\n\n\t// 创建HTTP请求\n\turl := fmt.Sprintf(\"%s\", s.Config.BaseURL)\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"创建HTTP请求失败: %v\", err)\n\t}\n\n\t// 设置请求头\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+s.Config.APIKey)\n\treq.Header.Set(\"Accept\", \"text/event-stream\")\n\n\t// 发送请求\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"发送请求失败: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 检查HTTP状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\tbody, _ := ioutil.ReadAll(resp.Body)\n\t\treturn \"\", \"\", fmt.Errorf(\"API请求失败,状态码: %d, 响应: %s\", resp.StatusCode, string(body))\n\t}\n\n\t// 读取响应流\n\treader := bufio.NewReader(resp.Body)\n\n\t// 用于收集完整回复\n\tvar fullResponse strings.Builder\n\tvar fullThinkingResponse strings.Builder\n\n\t// 如果DeepSeek API不支持流式输出或出现问题,我们实现一个模拟的流式响应\n\t// 这里通过简单地逐字符输出来模拟流式效果\n\tif !strings.Contains(resp.Header.Get(\"Content-Type\"), \"text/event-stream\") {\n\t\t// 读取整个响应\n\t\tbody, err := ioutil.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\treturn \"\", \"\", fmt.Errorf(\"读取响应失败: %v\", err)\n\t\t}\n\n\t\tvar response ChatResponse\n\t\tif err := json.Unmarshal(body, &response); err != nil {\n\t\t\treturn \"\", \"\", fmt.Errorf(\"解析响应失败: %v\", err)\n\t\t}\n\n\t\tif len(response.Choices) == 0 {\n\t\t\treturn \"\", \"\", fmt.Errorf(\"没有收到有效回复\")\n\t\t}\n\n\t\t// 获取完整回复\n\t\tfullReply := response.Choices[0].Message.Content\n\n\t\t// 模拟流式输出,每次发送一个字符\n\t\tfor _, char := range fullReply {\n\t\t\t_, err := writer.Write([]byte(string(char)))\n\t\t\tif err != nil {\n\t\t\t\treturn fullResponse.String(), \"\", fmt.Errorf(\"写入响应失败: %v\", err)\n\t\t\t}\n\t\t\t// 小延迟,模拟打字效果\n\t\t\ttime.Sleep(10 * time.Millisecond)\n\t\t\tfullResponse.WriteRune(char)\n\t\t}\n\t\treturn fullResponse.String(), fullThinkingResponse.String(), nil\n\t}\n\tthinking := false\n\t// 处理真正的SSE流\n\tfor {\n\t\tline, err := reader.ReadString('\\n')\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn fullResponse.String(), fullThinkingResponse.String(), fmt.Errorf(\"读取流失败: %v\", err)\n\t\t}\n\n\t\t// 跳过空行\n\t\tline = strings.TrimSpace(line)\n\t\tif line == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\t// 处理SSE格式数据\n\t\tif strings.HasPrefix(line, \"data: \") {\n\t\t\tdata := strings.TrimPrefix(line, \"data: \")\n\n\t\t\t// 检查流是否结束\n\t\t\tif data == \"[DONE]\" {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// 解析JSON\n\t\t\tvar streamResponse struct {\n\t\t\t\tChoices []struct {\n\t\t\t\t\tDelta struct {\n\t\t\t\t\t\tContent string `json:\"content\"`\n\t\t\t\t\t\tReasoningContent string `json:\"reasoning_content\"`\n\t\t\t\t\t} `json:\"delta\"`\n\t\t\t\t\tFinishReason *string `json:\"finish_reason\"`\n\t\t\t\t} `json:\"choices\"`\n\t\t\t}\n\n\t\t\tif err := json.Unmarshal([]byte(data), &streamResponse); err != nil {\n\t\t\t\tcontinue // 忽略解析错误,继续处理\n\t\t\t}\n\t\t\t// 检查是否有内容需要写入\n\t\t\tif len(streamResponse.Choices) > 0 {\n\t\t\t\treasoning_content := streamResponse.Choices[0].Delta.ReasoningContent\n\t\t\t\tif reasoning_content != \"\" {\n\t\t\t\t\tthinking = true\n\t\t\t\t\t_, err := writer.Write([]byte(reasoning_content))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn fullResponse.String(), fullThinkingResponse.String(), fmt.Errorf(\"写入响应失败: %v\", err)\n\t\t\t\t\t}\n\t\t\t\t\t// 收集完整回复\n\t\t\t\t\tfullThinkingResponse.WriteString(reasoning_content)\n\t\t\t\t} else {\n\t\t\t\t\tcontent := streamResponse.Choices[0].Delta.Content\n\t\t\t\t\tif content != \"\" {\n\t\t\t\t\t\tif thinking {\n\t\t\t\t\t\t\twriter.Write([]byte(\"$thinkEnd$\"))\n\t\t\t\t\t\t\tthinking = false\n\t\t\t\t\t\t}\n\t\t\t\t\t\t_, err := writer.Write([]byte(content))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn fullResponse.String(), fullThinkingResponse.String(), fmt.Errorf(\"写入响应失败: %v\", err)\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// 收集完整回复\n\t\t\t\t\t\tfullResponse.WriteString(content)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// 检查是否完成\n\t\t\t\tif streamResponse.Choices[0].FinishReason != nil {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fullResponse.String(), fullThinkingResponse.String(), nil\n}\n\n// GetChatResponse 获取聊天回复\nfunc (s *DeepSeekService) GetChatResponse(userMessage string, deepThinking bool) (string, error) {\n\tif s.Config.APIKey == \"\" {\n\t\treturn \"未配置API密钥,无法连接DeepSeek服务\", nil\n\t}\n\n\t// 根据deepThinking标志选择使用的模型\n\tmodelToUse := s.Config.Model\n\tif deepThinking && s.Config.ReasonerModel != \"\" {\n\t\tmodelToUse = s.Config.ReasonerModel\n\t}\n\n\t// 构建请求体\n\trequestBody := ChatRequest{\n\t\tModel: modelToUse,\n\t\tMessages: []ChatMessage{\n\t\t\t{\n\t\t\t\tRole: \"user\",\n\t\t\t\tContent: userMessage,\n\t\t\t},\n\t\t},\n\t\tTemperature: 0.7,\n\t\tMaxTokens: 2000,\n\t}\n\n\t// 转换为JSON\n\tjsonData, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"序列化请求失败: %v\", err)\n\t}\n\n\t// 创建HTTP请求\n\turl := fmt.Sprintf(\"%s/chat/completions\", s.Config.BaseURL)\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"创建HTTP请求失败: %v\", err)\n\t}\n\n\t// 设置请求头\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+s.Config.APIKey)\n\n\t// 发送请求\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"发送请求失败: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 读取响应\n\tbody, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"读取响应失败: %v\", err)\n\t}\n\n\t// 检查HTTP状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"API请求失败,状态码: %d, 响应: %s\", resp.StatusCode, string(body))\n\t}\n\n\t// 解析响应\n\tvar response ChatResponse\n\tif err := json.Unmarshal(body, &response); err != nil {\n\t\treturn \"\", fmt.Errorf(\"解析响应失败: %v\", err)\n\t}\n\n\t// 检查是否有回复\n\tif len(response.Choices) == 0 {\n\t\treturn \"\", fmt.Errorf(\"没有收到有效回复\")\n\t}\n\n\t// 返回AI的回复\n\treturn response.Choices[0].Message.Content, nil\n}\n"}, "6be26160bd44a2ee028a4a82b8375d441daaa1cf": {"t": 1785759882.4024727, "n": 8371, "h": "8135cf97905c9819", "c": "package services\n\nimport (\n\t\"aiChat/backend/config\"\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n)\n\n// DeepSeekConfig 保存DeepSeek API的配置信息\ntype DeepSeekConfig struct {\n\tAPIKey string\n\tBaseURL string\n\tModel string\n\tReasonerModel string\n}\n\n// DeepSeekService 处理与DeepSeek API的交互\ntype DeepSeekService struct {\n\tConfig DeepSeekConfig\n}\n\n// 创建默认DeepSeek服务实例\nvar defaultDeepSeekService = NewDeepSeekService(DeepSeekConfig{\n\tBaseURL: \"https://api.deepseek.com/chat/completions\",\n\tModel: \"deepseek-chat\", // 默认使用v3模型\n\tReasonerModel: \"deepseek-reasoner\", // 用于思考模式的模型\n})\n\n// NewDeepSeekService 创建一个新的DeepSeekService实例\nfunc NewDeepSeekService(config DeepSeekConfig) *DeepSeekService {\n\treturn &DeepSeekService{\n\t\tConfig: config,\n\t}\n}\n\n// GetDefaultDeepSeekService 获取默认DeepSeek服务实例\nfunc GetDefaultDeepSeekService() *DeepSeekService {\n\treturn defaultDeepSeekService\n}\n\n// SetAPIKey 设置API密钥\nfunc (s *DeepSeekService) SetAPIKey(apiKey string) {\n\ts.Config.APIKey = apiKey\n}\n\n// SetModel 设置要使用的模型\nfunc (s *DeepSeekService) SetModel(model string) {\n\ts.Config.Model = model\n}\n\n// SetReasonerModel 设置要使用的思考模型\nfunc (s *DeepSeekService) SetReasonerModel(model string) {\n\ts.Config.ReasonerModel = model\n}\n\n// ChatRequest DeepSeek API聊天请求\ntype ChatRequest struct {\n\tModel string `json:\"model\"`\n\tMessages []ChatMessage `json:\"messages\"`\n\tTemperature float64 `json:\"temperature,omitempty\"`\n\tMaxTokens int `json:\"max_tokens,omitempty\"`\n\tStream bool `json:\"stream\"`\n}\n\n// ChatMessage 聊天消息\ntype ChatMessage struct {\n\tRole string `json:\"role\"`\n\tContent string `json:\"content\"`\n}\n\n// ChatResponse DeepSeek API聊天响应\ntype ChatResponse struct {\n\tID string `json:\"id\"`\n\tObject string `json:\"object\"`\n\tCreated int64 `json:\"created\"`\n\tModel string `json:\"model\"`\n\tChoices []struct {\n\t\tMessage ChatMessage `json:\"message\"`\n\t\tFinishReason string `json:\"finish_reason\"`\n\t} `json:\"choices\"`\n\tUsage struct {\n\t\tPromptTokens int `json:\"prompt_tokens\"`\n\t\tCompletionTokens int `json:\"completion_tokens\"`\n\t\tTotalTokens int `json:\"total_tokens\"`\n\t} `json:\"usage\"`\n}\n\n// StreamChatResponse 流式获取聊天回复,同时返回完整的响应文本\nfunc (s *DeepSeekService) StreamChatResponse(userMessage string, writer io.Writer, deepThinking bool) (string, string, error) {\n\tif s.Config.APIKey == \"\" {\n\t\tresponse := \"未配置API密钥,无法连接DeepSeek服务\"\n\t\twriter.Write([]byte(response))\n\t\treturn response, \"\", nil\n\t}\n\n\t// 根据deepThinking标志选择使用的模型\n\tmodelToUse := s.Config.Model\n\tif deepThinking && s.Config.ReasonerModel != \"\" {\n\t\tmodelToUse = s.Config.ReasonerModel\n\t}\n\n\t// 构建请求体\n\trequestBody := ChatRequest{\n\t\tModel: modelToUse,\n\t\tMessages: []ChatMessage{\n\t\t\t{\n\t\t\t\tRole: \"user\",\n\t\t\t\tContent: userMessage,\n\t\t\t},\n\t\t},\n\t\tTemperature: 0.7,\n\t\tMaxTokens: int(config.AppConfig.DeepSeek.MaxTokens),\n\t\tStream: true, // 启用流式响应\n\t}\n\n\t// 转换为JSON\n\tjsonData, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"序列化请求失败: %v\", err)\n\t}\n\n\t// 创建HTTP请求\n\turl := fmt.Sprintf(\"%s\", s.Config.BaseURL)\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"创建HTTP请求失败: %v\", err)\n\t}\n\n\t// 设置请求头\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+s.Config.APIKey)\n\treq.Header.Set(\"Accept\", \"text/event-stream\")\n\n\t// 发送请求\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"发送请求失败: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 检查HTTP状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\tbody, _ := ioutil.ReadAll(resp.Body)\n\t\treturn \"\", \"\", fmt.Errorf(\"API请求失败,状态码: %d, 响应: %s\", resp.StatusCode, string(body))\n\t}\n\n\t// 读取响应流\n\treader := bufio.NewReader(resp.Body)\n\n\t// 用于收集完整回复\n\tvar fullResponse strings.Builder\n\tvar fullThinkingResponse strings.Builder\n\n\t// 如果DeepSeek API不支持流式输出或出现问题,我们实现一个模拟的流式响应\n\t// 这里通过简单地逐字符输出来模拟流式效果\n\tif !strings.Contains(resp.Header.Get(\"Content-Type\"), \"text/event-stream\") {\n\t\t// 读取整个响应\n\t\tbody, err := ioutil.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\treturn \"\", \"\", fmt.Errorf(\"读取响应失败: %v\", err)\n\t\t}\n\n\t\tvar response ChatResponse\n\t\tif err := json.Unmarshal(body, &response); err != nil {\n\t\t\treturn \"\", \"\", fmt.Errorf(\"解析响应失败: %v\", err)\n\t\t}\n\n\t\tif len(response.Choices) == 0 {\n\t\t\treturn \"\", \"\", fmt.Errorf(\"没有收到有效回复\")\n\t\t}\n\n\t\t// 获取完整回复\n\t\tfullReply := response.Choices[0].Message.Content\n\n\t\t// 模拟流式输出,每次发送一个字符\n\t\tfor _, char := range fullReply {\n\t\t\t_, err := writer.Write([]byte(string(char)))\n\t\t\tif err != nil {\n\t\t\t\treturn fullResponse.String(), \"\", fmt.Errorf(\"写入响应失败: %v\", err)\n\t\t\t}\n\t\t\t// 小延迟,模拟打字效果\n\t\t\ttime.Sleep(10 * time.Millisecond)\n\t\t\tfullResponse.WriteRune(char)\n\t\t}\n\t\treturn fullResponse.String(), fullThinkingResponse.String(), nil\n\t}\n\tthinking := false\n\t// 处理真正的SSE流\n\tfor {\n\t\tline, err := reader.ReadString('\\n')\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn fullResponse.String(), fullThinkingResponse.String(), fmt.Errorf(\"读取流失败: %v\", err)\n\t\t}\n\n\t\t// 跳过空行\n\t\tline = strings.TrimSpace(line)\n\t\tif line == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\t// 处理SSE格式数据\n\t\tif strings.HasPrefix(line, \"data: \") {\n\t\t\tdata := strings.TrimPrefix(line, \"data: \")\n\n\t\t\t// 检查流是否结束\n\t\t\tif data == \"[DONE]\" {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// 解析JSON\n\t\t\tvar streamResponse struct {\n\t\t\t\tChoices []struct {\n\t\t\t\t\tDelta struct {\n\t\t\t\t\t\tContent string `json:\"content\"`\n\t\t\t\t\t\tReasoningContent string `json:\"reasoning_content\"`\n\t\t\t\t\t} `json:\"delta\"`\n\t\t\t\t\tFinishReason *string `json:\"finish_reason\"`\n\t\t\t\t} `json:\"choices\"`\n\t\t\t}\n\n\t\t\tif err := json.Unmarshal([]byte(data), &streamResponse); err != nil {\n\t\t\t\tcontinue // 忽略解析错误,继续处理\n\t\t\t}\n\t\t\t// 检查是否有内容需要写入\n\t\t\tif len(streamResponse.Choices) > 0 {\n\t\t\t\treasoning_content := streamResponse.Choices[0].Delta.ReasoningContent\n\t\t\t\tif reasoning_content != \"\" {\n\t\t\t\t\tthinking = true\n\t\t\t\t\t_, err := writer.Write([]byte(reasoning_content))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn fullResponse.String(), fullThinkingResponse.String(), fmt.Errorf(\"写入响应失败: %v\", err)\n\t\t\t\t\t}\n\t\t\t\t\t// 收集完整回复\n\t\t\t\t\tfullThinkingResponse.WriteString(reasoning_content)\n\t\t\t\t} else {\n\t\t\t\t\tcontent := streamResponse.Choices[0].Delta.Content\n\t\t\t\t\tif content != \"\" {\n\t\t\t\t\t\tif thinking {\n\t\t\t\t\t\t\twriter.Write([]byte(\"$thinkEnd$\"))\n\t\t\t\t\t\t\tthinking = false\n\t\t\t\t\t\t}\n\t\t\t\t\t\t_, err := writer.Write([]byte(content))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn fullResponse.String(), fullThinkingResponse.String(), fmt.Errorf(\"写入响应失败: %v\", err)\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// 收集完整回复\n\t\t\t\t\t\tfullResponse.WriteString(content)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// 检查是否完成\n\t\t\t\tif streamResponse.Choices[0].FinishReason != nil {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fullResponse.String(), fullThinkingResponse.String(), nil\n}\n\n// GetChatResponse 获取聊天回复\nfunc (s *DeepSeekService) GetChatResponse(userMessage string, deepThinking bool) (string, error) {\n\tif s.Config.APIKey == \"\" {\n\t\treturn \"未配置API密钥,无法连接DeepSeek服务\", nil\n\t}\n\n\t// 根据deepThinking标志选择使用的模型\n\tmodelToUse := s.Config.Model\n\tif deepThinking && s.Config.ReasonerModel != \"\" {\n\t\tmodelToUse = s.Config.ReasonerModel\n\t}\n\n\t// 构建请求体\n\trequestBody := ChatRequest{\n\t\tModel: modelToUse,\n\t\tMessages: []ChatMessage{\n\t\t\t{\n\t\t\t\tRole: \"user\",\n\t\t\t\tContent: userMessage,\n\t\t\t},\n\t\t},\n\t\tTemperature: 0.7,\n\t\tMaxTokens: 2000,\n\t}\n\n\t// 转换为JSON\n\tjsonData, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"序列化请求失败: %v\", err)\n\t}\n\n\t// 创建HTTP请求\n\turl := fmt.Sprintf(\"%s/chat/completions\", s.Config.BaseURL)\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"创建HTTP请求失败: %v\", err)\n\t}\n\n\t// 设置请求头\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+s.Config.APIKey)\n\n\t// 发送请求\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"发送请求失败: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 读取响应\n\tbody, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"读取响应失败: %v\", err)\n\t}\n\n\t// 检查HTTP状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"API请求失败,状态码: %d, 响应: %s\", resp.StatusCode, string(body))\n\t}\n\n\t// 解析响应\n\tvar response ChatResponse\n\tif err := json.Unmarshal(body, &response); err != nil {\n\t\treturn \"\", fmt.Errorf(\"解析响应失败: %v\", err)\n\t}\n\n\t// 检查是否有回复\n\tif len(response.Choices) == 0 {\n\t\treturn \"\", fmt.Errorf(\"没有收到有效回复\")\n\t}\n\n\t// 返回AI的回复\n\treturn response.Choices[0].Message.Content, nil\n}\n"}, "9acb252f7c2b27eb9f63c8cc9f44bff69f58b25a": {"t": 1785759883.6496587, "n": 8309, "h": "65b4d83937388826", "c": "package services\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n)\n\n// DeepSeekConfig 保存DeepSeek API的配置信息\ntype DeepSeekConfig struct {\n\tAPIKey string\n\tBaseURL string\n\tModel string\n\tReasonerModel string\n}\n\n// DeepSeekService 处理与DeepSeek API的交互\ntype DeepSeekService struct {\n\tConfig DeepSeekConfig\n}\n\n// 创建默认DeepSeek服务实例\nvar defaultDeepSeekService = NewDeepSeekService(DeepSeekConfig{\n\tBaseURL: \"https://api.deepseek.com/chat/completions\",\n\tModel: \"deepseek-chat\", // 默认使用v3模型\n\tReasonerModel: \"deepseek-reasoner\", // 用于思考模式的模型\n})\n\n// NewDeepSeekService 创建一个新的DeepSeekService实例\nfunc NewDeepSeekService(config DeepSeekConfig) *DeepSeekService {\n\treturn &DeepSeekService{\n\t\tConfig: config,\n\t}\n}\n\n// GetDefaultDeepSeekService 获取默认DeepSeek服务实例\nfunc GetDefaultDeepSeekService() *DeepSeekService {\n\treturn defaultDeepSeekService\n}\n\n// SetAPIKey 设置API密钥\nfunc (s *DeepSeekService) SetAPIKey(apiKey string) {\n\ts.Config.APIKey = apiKey\n}\n\n// SetModel 设置要使用的模型\nfunc (s *DeepSeekService) SetModel(model string) {\n\ts.Config.Model = model\n}\n\n// SetReasonerModel 设置要使用的思考模型\nfunc (s *DeepSeekService) SetReasonerModel(model string) {\n\ts.Config.ReasonerModel = model\n}\n\n// ChatRequest DeepSeek API聊天请求\ntype ChatRequest struct {\n\tModel string `json:\"model\"`\n\tMessages []ChatMessage `json:\"messages\"`\n\tTemperature float64 `json:\"temperature,omitempty\"`\n\tMaxTokens int `json:\"max_tokens,omitempty\"`\n\tStream bool `json:\"stream\"`\n}\n\n// ChatMessage 聊天消息\ntype ChatMessage struct {\n\tRole string `json:\"role\"`\n\tContent string `json:\"content\"`\n}\n\n// ChatResponse DeepSeek API聊天响应\ntype ChatResponse struct {\n\tID string `json:\"id\"`\n\tObject string `json:\"object\"`\n\tCreated int64 `json:\"created\"`\n\tModel string `json:\"model\"`\n\tChoices []struct {\n\t\tMessage ChatMessage `json:\"message\"`\n\t\tFinishReason string `json:\"finish_reason\"`\n\t} `json:\"choices\"`\n\tUsage struct {\n\t\tPromptTokens int `json:\"prompt_tokens\"`\n\t\tCompletionTokens int `json:\"completion_tokens\"`\n\t\tTotalTokens int `json:\"total_tokens\"`\n\t} `json:\"usage\"`\n}\n\n// StreamChatResponse 流式获取聊天回复,同时返回完整的响应文本\nfunc (s *DeepSeekService) StreamChatResponse(userMessage string, writer io.Writer, deepThinking bool) (string, string, error) {\n\tif s.Config.APIKey == \"\" {\n\t\tresponse := \"未配置API密钥,无法连接DeepSeek服务\"\n\t\twriter.Write([]byte(response))\n\t\treturn response, \"\", nil\n\t}\n\n\t// 根据deepThinking标志选择使用的模型\n\tmodelToUse := s.Config.Model\n\tif deepThinking && s.Config.ReasonerModel != \"\" {\n\t\tmodelToUse = s.Config.ReasonerModel\n\t}\n\n\t// 构建请求体\n\trequestBody := ChatRequest{\n\t\tModel: modelToUse,\n\t\tMessages: []ChatMessage{\n\t\t\t{\n\t\t\t\tRole: \"user\",\n\t\t\t\tContent: userMessage,\n\t\t\t},\n\t\t},\n\t\tTemperature: 0.7,\n\t\tMaxTokens: 100,\n\t\tStream: true, // 启用流式响应\n\t}\n\n\t// 转换为JSON\n\tjsonData, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"序列化请求失败: %v\", err)\n\t}\n\n\t// 创建HTTP请求\n\turl := fmt.Sprintf(\"%s\", s.Config.BaseURL)\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"创建HTTP请求失败: %v\", err)\n\t}\n\n\t// 设置请求头\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+s.Config.APIKey)\n\treq.Header.Set(\"Accept\", \"text/event-stream\")\n\n\t// 发送请求\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"发送请求失败: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 检查HTTP状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\tbody, _ := ioutil.ReadAll(resp.Body)\n\t\treturn \"\", \"\", fmt.Errorf(\"API请求失败,状态码: %d, 响应: %s\", resp.StatusCode, string(body))\n\t}\n\n\t// 读取响应流\n\treader := bufio.NewReader(resp.Body)\n\n\t// 用于收集完整回复\n\tvar fullResponse strings.Builder\n\tvar fullThinkingResponse strings.Builder\n\n\t// 如果DeepSeek API不支持流式输出或出现问题,我们实现一个模拟的流式响应\n\t// 这里通过简单地逐字符输出来模拟流式效果\n\tif !strings.Contains(resp.Header.Get(\"Content-Type\"), \"text/event-stream\") {\n\t\t// 读取整个响应\n\t\tbody, err := ioutil.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\treturn \"\", \"\", fmt.Errorf(\"读取响应失败: %v\", err)\n\t\t}\n\n\t\tvar response ChatResponse\n\t\tif err := json.Unmarshal(body, &response); err != nil {\n\t\t\treturn \"\", \"\", fmt.Errorf(\"解析响应失败: %v\", err)\n\t\t}\n\n\t\tif len(response.Choices) == 0 {\n\t\t\treturn \"\", \"\", fmt.Errorf(\"没有收到有效回复\")\n\t\t}\n\n\t\t// 获取完整回复\n\t\tfullReply := response.Choices[0].Message.Content\n\n\t\t// 模拟流式输出,每次发送一个字符\n\t\tfor _, char := range fullReply {\n\t\t\t_, err := writer.Write([]byte(string(char)))\n\t\t\tif err != nil {\n\t\t\t\treturn fullResponse.String(), \"\", fmt.Errorf(\"写入响应失败: %v\", err)\n\t\t\t}\n\t\t\t// 小延迟,模拟打字效果\n\t\t\ttime.Sleep(10 * time.Millisecond)\n\t\t\tfullResponse.WriteRune(char)\n\t\t}\n\t\treturn fullResponse.String(), fullThinkingResponse.String(), nil\n\t}\n\tthinking := false\n\t// 处理真正的SSE流\n\tfor {\n\t\tline, err := reader.ReadString('\\n')\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn fullResponse.String(), fullThinkingResponse.String(), fmt.Errorf(\"读取流失败: %v\", err)\n\t\t}\n\n\t\t// 跳过空行\n\t\tline = strings.TrimSpace(line)\n\t\tif line == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\t// 处理SSE格式数据\n\t\tif strings.HasPrefix(line, \"data: \") {\n\t\t\tdata := strings.TrimPrefix(line, \"data: \")\n\n\t\t\t// 检查流是否结束\n\t\t\tif data == \"[DONE]\" {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// 解析JSON\n\t\t\tvar streamResponse struct {\n\t\t\t\tChoices []struct {\n\t\t\t\t\tDelta struct {\n\t\t\t\t\t\tContent string `json:\"content\"`\n\t\t\t\t\t\tReasoningContent string `json:\"reasoning_content\"`\n\t\t\t\t\t} `json:\"delta\"`\n\t\t\t\t\tFinishReason *string `json:\"finish_reason\"`\n\t\t\t\t} `json:\"choices\"`\n\t\t\t}\n\n\t\t\tif err := json.Unmarshal([]byte(data), &streamResponse); err != nil {\n\t\t\t\tcontinue // 忽略解析错误,继续处理\n\t\t\t}\n\t\t\t// 检查是否有内容需要写入\n\t\t\tif len(streamResponse.Choices) > 0 {\n\t\t\t\treasoning_content := streamResponse.Choices[0].Delta.ReasoningContent\n\t\t\t\tif reasoning_content != \"\" {\n\t\t\t\t\tthinking = true\n\t\t\t\t\t_, err := writer.Write([]byte(reasoning_content))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn fullResponse.String(), fullThinkingResponse.String(), fmt.Errorf(\"写入响应失败: %v\", err)\n\t\t\t\t\t}\n\t\t\t\t\t// 收集完整回复\n\t\t\t\t\tfullThinkingResponse.WriteString(reasoning_content)\n\t\t\t\t} else {\n\t\t\t\t\tcontent := streamResponse.Choices[0].Delta.Content\n\t\t\t\t\tif content != \"\" {\n\t\t\t\t\t\tif thinking {\n\t\t\t\t\t\t\twriter.Write([]byte(\"$thinkEnd$\"))\n\t\t\t\t\t\t\tthinking = false\n\t\t\t\t\t\t}\n\t\t\t\t\t\t_, err := writer.Write([]byte(content))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn fullResponse.String(), fullThinkingResponse.String(), fmt.Errorf(\"写入响应失败: %v\", err)\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// 收集完整回复\n\t\t\t\t\t\tfullResponse.WriteString(content)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// 检查是否完成\n\t\t\t\tif streamResponse.Choices[0].FinishReason != nil {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fullResponse.String(), fullThinkingResponse.String(), nil\n}\n\n// GetChatResponse 获取聊天回复\nfunc (s *DeepSeekService) GetChatResponse(userMessage string, deepThinking bool) (string, error) {\n\tif s.Config.APIKey == \"\" {\n\t\treturn \"未配置API密钥,无法连接DeepSeek服务\", nil\n\t}\n\n\t// 根据deepThinking标志选择使用的模型\n\tmodelToUse := s.Config.Model\n\tif deepThinking && s.Config.ReasonerModel != \"\" {\n\t\tmodelToUse = s.Config.ReasonerModel\n\t}\n\n\t// 构建请求体\n\trequestBody := ChatRequest{\n\t\tModel: modelToUse,\n\t\tMessages: []ChatMessage{\n\t\t\t{\n\t\t\t\tRole: \"user\",\n\t\t\t\tContent: userMessage,\n\t\t\t},\n\t\t},\n\t\tTemperature: 0.7,\n\t\tMaxTokens: 2000,\n\t}\n\n\t// 转换为JSON\n\tjsonData, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"序列化请求失败: %v\", err)\n\t}\n\n\t// 创建HTTP请求\n\turl := fmt.Sprintf(\"%s/chat/completions\", s.Config.BaseURL)\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"创建HTTP请求失败: %v\", err)\n\t}\n\n\t// 设置请求头\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+s.Config.APIKey)\n\n\t// 发送请求\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"发送请求失败: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 读取响应\n\tbody, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"读取响应失败: %v\", err)\n\t}\n\n\t// 检查HTTP状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"API请求失败,状态码: %d, 响应: %s\", resp.StatusCode, string(body))\n\t}\n\n\t// 解析响应\n\tvar response ChatResponse\n\tif err := json.Unmarshal(body, &response); err != nil {\n\t\treturn \"\", fmt.Errorf(\"解析响应失败: %v\", err)\n\t}\n\n\t// 检查是否有回复\n\tif len(response.Choices) == 0 {\n\t\treturn \"\", fmt.Errorf(\"没有收到有效回复\")\n\t}\n\n\t// 返回AI的回复\n\treturn response.Choices[0].Message.Content, nil\n}\n"}, "91f7ec85fea74bd91d16025b80aacba1d6f72501": {"t": 1785759884.9595797, "n": 7519, "h": "8ff067770b15dc0c", "c": "package services\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n)\n\n// DeepSeekConfig 保存DeepSeek API的配置信息\ntype DeepSeekConfig struct {\n\tAPIKey string\n\tBaseURL string\n\tModel string\n\tReasonerModel string\n}\n\n// DeepSeekService 处理与DeepSeek API的交互\ntype DeepSeekService struct {\n\tConfig DeepSeekConfig\n}\n\n// 创建默认DeepSeek服务实例\nvar defaultDeepSeekService = NewDeepSeekService(DeepSeekConfig{\n\tBaseURL: \"https://api.deepseek.com/v1\",\n\tModel: \"deepseek-chat\", // 默认使用v3模型\n\tReasonerModel: \"deepseek-reasoner\", // 用于思考模式的模型\n})\n\n// NewDeepSeekService 创建一个新的DeepSeekService实例\nfunc NewDeepSeekService(config DeepSeekConfig) *DeepSeekService {\n\treturn &DeepSeekService{\n\t\tConfig: config,\n\t}\n}\n\n// GetDefaultDeepSeekService 获取默认DeepSeek服务实例\nfunc GetDefaultDeepSeekService() *DeepSeekService {\n\treturn defaultDeepSeekService\n}\n\n// SetAPIKey 设置API密钥\nfunc (s *DeepSeekService) SetAPIKey(apiKey string) {\n\ts.Config.APIKey = apiKey\n}\n\n// SetModel 设置要使用的模型\nfunc (s *DeepSeekService) SetModel(model string) {\n\ts.Config.Model = model\n}\n\n// SetReasonerModel 设置要使用的思考模型\nfunc (s *DeepSeekService) SetReasonerModel(model string) {\n\ts.Config.ReasonerModel = model\n}\n\n// ChatRequest DeepSeek API聊天请求\ntype ChatRequest struct {\n\tModel string `json:\"model\"`\n\tMessages []ChatMessage `json:\"messages\"`\n\tTemperature float64 `json:\"temperature,omitempty\"`\n\tMaxTokens int `json:\"max_tokens,omitempty\"`\n\tStream bool `json:\"stream\"`\n}\n\n// ChatMessage 聊天消息\ntype ChatMessage struct {\n\tRole string `json:\"role\"`\n\tContent string `json:\"content\"`\n}\n\n// ChatResponse DeepSeek API聊天响应\ntype ChatResponse struct {\n\tID string `json:\"id\"`\n\tObject string `json:\"object\"`\n\tCreated int64 `json:\"created\"`\n\tModel string `json:\"model\"`\n\tChoices []struct {\n\t\tMessage ChatMessage `json:\"message\"`\n\t\tFinishReason string `json:\"finish_reason\"`\n\t} `json:\"choices\"`\n\tUsage struct {\n\t\tPromptTokens int `json:\"prompt_tokens\"`\n\t\tCompletionTokens int `json:\"completion_tokens\"`\n\t\tTotalTokens int `json:\"total_tokens\"`\n\t} `json:\"usage\"`\n}\n\n// StreamChatResponse 流式获取聊天回复,同时返回完整的响应文本\nfunc (s *DeepSeekService) StreamChatResponse(userMessage string, writer io.Writer, deepThinking bool) (string, error) {\n\tif s.Config.APIKey == \"\" {\n\t\tresponse := \"未配置API密钥,无法连接DeepSeek服务\"\n\t\twriter.Write([]byte(response))\n\t\treturn response, nil\n\t}\n\n\t// 根据deepThinking标志选择使用的模型\n\tmodelToUse := s.Config.Model\n\tif deepThinking && s.Config.ReasonerModel != \"\" {\n\t\tmodelToUse = s.Config.ReasonerModel\n\t}\n\n\t// 构建请求体\n\trequestBody := ChatRequest{\n\t\tModel: modelToUse,\n\t\tMessages: []ChatMessage{\n\t\t\t{\n\t\t\t\tRole: \"user\",\n\t\t\t\tContent: userMessage,\n\t\t\t},\n\t\t},\n\t\tTemperature: 0.7,\n\t\tMaxTokens: 2000,\n\t\tStream: true, // 启用流式响应\n\t}\n\n\t// 转换为JSON\n\tjsonData, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"序列化请求失败: %v\", err)\n\t}\n\n\t// 创建HTTP请求\n\turl := fmt.Sprintf(\"%s/chat/completions\", s.Config.BaseURL)\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"创建HTTP请求失败: %v\", err)\n\t}\n\n\t// 设置请求头\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+s.Config.APIKey)\n\treq.Header.Set(\"Accept\", \"text/event-stream\")\n\n\t// 发送请求\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"发送请求失败: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 检查HTTP状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\tbody, _ := ioutil.ReadAll(resp.Body)\n\t\treturn \"\", fmt.Errorf(\"API请求失败,状态码: %d, 响应: %s\", resp.StatusCode, string(body))\n\t}\n\n\t// 读取响应流\n\treader := bufio.NewReader(resp.Body)\n\n\t// 用于收集完整回复\n\tvar fullResponse strings.Builder\n\n\t// 如果DeepSeek API不支持流式输出或出现问题,我们实现一个模拟的流式响应\n\t// 这里通过简单地逐字符输出来模拟流式效果\n\tif !strings.Contains(resp.Header.Get(\"Content-Type\"), \"text/event-stream\") {\n\t\t// 读取整个响应\n\t\tbody, err := ioutil.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"读取响应失败: %v\", err)\n\t\t}\n\n\t\tvar response ChatResponse\n\t\tif err := json.Unmarshal(body, &response); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"解析响应失败: %v\", err)\n\t\t}\n\n\t\tif len(response.Choices) == 0 {\n\t\t\treturn \"\", fmt.Errorf(\"没有收到有效回复\")\n\t\t}\n\n\t\t// 获取完整回复\n\t\tfullReply := response.Choices[0].Message.Content\n\n\t\t// 模拟流式输出,每次发送一个字符\n\t\tfor _, char := range fullReply {\n\t\t\t_, err := writer.Write([]byte(string(char)))\n\t\t\tif err != nil {\n\t\t\t\treturn fullResponse.String(), fmt.Errorf(\"写入响应失败: %v\", err)\n\t\t\t}\n\t\t\t// 小延迟,模拟打字效果\n\t\t\ttime.Sleep(10 * time.Millisecond)\n\t\t\tfullResponse.WriteRune(char)\n\t\t}\n\t\treturn fullResponse.String(), nil\n\t}\n\n\t// 处理真正的SSE流\n\tfor {\n\t\tline, err := reader.ReadString('\\n')\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn fullResponse.String(), fmt.Errorf(\"读取流失败: %v\", err)\n\t\t}\n\n\t\t// 跳过空行\n\t\tline = strings.TrimSpace(line)\n\t\tif line == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\t// 处理SSE格式数据\n\t\tif strings.HasPrefix(line, \"data: \") {\n\t\t\tdata := strings.TrimPrefix(line, \"data: \")\n\n\t\t\t// 检查流是否结束\n\t\t\tif data == \"[DONE]\" {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// 解析JSON\n\t\t\tvar streamResponse struct {\n\t\t\t\tChoices []struct {\n\t\t\t\t\tDelta struct {\n\t\t\t\t\t\tContent string `json:\"content\"`\n\t\t\t\t\t} `json:\"delta\"`\n\t\t\t\t\tFinishReason *string `json:\"finish_reason\"`\n\t\t\t\t} `json:\"choices\"`\n\t\t\t}\n\n\t\t\tif err := json.Unmarshal([]byte(data), &streamResponse); err != nil {\n\t\t\t\tcontinue // 忽略解析错误,继续处理\n\t\t\t}\n\n\t\t\t// 检查是否有内容需要写入\n\t\t\tif len(streamResponse.Choices) > 0 {\n\t\t\t\tcontent := streamResponse.Choices[0].Delta.Content\n\t\t\t\tif content != \"\" {\n\t\t\t\t\t_, err := writer.Write([]byte(content))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn fullResponse.String(), fmt.Errorf(\"写入响应失败: %v\", err)\n\t\t\t\t\t}\n\t\t\t\t\t// 收集完整回复\n\t\t\t\t\tfullResponse.WriteString(content)\n\t\t\t\t}\n\n\t\t\t\t// 检查是否完成\n\t\t\t\tif streamResponse.Choices[0].FinishReason != nil {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fullResponse.String(), nil\n}\n\n// GetChatResponse 获取聊天回复\nfunc (s *DeepSeekService) GetChatResponse(userMessage string, deepThinking bool) (string, error) {\n\tif s.Config.APIKey == \"\" {\n\t\treturn \"未配置API密钥,无法连接DeepSeek服务\", nil\n\t}\n\n\t// 根据deepThinking标志选择使用的模型\n\tmodelToUse := s.Config.Model\n\tif deepThinking && s.Config.ReasonerModel != \"\" {\n\t\tmodelToUse = s.Config.ReasonerModel\n\t}\n\n\t// 构建请求体\n\trequestBody := ChatRequest{\n\t\tModel: modelToUse,\n\t\tMessages: []ChatMessage{\n\t\t\t{\n\t\t\t\tRole: \"user\",\n\t\t\t\tContent: userMessage,\n\t\t\t},\n\t\t},\n\t\tTemperature: 0.7,\n\t\tMaxTokens: 2000,\n\t}\n\n\t// 转换为JSON\n\tjsonData, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"序列化请求失败: %v\", err)\n\t}\n\n\t// 创建HTTP请求\n\turl := fmt.Sprintf(\"%s/chat/completions\", s.Config.BaseURL)\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"创建HTTP请求失败: %v\", err)\n\t}\n\n\t// 设置请求头\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+s.Config.APIKey)\n\n\t// 发送请求\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"发送请求失败: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 读取响应\n\tbody, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"读取响应失败: %v\", err)\n\t}\n\n\t// 检查HTTP状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"API请求失败,状态码: %d, 响应: %s\", resp.StatusCode, string(body))\n\t}\n\n\t// 解析响应\n\tvar response ChatResponse\n\tif err := json.Unmarshal(body, &response); err != nil {\n\t\treturn \"\", fmt.Errorf(\"解析响应失败: %v\", err)\n\t}\n\n\t// 检查是否有回复\n\tif len(response.Choices) == 0 {\n\t\treturn \"\", fmt.Errorf(\"没有收到有效回复\")\n\t}\n\n\t// 返回AI的回复\n\treturn response.Choices[0].Message.Content, nil\n}\n"}, "28516414574e37dbcf0c60350bf3303b89a343d8": {"t": 1785759886.200604, "n": 6956, "h": "78e52543323e71ce", "c": "package services\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n)\n\n// DeepSeekConfig 保存DeepSeek API的配置信息\ntype DeepSeekConfig struct {\n\tAPIKey string\n\tBaseURL string\n\tModel string\n}\n\n// DeepSeekService 处理与DeepSeek API的交互\ntype DeepSeekService struct {\n\tConfig DeepSeekConfig\n}\n\n// 创建默认DeepSeek服务实例\nvar defaultDeepSeekService = NewDeepSeekService(DeepSeekConfig{\n\tBaseURL: \"https://api.deepseek.com/v1\",\n\tModel: \"deepseek-chat\", // 默认使用v3模型\n})\n\n// NewDeepSeekService 创建一个新的DeepSeekService实例\nfunc NewDeepSeekService(config DeepSeekConfig) *DeepSeekService {\n\treturn &DeepSeekService{\n\t\tConfig: config,\n\t}\n}\n\n// GetDefaultDeepSeekService 获取默认DeepSeek服务实例\nfunc GetDefaultDeepSeekService() *DeepSeekService {\n\treturn defaultDeepSeekService\n}\n\n// SetAPIKey 设置API密钥\nfunc (s *DeepSeekService) SetAPIKey(apiKey string) {\n\ts.Config.APIKey = apiKey\n}\n\n// SetModel 设置要使用的模型\nfunc (s *DeepSeekService) SetModel(model string) {\n\ts.Config.Model = model\n}\n\n// ChatRequest DeepSeek API聊天请求\ntype ChatRequest struct {\n\tModel string `json:\"model\"`\n\tMessages []ChatMessage `json:\"messages\"`\n\tTemperature float64 `json:\"temperature,omitempty\"`\n\tMaxTokens int `json:\"max_tokens,omitempty\"`\n\tStream bool `json:\"stream\"`\n}\n\n// ChatMessage 聊天消息\ntype ChatMessage struct {\n\tRole string `json:\"role\"`\n\tContent string `json:\"content\"`\n}\n\n// ChatResponse DeepSeek API聊天响应\ntype ChatResponse struct {\n\tID string `json:\"id\"`\n\tObject string `json:\"object\"`\n\tCreated int64 `json:\"created\"`\n\tModel string `json:\"model\"`\n\tChoices []struct {\n\t\tMessage ChatMessage `json:\"message\"`\n\t\tFinishReason string `json:\"finish_reason\"`\n\t} `json:\"choices\"`\n\tUsage struct {\n\t\tPromptTokens int `json:\"prompt_tokens\"`\n\t\tCompletionTokens int `json:\"completion_tokens\"`\n\t\tTotalTokens int `json:\"total_tokens\"`\n\t} `json:\"usage\"`\n}\n\n// StreamChatResponse 流式获取聊天回复,同时返回完整的响应文本\nfunc (s *DeepSeekService) StreamChatResponse(userMessage string, writer io.Writer) (string, error) {\n\tif s.Config.APIKey == \"\" {\n\t\tresponse := \"未配置API密钥,无法连接DeepSeek服务\"\n\t\twriter.Write([]byte(response))\n\t\treturn response, nil\n\t}\n\n\t// 构建请求体\n\trequestBody := ChatRequest{\n\t\tModel: s.Config.Model,\n\t\tMessages: []ChatMessage{\n\t\t\t{\n\t\t\t\tRole: \"user\",\n\t\t\t\tContent: userMessage,\n\t\t\t},\n\t\t},\n\t\tTemperature: 0.7,\n\t\tMaxTokens: 2000,\n\t\tStream: true, // 启用流式响应\n\t}\n\n\t// 转换为JSON\n\tjsonData, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"序列化请求失败: %v\", err)\n\t}\n\n\t// 创建HTTP请求\n\turl := fmt.Sprintf(\"%s/chat/completions\", s.Config.BaseURL)\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"创建HTTP请求失败: %v\", err)\n\t}\n\n\t// 设置请求头\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+s.Config.APIKey)\n\treq.Header.Set(\"Accept\", \"text/event-stream\")\n\n\t// 发送请求\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"发送请求失败: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 检查HTTP状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\tbody, _ := ioutil.ReadAll(resp.Body)\n\t\treturn \"\", fmt.Errorf(\"API请求失败,状态码: %d, 响应: %s\", resp.StatusCode, string(body))\n\t}\n\n\t// 读取响应流\n\treader := bufio.NewReader(resp.Body)\n\n\t// 用于收集完整回复\n\tvar fullResponse strings.Builder\n\n\t// 如果DeepSeek API不支持流式输出或出现问题,我们实现一个模拟的流式响应\n\t// 这里通过简单地逐字符输出来模拟流式效果\n\tif !strings.Contains(resp.Header.Get(\"Content-Type\"), \"text/event-stream\") {\n\t\t// 读取整个响应\n\t\tbody, err := ioutil.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"读取响应失败: %v\", err)\n\t\t}\n\n\t\tvar response ChatResponse\n\t\tif err := json.Unmarshal(body, &response); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"解析响应失败: %v\", err)\n\t\t}\n\n\t\tif len(response.Choices) == 0 {\n\t\t\treturn \"\", fmt.Errorf(\"没有收到有效回复\")\n\t\t}\n\n\t\t// 获取完整回复\n\t\tfullReply := response.Choices[0].Message.Content\n\n\t\t// 模拟流式输出,每次发送一个字符\n\t\tfor _, char := range fullReply {\n\t\t\t_, err := writer.Write([]byte(string(char)))\n\t\t\tif err != nil {\n\t\t\t\treturn fullResponse.String(), fmt.Errorf(\"写入响应失败: %v\", err)\n\t\t\t}\n\t\t\t// 小延迟,模拟打字效果\n\t\t\ttime.Sleep(10 * time.Millisecond)\n\t\t\tfullResponse.WriteRune(char)\n\t\t}\n\t\treturn fullResponse.String(), nil\n\t}\n\n\t// 处理真正的SSE流\n\tfor {\n\t\tline, err := reader.ReadString('\\n')\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn fullResponse.String(), fmt.Errorf(\"读取流失败: %v\", err)\n\t\t}\n\n\t\t// 跳过空行\n\t\tline = strings.TrimSpace(line)\n\t\tif line == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\t// 处理SSE格式数据\n\t\tif strings.HasPrefix(line, \"data: \") {\n\t\t\tdata := strings.TrimPrefix(line, \"data: \")\n\n\t\t\t// 检查流是否结束\n\t\t\tif data == \"[DONE]\" {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// 解析JSON\n\t\t\tvar streamResponse struct {\n\t\t\t\tChoices []struct {\n\t\t\t\t\tDelta struct {\n\t\t\t\t\t\tContent string `json:\"content\"`\n\t\t\t\t\t} `json:\"delta\"`\n\t\t\t\t\tFinishReason *string `json:\"finish_reason\"`\n\t\t\t\t} `json:\"choices\"`\n\t\t\t}\n\n\t\t\tif err := json.Unmarshal([]byte(data), &streamResponse); err != nil {\n\t\t\t\tcontinue // 忽略解析错误,继续处理\n\t\t\t}\n\n\t\t\t// 检查是否有内容需要写入\n\t\t\tif len(streamResponse.Choices) > 0 {\n\t\t\t\tcontent := streamResponse.Choices[0].Delta.Content\n\t\t\t\tif content != \"\" {\n\t\t\t\t\t_, err := writer.Write([]byte(content))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn fullResponse.String(), fmt.Errorf(\"写入响应失败: %v\", err)\n\t\t\t\t\t}\n\t\t\t\t\t// 收集完整回复\n\t\t\t\t\tfullResponse.WriteString(content)\n\t\t\t\t}\n\n\t\t\t\t// 检查是否完成\n\t\t\t\tif streamResponse.Choices[0].FinishReason != nil {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fullResponse.String(), nil\n}\n\n// GetChatResponse 获取聊天回复\nfunc (s *DeepSeekService) GetChatResponse(userMessage string) (string, error) {\n\tif s.Config.APIKey == \"\" {\n\t\treturn \"未配置API密钥,无法连接DeepSeek服务\", nil\n\t}\n\n\t// 构建请求体\n\trequestBody := ChatRequest{\n\t\tModel: s.Config.Model,\n\t\tMessages: []ChatMessage{\n\t\t\t{\n\t\t\t\tRole: \"user\",\n\t\t\t\tContent: userMessage,\n\t\t\t},\n\t\t},\n\t\tTemperature: 0.7,\n\t\tMaxTokens: 2000,\n\t}\n\n\t// 转换为JSON\n\tjsonData, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"序列化请求失败: %v\", err)\n\t}\n\n\t// 创建HTTP请求\n\turl := fmt.Sprintf(\"%s/chat/completions\", s.Config.BaseURL)\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"创建HTTP请求失败: %v\", err)\n\t}\n\n\t// 设置请求头\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+s.Config.APIKey)\n\n\t// 发送请求\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"发送请求失败: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 读取响应\n\tbody, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"读取响应失败: %v\", err)\n\t}\n\n\t// 检查HTTP状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"API请求失败,状态码: %d, 响应: %s\", resp.StatusCode, string(body))\n\t}\n\n\t// 解析响应\n\tvar response ChatResponse\n\tif err := json.Unmarshal(body, &response); err != nil {\n\t\treturn \"\", fmt.Errorf(\"解析响应失败: %v\", err)\n\t}\n\n\t// 检查是否有回复\n\tif len(response.Choices) == 0 {\n\t\treturn \"\", fmt.Errorf(\"没有收到有效回复\")\n\t}\n\n\t// 返回AI的回复\n\treturn response.Choices[0].Message.Content, nil\n}\n"}, "045787b34678dba93506a321b2e5c9b0f9438681": {"t": 1785759887.526687, "n": 3360, "h": "45cc5082c7737659", "c": "package services\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"net/http\"\n)\n\n// DeepSeekConfig 保存DeepSeek API的配置信息\ntype DeepSeekConfig struct {\n\tAPIKey string\n\tBaseURL string\n\tModel string\n}\n\n// DeepSeekService 处理与DeepSeek API的交互\ntype DeepSeekService struct {\n\tConfig DeepSeekConfig\n}\n\n// 创建默认DeepSeek服务实例\nvar defaultDeepSeekService = NewDeepSeekService(DeepSeekConfig{\n\tBaseURL: \"https://api.deepseek.com/v1\",\n\tModel: \"deepseek-chat\", // 默认使用v3模型\n})\n\n// NewDeepSeekService 创建一个新的DeepSeekService实例\nfunc NewDeepSeekService(config DeepSeekConfig) *DeepSeekService {\n\treturn &DeepSeekService{\n\t\tConfig: config,\n\t}\n}\n\n// GetDefaultDeepSeekService 获取默认DeepSeek服务实例\nfunc GetDefaultDeepSeekService() *DeepSeekService {\n\treturn defaultDeepSeekService\n}\n\n// SetAPIKey 设置API密钥\nfunc (s *DeepSeekService) SetAPIKey(apiKey string) {\n\ts.Config.APIKey = apiKey\n}\n\n// SetModel 设置要使用的模型\nfunc (s *DeepSeekService) SetModel(model string) {\n\ts.Config.Model = model\n}\n\n// ChatRequest DeepSeek API聊天请求\ntype ChatRequest struct {\n\tModel string `json:\"model\"`\n\tMessages []ChatMessage `json:\"messages\"`\n\tTemperature float64 `json:\"temperature,omitempty\"`\n\tMaxTokens int `json:\"max_tokens,omitempty\"`\n}\n\n// ChatMessage 聊天消息\ntype ChatMessage struct {\n\tRole string `json:\"role\"`\n\tContent string `json:\"content\"`\n}\n\n// ChatResponse DeepSeek API聊天响应\ntype ChatResponse struct {\n\tID string `json:\"id\"`\n\tObject string `json:\"object\"`\n\tCreated int64 `json:\"created\"`\n\tModel string `json:\"model\"`\n\tChoices []struct {\n\t\tMessage ChatMessage `json:\"message\"`\n\t\tFinishReason string `json:\"finish_reason\"`\n\t} `json:\"choices\"`\n\tUsage struct {\n\t\tPromptTokens int `json:\"prompt_tokens\"`\n\t\tCompletionTokens int `json:\"completion_tokens\"`\n\t\tTotalTokens int `json:\"total_tokens\"`\n\t} `json:\"usage\"`\n}\n\n// GetChatResponse 获取聊天回复\nfunc (s *DeepSeekService) GetChatResponse(userMessage string) (string, error) {\n\tif s.Config.APIKey == \"\" {\n\t\treturn \"未配置API密钥,无法连接DeepSeek服务\", nil\n\t}\n\n\t// 构建请求体\n\trequestBody := ChatRequest{\n\t\tModel: s.Config.Model,\n\t\tMessages: []ChatMessage{\n\t\t\t{\n\t\t\t\tRole: \"user\",\n\t\t\t\tContent: userMessage,\n\t\t\t},\n\t\t},\n\t\tTemperature: 0.7,\n\t\tMaxTokens: 2000,\n\t}\n\n\t// 转换为JSON\n\tjsonData, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"序列化请求失败: %v\", err)\n\t}\n\n\t// 创建HTTP请求\n\turl := fmt.Sprintf(\"%s/chat/completions\", s.Config.BaseURL)\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"创建HTTP请求失败: %v\", err)\n\t}\n\n\t// 设置请求头\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Authorization\", \"Bearer \"+s.Config.APIKey)\n\n\t// 发送请求\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"发送请求失败: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 读取响应\n\tbody, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"读取响应失败: %v\", err)\n\t}\n\n\t// 检查HTTP状态码\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"API请求失败,状态码: %d, 响应: %s\", resp.StatusCode, string(body))\n\t}\n\n\t// 解析响应\n\tvar response ChatResponse\n\tif err := json.Unmarshal(body, &response); err != nil {\n\t\treturn \"\", fmt.Errorf(\"解析响应失败: %v\", err)\n\t}\n\n\t// 检查是否有回复\n\tif len(response.Choices) == 0 {\n\t\treturn \"\", fmt.Errorf(\"没有收到有效回复\")\n\t}\n\n\t// 返回AI的回复\n\treturn response.Choices[0].Message.Content, nil\n}\n"}}, "backend/config.yml": {"6c49a3d14913d217c7cf28251bf4c0c28d17899d": {"t": 1785746862.3463628, "n": 397, "h": "2834453101426c49", "c": "server:\n host: 0.0.0.0\n port: 8080\n\ndatabase:\n host: 113.44.1.253\n port: 3306\n user: root\n password: root\n dbname: chat\n charset: utf8mb4\n\njwt:\n secret: your-secret-key-change-this\n expires_in: 24 \n\ndeepseek:\n api_key: sk-ab05874f5a4847bfa44c0a8c07db03e6\n base_url: https://api.deepseek.com/chat/completions\n model: deepseek-chat \n reasoner_model: deepseek-reasoner \n max_token: 300"}, "6be26160bd44a2ee028a4a82b8375d441daaa1cf": {"t": 1785759882.184214, "n": 397, "h": "2834453101426c49", "c": "server:\n host: 0.0.0.0\n port: 8080\n\ndatabase:\n host: 113.44.1.253\n port: 3306\n user: root\n password: root\n dbname: chat\n charset: utf8mb4\n\njwt:\n secret: your-secret-key-change-this\n expires_in: 24 \n\ndeepseek:\n api_key: sk-ab05874f5a4847bfa44c0a8c07db03e6\n base_url: https://api.deepseek.com/chat/completions\n model: deepseek-chat \n reasoner_model: deepseek-reasoner \n max_token: 300"}, "9acb252f7c2b27eb9f63c8cc9f44bff69f58b25a": {"t": 1785759883.5367143, "n": 380, "h": "f83047a57774093f", "c": "server:\n host: 0.0.0.0\n port: 8080\n\ndatabase:\n host: 113.44.1.253\n port: 3306\n user: root\n password: root\n dbname: chat\n charset: utf8mb4\n\njwt:\n secret: your-secret-key-change-this\n expires_in: 24 \n\ndeepseek:\n api_key: sk-ab05874f5a4847bfa44c0a8c07db03e6\n base_url: https://api.deepseek.com/chat/completions\n model: deepseek-chat \n reasoner_model: deepseek-reasoner "}, "91f7ec85fea74bd91d16025b80aacba1d6f72501": {"t": 1785759884.8594844, "n": 366, "h": "d9bd2407a766b1c7", "c": "server:\n host: 0.0.0.0\n port: 8080\n\ndatabase:\n host: 113.44.1.253\n port: 3306\n user: root\n password: root\n dbname: chat\n charset: utf8mb4\n\njwt:\n secret: your-secret-key-change-this\n expires_in: 24 \n\ndeepseek:\n api_key: sk-ab05874f5a4847bfa44c0a8c07db03e6\n base_url: https://api.deepseek.com/v1\n model: deepseek-chat \n reasoner_model: deepseek-reasoner "}, "28516414574e37dbcf0c60350bf3303b89a343d8": {"t": 1785759886.08344, "n": 329, "h": "49afcbac6532aa10", "c": "server:\n host: 0.0.0.0\n port: 8080\n\ndatabase:\n host: 113.44.1.253\n port: 3306\n user: root\n password: root\n dbname: chat\n charset: utf8mb4\n\njwt:\n secret: your-secret-key-change-this\n expires_in: 24 \n\ndeepseek:\n api_key: sk-ab05874f5a4847bfa44c0a8c07db03e6\n base_url: https://api.deepseek.com/v1\n model: deepseek-chat "}}}}