diff --git a/applogic/chatglm.go b/applogic/chatglm.go index 6373a6e..3405390 100644 --- a/applogic/chatglm.go +++ b/applogic/chatglm.go @@ -225,16 +225,16 @@ func (app *App) ChatHandlerGlm(w http.ResponseWriter, r *http.Request) { } // 获取配置信息 - apiKey := config.GetGlmApiKey() + apiKey := config.GetGlmApiKey(promptstr) // 创建请求体的映射结构 requestBody := map[string]interface{}{ - "model": config.GetGlmModel(), + "model": config.GetGlmModel(promptstr), "messages": messages, "do_sample": config.GetGlmDoSample(), "stream": config.GetuseSse(promptstr), "temperature": config.GetGlmTemperature(), "top_p": config.GetGlmTopP(), - "max_tokens": config.GetGlmMaxTokens(), + "max_tokens": config.GetGlmMaxTokens(promptstr), "stop": config.GetGlmStop(), //"tools": config.GetGlmTools(), 不太清楚参数格式 "tool_choice": config.GetGlmToolChoice(), diff --git a/applogic/gensokyo.go b/applogic/gensokyo.go index 246c80c..60d5a94 100644 --- a/applogic/gensokyo.go +++ b/applogic/gensokyo.go @@ -11,6 +11,7 @@ import ( "net/url" "strconv" "strings" + "sync" "github.com/hoshinonyaruko/gensokyo-llm/acnode" "github.com/hoshinonyaruko/gensokyo-llm/config" @@ -20,7 +21,8 @@ import ( ) var newmsgToStringMap = make(map[string]string) -var stringToIndexMap = make(map[string]int) +var stringToIndexMap sync.Map +var processMessageMu sync.Mutex // RecordStringById 根据id记录一个string func RecordStringByNewmsg(id, value string) { @@ -38,20 +40,30 @@ func GetStringByNewmsg(newmsg string) string { // IncrementIndex 为给定的字符串递增索引 func IncrementIndex(s string) int { - // 检查map中是否已经有这个字符串的索引 - if _, exists := stringToIndexMap[s]; !exists { - // 如果不存在,初始化为0 - stringToIndexMap[s] = 0 + // 尝试从map中获取值,如果不存在则初始化为0 + val, loaded := stringToIndexMap.LoadOrStore(s, 0) + if !loaded { + // 如果这是一个新的键,我们现在将其值设置为1 + stringToIndexMap.Store(s, 1) + return 1 } - // 递增索引 - stringToIndexMap[s]++ - // 返回新的索引值 - return stringToIndexMap[s] + + // 如果已存在,递增索引 + newVal := val.(int) + 1 + stringToIndexMap.Store(s, newVal) + return newVal } -// ResetIndex 将给定字符串的索引归零 +// ResetIndex 重置或删除给定字符串的索引 func ResetIndex(s string) { - stringToIndexMap[s] = 0 + // 直接从map中删除指定的键 + stringToIndexMap.Delete(s) +} + +// ResetAllIndexes 清空整个索引map +func ResetAllIndexes() { + // 重新初始化stringToIndexMap,因为sync.Map没有提供清空所有条目的直接方法 + stringToIndexMap = sync.Map{} } // checkMessageForHints 检查消息中是否包含给定的提示词 @@ -252,7 +264,7 @@ func (app *App) GensokyoHandler(w http.ResponseWriter, r *http.Request) { } if utils.BlacklistIntercept(message, selfid) { - fmtf.Printf("userid:[%v]这位用户在黑名单中,被拦截", message.UserID) + fmtf.Printf("userid:[%v]groupid:[%v]这位用户或群在黑名单中,被拦截", message.UserID, message.GroupID) return } @@ -607,7 +619,11 @@ func (app *App) GensokyoHandler(w http.ResponseWriter, r *http.Request) { lastMessageID = id // 更新lastMessageID // 检查是否有未发送的消息部分 key := utils.GetKey(message.GroupID, message.UserID) - accumulatedMessage, exists := groupUserMessages[key] + accumulatedMessageInterface, exists := groupUserMessages.Load(key) + var accumulatedMessage string + if exists { + accumulatedMessage = accumulatedMessageInterface.(string) + } // 提取response字段 if response, ok = responseData["response"].(string); ok { @@ -721,8 +737,8 @@ func (app *App) GensokyoHandler(w http.ResponseWriter, r *http.Request) { } } - // 清空映射中对应的累积消息 - groupUserMessages[key] = "" + // 清空key的值 + groupUserMessages.Store(key, "") } } else { //发送信息 @@ -909,7 +925,16 @@ func processMessage(response string, msg structs.OnebotGroupMessage, newmesssage // 达到标点符号,发送累积的整个消息 if messageBuilder.Len() > 0 { accumulatedMessage := messageBuilder.String() - groupUserMessages[key] += accumulatedMessage + // 锁定 + processMessageMu.Lock() + // 从sync.map读取当前的value + valueInterface, _ := groupUserMessages.Load(key) + value, _ := valueInterface.(string) + // 添加当前messageBuilder中的新内容 + value += accumulatedMessage + // 储存新的内容到sync.map + groupUserMessages.Store(key, value) + processMessageMu.Unlock() // 完成更新后时解锁 // 判断消息类型,如果是私人消息或私有群消息,发送私人消息;否则,根据配置决定是否发送群消息 if msg.RealMessageType == "group_private" || msg.MessageType == "private" { diff --git a/applogic/hunyuan.go b/applogic/hunyuan.go index 59dc088..8168e87 100644 --- a/applogic/hunyuan.go +++ b/applogic/hunyuan.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" "strings" + "sync" "github.com/hoshinonyaruko/gensokyo-llm/config" "github.com/hoshinonyaruko/gensokyo-llm/fmtf" @@ -15,7 +16,7 @@ import ( ) var messageBuilder strings.Builder -var groupUserMessages = make(map[string]string) +var groupUserMessages sync.Map func (app *App) ChatHandlerHunyuan(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { diff --git a/applogic/tongyiqianwen.go b/applogic/tongyiqianwen.go index e067e90..e35e4d7 100644 --- a/applogic/tongyiqianwen.go +++ b/applogic/tongyiqianwen.go @@ -198,7 +198,7 @@ func (app *App) ChatHandlerTyqw(w http.ResponseWriter, r *http.Request) { fmtf.Printf("Tyqw上下文history:%v\n", history) // 构建请求到Tyqw API - apiURL := config.GetTyqwApiPath() + apiURL := config.GetTyqwApiPath(promptstr) // 构造消息历史和当前消息 messages := []map[string]interface{}{} @@ -216,29 +216,29 @@ func (app *App) ChatHandlerTyqw(w http.ResponseWriter, r *http.Request) { }) var isIncrementalOutput bool - if config.GetTyqwSseType() == 1 { + if config.GetTyqwSseType(promptstr) == 1 { isIncrementalOutput = true } // 获取配置信息 useSSE := config.GetuseSse(promptstr) - apiKey := config.GetTyqwKey() + apiKey := config.GetTyqwKey(promptstr) var requestBody map[string]interface{} if useSSE { // 构建请求体,根据提供的文档重新调整 requestBody = map[string]interface{}{ "parameters": map[string]interface{}{ - "max_tokens": config.GetTyqwMaxTokens(), // 最大生成的token数 - "temperature": config.GetTyqwTemperature(), // 控制随机性和多样性的温度 - "top_p": config.GetTyqwTopP(), // 核采样方法的概率阈值 - "top_k": config.GetTyqwTopK(), // 采样候选集的大小 - "repetition_penalty": config.GetTyqwRepetitionPenalty(), // 控制重复度的惩罚因子 - "stop": config.GetTyqwStopTokens(), // 停止标记 - "seed": config.GetTyqwSeed(), // 随机数种子 - "result_format": "message", // 返回结果的格式 - "enable_search": config.GetTyqwEnableSearch(), // 是否启用互联网搜索 - "incremental_output": isIncrementalOutput, // 是否使用增量SSE模式,使用增量模式会更快,rwkv和openai不支持增量模式 + "max_tokens": config.GetTyqwMaxTokens(promptstr), // 最大生成的token数 + "temperature": config.GetTyqwTemperature(promptstr), // 控制随机性和多样性的温度 + "top_p": config.GetTyqwTopP(promptstr), // 核采样方法的概率阈值 + "top_k": config.GetTyqwTopK(promptstr), // 采样候选集的大小 + "repetition_penalty": config.GetTyqwRepetitionPenalty(), // 控制重复度的惩罚因子 + "stop": config.GetTyqwStopTokens(), // 停止标记 + "seed": config.GetTyqwSeed(), // 随机数种子 + "result_format": "message", // 返回结果的格式 + "enable_search": config.GetTyqwEnableSearch(), // 是否启用互联网搜索 + "incremental_output": isIncrementalOutput, // 是否使用增量SSE模式,使用增量模式会更快,rwkv和openai不支持增量模式 }, - "model": config.GetTyqwModel(), // 指定对话模型 + "model": config.GetTyqwModel(promptstr), // 指定对话模型 "input": map[string]interface{}{ "messages": messages, // 用户与模型的对话历史 }, @@ -251,17 +251,17 @@ func (app *App) ChatHandlerTyqw(w http.ResponseWriter, r *http.Request) { // 构建请求体,根据提供的文档重新调整 requestBody = map[string]interface{}{ "parameters": map[string]interface{}{ - "max_tokens": config.GetTyqwMaxTokens(), // 最大生成的token数 - "temperature": config.GetTyqwTemperature(), // 控制随机性和多样性的温度 - "top_p": config.GetTyqwTopP(), // 核采样方法的概率阈值 - "top_k": config.GetTyqwTopK(), // 采样候选集的大小 - "repetition_penalty": config.GetTyqwRepetitionPenalty(), // 控制重复度的惩罚因子 - "stop": config.GetTyqwStopTokens(), // 停止标记 - "seed": config.GetTyqwSeed(), // 随机数种子 - "result_format": "message", // 返回结果的格式 - "enable_search": config.GetTyqwEnableSearch(), // 是否启用互联网搜索 + "max_tokens": config.GetTyqwMaxTokens(promptstr), // 最大生成的token数 + "temperature": config.GetTyqwTemperature(promptstr), // 控制随机性和多样性的温度 + "top_p": config.GetTyqwTopP(promptstr), // 核采样方法的概率阈值 + "top_k": config.GetTyqwTopK(promptstr), // 采样候选集的大小 + "repetition_penalty": config.GetTyqwRepetitionPenalty(), // 控制重复度的惩罚因子 + "stop": config.GetTyqwStopTokens(), // 停止标记 + "seed": config.GetTyqwSeed(), // 随机数种子 + "result_format": "message", // 返回结果的格式 + "enable_search": config.GetTyqwEnableSearch(), // 是否启用互联网搜索 }, - "model": config.GetTyqwModel(), // 指定对话模型 + "model": config.GetTyqwModel(promptstr), // 指定对话模型 "input": map[string]interface{}{ "messages": messages, // 用户与模型的对话历史 }, @@ -402,7 +402,7 @@ func (app *App) ChatHandlerTyqw(w http.ResponseWriter, r *http.Request) { reader := bufio.NewReader(resp.Body) var totalUsage structs.GPTUsageInfo - if config.GetTyqwSseType() == 1 { + if config.GetTyqwSseType(promptstr) == 1 { for { line, err := reader.ReadString('\n') if err != nil { diff --git a/config/config.go b/config/config.go index d3d2704..745d86a 100644 --- a/config/config.go +++ b/config/config.go @@ -2032,14 +2032,38 @@ func GetNo4Promptkeyboard() bool { return false } -// 获取TYQW API路径 -func GetTyqwApiPath() string { +// GetTyqwApiPath 获取TYQW API路径,可接受basename作为参数 +func GetTyqwApiPath(options ...string) string { mu.Lock() defer mu.Unlock() - if instance != nil { - return instance.Settings.TyqwApiPath + return getTyqwApiPathInternal(options...) +} + +// getTyqwApiPathInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用 +func getTyqwApiPathInternal(options ...string) string { + // 检查是否有参数传递进来,以及是否为空字符串 + if len(options) == 0 || options[0] == "" { + if instance != nil { + return instance.Settings.TyqwApiPath + } + return "" // 默认值或错误处理 } - return "" // 默认值或错误处理 + + // 使用传入的 basename + basename := options[0] + apiPathInterface, err := prompt.GetSettingFromFilename(basename, "TyqwApiPath") + if err != nil { + log.Println("Error retrieving TyqwApiPath:", err) + return getTyqwApiPathInternal() // 递归调用内部函数,不传递任何参数 + } + + apiPath, ok := apiPathInterface.(string) + if !ok { // 检查类型断言是否失败 + log.Println("Type assertion failed for TyqwApiPath, fetching default") + return getTyqwApiPathInternal() // 递归调用内部函数,不传递任何参数 + } + + return apiPath } // 获取TYQW最大Token数量,可接受basename作为参数 @@ -2076,44 +2100,140 @@ func getTyqwMaxTokensInternal(options ...string) int { return maxTokens } -// 获取TYQW温度设置 -func GetTyqwTemperature() float64 { +// GetTyqwTemperature 获取TYQW温度设置,可接受basename作为参数 +func GetTyqwTemperature(options ...string) float64 { mu.Lock() defer mu.Unlock() - if instance != nil { - return instance.Settings.TyqwTemperature + return getTyqwTemperatureInternal(options...) +} + +// getTyqwTemperatureInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用 +func getTyqwTemperatureInternal(options ...string) float64 { + // 检查是否有参数传递进来,以及是否为空字符串 + if len(options) == 0 || options[0] == "" { + if instance != nil { + return instance.Settings.TyqwTemperature + } + return 0.0 // 默认值或错误处理 } - return 0.0 // 默认值或错误处理 + + // 使用传入的 basename + basename := options[0] + temperatureInterface, err := prompt.GetSettingFromFilename(basename, "TyqwTemperature") + if err != nil { + log.Println("Error retrieving TyqwTemperature:", err) + return getTyqwTemperatureInternal() // 递归调用内部函数,不传递任何参数 + } + + temperature, ok := temperatureInterface.(float64) + if !ok { // 检查类型断言是否失败 + log.Println("Type assertion failed for TyqwTemperature, fetching default") + return getTyqwTemperatureInternal() // 递归调用内部函数,不传递任何参数 + } + + return temperature } -// 获取TYQW Top P -func GetTyqwTopP() float64 { +// GetTyqwTopP 获取TYQW Top P值,可接受basename作为参数 +func GetTyqwTopP(options ...string) float64 { mu.Lock() defer mu.Unlock() - if instance != nil { - return instance.Settings.TyqwTopP + return getTyqwTopPInternal(options...) +} + +// getTyqwTopPInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用 +func getTyqwTopPInternal(options ...string) float64 { + // 检查是否有参数传递进来,以及是否为空字符串 + if len(options) == 0 || options[0] == "" { + if instance != nil { + return instance.Settings.TyqwTopP + } + return 0.0 // 默认值或错误处理 } - return 0.0 // 默认值或错误处理 + + // 使用传入的 basename + basename := options[0] + topPInterface, err := prompt.GetSettingFromFilename(basename, "TyqwTopP") + if err != nil { + log.Println("Error retrieving TyqwTopP:", err) + return getTyqwTopPInternal() // 递归调用内部函数,不传递任何参数 + } + + topP, ok := topPInterface.(float64) + if !ok { // 检查类型断言是否失败 + log.Println("Type assertion failed for TyqwTopP, fetching default") + return getTyqwTopPInternal() // 递归调用内部函数,不传递任何参数 + } + + return topP } -// 获取TYQW Top K -func GetTyqwTopK() int { +// GetTyqwTopK 获取TYQW Top K设置,可接受basename作为参数 +func GetTyqwTopK(options ...string) int { mu.Lock() defer mu.Unlock() - if instance != nil { - return instance.Settings.TyqwTopK + return getTyqwTopKInternal(options...) +} + +// getTyqwTopKInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用 +func getTyqwTopKInternal(options ...string) int { + // 检查是否有参数传递进来,以及是否为空字符串 + if len(options) == 0 || options[0] == "" { + if instance != nil { + return instance.Settings.TyqwTopK + } + return 0 // 默认值或错误处理 } - return 0 // 默认值或错误处理 + + // 使用传入的 basename + basename := options[0] + topKInterface, err := prompt.GetSettingFromFilename(basename, "TyqwTopK") + if err != nil { + log.Println("Error retrieving TyqwTopK:", err) + return getTyqwTopKInternal() // 递归调用内部函数,不传递任何参数 + } + + topK, ok := topKInterface.(int) + if !ok { // 检查类型断言是否失败 + log.Println("Type assertion failed for TyqwTopK, fetching default") + return getTyqwTopKInternal() // 递归调用内部函数,不传递任何参数 + } + + return topK } -// 获取TYQW SSE类型 -func GetTyqwSseType() int { +// GetTyqwSseType 获取TYQW SSE类型,可接受basename作为参数 +func GetTyqwSseType(options ...string) int { mu.Lock() defer mu.Unlock() - if instance != nil { - return instance.Settings.TyqwSseType + return getTyqwSseTypeInternal(options...) +} + +// getTyqwSseTypeInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用 +func getTyqwSseTypeInternal(options ...string) int { + // 检查是否有参数传递进来,以及是否为空字符串 + if len(options) == 0 || options[0] == "" { + if instance != nil { + return instance.Settings.TyqwSseType + } + return 0 // 默认值或错误处理 } - return 0 // 默认值或错误处理 + + // 使用传入的 basename + basename := options[0] + sseTypeInterface, err := prompt.GetSettingFromFilename(basename, "TyqwSseType") + if err != nil { + log.Println("Error retrieving TyqwSseType:", err) + return getTyqwSseTypeInternal() // 递归调用内部函数,不传递任何参数 + } + + sseType, ok := sseTypeInterface.(int) + if !ok { // 检查类型断言是否失败 + log.Println("Type assertion failed for TyqwSseType, fetching default") + return getTyqwSseTypeInternal() // 递归调用内部函数,不传递任何参数 + } + + return sseType } // 获取TYQW用户名 @@ -2196,24 +2316,72 @@ func GetTyqwEnableSearch() bool { return false // 默认值或错误处理 } -// 获取TYQW模型名称 -func GetTyqwModel() string { +// GetTyqwModel 获取TYQW模型名称,可接受basename作为参数 +func GetTyqwModel(options ...string) string { mu.Lock() defer mu.Unlock() - if instance != nil { - return instance.Settings.TyqwModel + return getTyqwModelInternal(options...) +} + +// getTyqwModelInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用 +func getTyqwModelInternal(options ...string) string { + // 检查是否有参数传递进来,以及是否为空字符串 + if len(options) == 0 || options[0] == "" { + if instance != nil { + return instance.Settings.TyqwModel + } + return "default-model" // 默认值或错误处理 } - return "default-model" // 默认值或错误处理 + + // 使用传入的 basename + basename := options[0] + modelInterface, err := prompt.GetSettingFromFilename(basename, "TyqwModel") + if err != nil { + log.Println("Error retrieving TyqwModel:", err) + return getTyqwModelInternal() // 递归调用内部函数,不传递任何参数 + } + + model, ok := modelInterface.(string) + if !ok || model == "" { // 检查类型断言是否失败或结果为空字符串 + log.Println("Type assertion failed or empty string for TyqwModel, fetching default") + return getTyqwModelInternal() // 递归调用内部函数,不传递任何参数 + } + + return model } -// 获取TYQW API Key -func GetTyqwKey() string { +// GetTyqwKey 获取TYQW API Key,可接受basename作为参数 +func GetTyqwKey(options ...string) string { mu.Lock() defer mu.Unlock() - if instance != nil { - return instance.Settings.TyqwApiKey + return getTyqwKeyInternal(options...) +} + +// getTyqwKeyInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用 +func getTyqwKeyInternal(options ...string) string { + // 检查是否有参数传递进来,以及是否为空字符串 + if len(options) == 0 || options[0] == "" { + if instance != nil { + return instance.Settings.TyqwApiKey + } + return "" // 默认值或错误处理,表示没有找到有效的API Key + } + + // 使用传入的 basename + basename := options[0] + apiKeyInterface, err := prompt.GetSettingFromFilename(basename, "TyqwApiKey") + if err != nil { + log.Println("Error retrieving TyqwApiKey:", err) + return getTyqwKeyInternal() // 递归调用内部函数,不传递任何参数 + } + + apiKey, ok := apiKeyInterface.(string) + if !ok { // 检查类型断言是否失败 + log.Println("Type assertion failed for TyqwApiKey, fetching default") + return getTyqwKeyInternal() // 递归调用内部函数,不传递任何参数 } - return "" // 默认值或错误处理,表示没有找到有效的API Key + + return apiKey } // 获取TYQW Workspace @@ -2229,34 +2397,106 @@ func GetTyqworkspace() (string, error) { return "", fmt.Errorf("configuration instance is not initialized") // 错误处理,当配置实例未初始化时 } -// GetGlmApiPath 获取GLM API路径 -func GetGlmApiPath() string { +// GetGlmApiPath 获取GLM API路径,可接受basename作为参数 +func GetGlmApiPath(options ...string) string { mu.Lock() defer mu.Unlock() - if instance != nil { - return instance.Settings.GlmApiPath + return getGlmApiPathInternal(options...) +} + +// getGlmApiPathInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用 +func getGlmApiPathInternal(options ...string) string { + // 检查是否有参数传递进来,以及是否为空字符串 + if len(options) == 0 || options[0] == "" { + if instance != nil { + return instance.Settings.GlmApiPath + } + return "" // 默认值或错误处理 } - return "" // 默认值或错误处理 + + // 使用传入的 basename + basename := options[0] + apiPathInterface, err := prompt.GetSettingFromFilename(basename, "GlmApiPath") + if err != nil { + log.Println("Error retrieving GlmApiPath:", err) + return getGlmApiPathInternal() // 递归调用内部函数,不传递任何参数 + } + + apiPath, ok := apiPathInterface.(string) + if !ok { // 检查类型断言是否失败 + log.Println("Type assertion failed for GlmApiPath, fetching default") + return getGlmApiPathInternal() // 递归调用内部函数,不传递任何参数 + } + + return apiPath } -// GetGlmModel 获取模型编码 -func GetGlmModel() string { +// GetGlmModel 获取模型编码,可接受basename作为参数 +func GetGlmModel(options ...string) string { mu.Lock() defer mu.Unlock() - if instance != nil { - return instance.Settings.GlmModel + return getGlmModelInternal(options...) +} + +// getGlmModelInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用 +func getGlmModelInternal(options ...string) string { + // 检查是否有参数传递进来,以及是否为空字符串 + if len(options) == 0 || options[0] == "" { + if instance != nil { + return instance.Settings.GlmModel + } + return "" // 默认值或错误处理 } - return "" + + // 使用传入的 basename + basename := options[0] + modelInterface, err := prompt.GetSettingFromFilename(basename, "GlmModel") + if err != nil { + log.Println("Error retrieving GlmModel:", err) + return getGlmModelInternal() // 递归调用内部函数,不传递任何参数 + } + + model, ok := modelInterface.(string) + if !ok { // 检查类型断言是否失败 + log.Println("Type assertion failed for GlmModel, fetching default") + return getGlmModelInternal() // 递归调用内部函数,不传递任何参数 + } + + return model } -// GetGlmApiKey 获取模型编码 -func GetGlmApiKey() string { +// GetGlmApiKey 获取glm密钥,可接受basename作为参数 +func GetGlmApiKey(options ...string) string { mu.Lock() defer mu.Unlock() - if instance != nil { - return instance.Settings.GlmApiKey + return getGlmApiKeyInternal(options...) +} + +// getGlmApiKeyInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用 +func getGlmApiKeyInternal(options ...string) string { + // 检查是否有参数传递进来,以及是否为空字符串 + if len(options) == 0 || options[0] == "" { + if instance != nil { + return instance.Settings.GlmApiKey + } + return "" // 默认值或错误处理 } - return "" + + // 使用传入的 basename + basename := options[0] + apiKeyInterface, err := prompt.GetSettingFromFilename(basename, "GlmApiKey") + if err != nil { + log.Println("Error retrieving GlmApiKey:", err) + return getGlmApiKeyInternal() // 递归调用内部函数,不传递任何参数 + } + + apiKey, ok := apiKeyInterface.(string) + if !ok { // 检查类型断言是否失败 + log.Println("Type assertion failed for GlmApiKey, fetching default") + return getGlmApiKeyInternal() // 递归调用内部函数,不传递任何参数 + } + + return apiKey } // GetGlmMaxTokens 获取模型输出的最大tokens数,可接受basename作为参数 @@ -2293,14 +2533,38 @@ func getGlmMaxTokensInternal(options ...string) int { return maxTokens } -// GetGlmTemperature 获取模型的采样温度 -func GetGlmTemperature() float64 { +// GetGlmTemperature 获取模型的采样温度,可接受basename作为参数 +func GetGlmTemperature(options ...string) float64 { mu.Lock() defer mu.Unlock() - if instance != nil { - return instance.Settings.GlmTemperature + return getGlmTemperatureInternal(options...) +} + +// getGlmTemperatureInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用 +func getGlmTemperatureInternal(options ...string) float64 { + // 检查是否有参数传递进来,以及是否为空字符串 + if len(options) == 0 || options[0] == "" { + if instance != nil { + return instance.Settings.GlmTemperature + } + return 0.95 // 默认值或错误处理 + } + + // 使用传入的 basename + basename := options[0] + temperatureInterface, err := prompt.GetSettingFromFilename(basename, "GlmTemperature") + if err != nil { + log.Println("Error retrieving GlmTemperature:", err) + return getGlmTemperatureInternal() // 递归调用内部函数,不传递任何参数 + } + + temperature, ok := temperatureInterface.(float64) + if !ok { // 检查类型断言是否失败 + log.Println("Type assertion failed for GlmTemperature, fetching default") + return getGlmTemperatureInternal() // 递归调用内部函数,不传递任何参数 } - return 0.95 // 返回默认值 + + return temperature } // GetGlmDoSample 获取是否启用采样策略 @@ -2343,14 +2607,38 @@ func GetGlmRequestID() string { return "" // 返回默认值,表示没有设置 } -// GetGlmTopP 获取核取样概率 -func GetGlmTopP() float64 { +// GetGlmTopP 获取核取样概率,可接受basename作为参数 +func GetGlmTopP(options ...string) float64 { mu.Lock() defer mu.Unlock() - if instance != nil { - return instance.Settings.GlmTopP + return getGlmTopPInternal(options...) +} + +// getGlmTopPInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用 +func getGlmTopPInternal(options ...string) float64 { + // 检查是否有参数传递进来,以及是否为空字符串 + if len(options) == 0 || options[0] == "" { + if instance != nil { + return instance.Settings.GlmTopP + } + return 0.7 // 默认值或错误处理 + } + + // 使用传入的 basename + basename := options[0] + topPInterface, err := prompt.GetSettingFromFilename(basename, "GlmTopP") + if err != nil { + log.Println("Error retrieving GlmTopP:", err) + return getGlmTopPInternal() // 递归调用内部函数,不传递任何参数 + } + + topP, ok := topPInterface.(float64) + if !ok { // 检查类型断言是否失败 + log.Println("Type assertion failed for GlmTopP, fetching default") + return getGlmTopPInternal() // 递归调用内部函数,不传递任何参数 } - return 0.7 // 返回默认值 + + return topP } // GetGlmStop 获取停止生成的词列表 @@ -2373,12 +2661,36 @@ func GetGlmTools() []string { return []string{} // 返回空切片,表示没有工具设置 } -// 获取GroupHintWords列表 -func GetGroupHintWords() []string { +// GetGroupHintWords 获取GroupHintWords列表,可接受basename作为参数 +func GetGroupHintWords(options ...string) []string { mu.Lock() defer mu.Unlock() - if instance != nil { - return instance.Settings.GroupHintWords + return getGroupHintWordsInternal(options...) +} + +// getGroupHintWordsInternal 内部逻辑执行函数,不处理锁,可以安全地递归调用 +func getGroupHintWordsInternal(options ...string) []string { + // 检查是否有参数传递进来,以及是否为空字符串 + if len(options) == 0 || options[0] == "" { + if instance != nil { + return instance.Settings.GroupHintWords + } + return nil // 默认值或错误处理 } - return nil + + // 使用传入的 basename + basename := options[0] + hintWordsInterface, err := prompt.GetSettingFromFilename(basename, "GroupHintWords") + if err != nil { + log.Println("Error retrieving GroupHintWords:", err) + return getGroupHintWordsInternal() // 递归调用内部函数,不传递任何参数 + } + + hintWords, ok := hintWordsInterface.([]string) + if !ok { // 检查类型断言是否失败 + log.Println("Type assertion failed for GroupHintWords, fetching default") + return getGroupHintWordsInternal() // 递归调用内部函数,不传递任何参数 + } + + return hintWords } diff --git a/utils/blacklist.go b/utils/blacklist.go index 6d3b1f2..77b1aea 100644 --- a/utils/blacklist.go +++ b/utils/blacklist.go @@ -94,6 +94,26 @@ func WatchBlacklist(filePath string) { // BlacklistIntercept 检查用户ID是否在黑名单中,如果在,则发送预设消息 func BlacklistIntercept(message structs.OnebotGroupMessage, selfid string) bool { + // 检查群ID是否在黑名单中 + if IsInBlacklist(strconv.FormatInt(message.GroupID, 10)) { + // 获取黑名单响应消息 + responseMessage := config.GetBlacklistResponseMessages() + + // 根据消息类型发送响应 + if message.RealMessageType == "group_private" || message.MessageType == "private" { + if !config.GetUsePrivateSSE() { + SendPrivateMessage(message.UserID, responseMessage, selfid) + } else { + SendSSEPrivateMessage(message.UserID, responseMessage) + } + } else { + SendGroupMessage(message.GroupID, message.UserID, responseMessage, selfid) + } + + fmt.Printf("groupid:[%v]这个群在黑名单中,被拦截\n", message.GroupID) + return true // 拦截 + } + // 检查用户ID是否在黑名单中 if IsInBlacklist(strconv.FormatInt(message.UserID, 10)) { // 获取黑名单响应消息 @@ -113,5 +133,6 @@ func BlacklistIntercept(message structs.OnebotGroupMessage, selfid string) bool fmt.Printf("userid:[%v]这位用户在黑名单中,被拦截\n", message.UserID) return true // 拦截 } + return false // 用户ID不在黑名单中,不拦截 }