From cdb74588b2911a7e096f2bd323d2b0539f97f330 Mon Sep 17 00:00:00 2001 From: liyp Date: Sun, 30 Jun 2024 16:12:26 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E9=87=8D=E6=9E=84=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E6=96=B9=E5=BC=8F=E5=B9=B6=E5=BC=95=E5=85=A5?= =?UTF-8?q?sync.Once=E7=A1=AE=E4=BF=9D=E5=8D=95=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将配置加载逻辑从全局变量改为使用sync.Once确保单例模式, 优化了config包的结构,现在通过GetConfig方法来获取配置, 而不是直接访问全局变量。这种方式更加线程安全,并且 允许未来在不同包中异步加载配置而无需担心初始化顺序问题。 BREAKING CHANGE: 现在必须使用config.GetConfig()来获取配置, 而不是直接访问config.GlobalConfig。这可能需要更新任何 依赖于GlobalConfig的代码。 --- config/config.go | 37 +++++++++++++------------------------ main.go | 8 +++++++- workers/core.go | 18 ++++++++++++------ 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/config/config.go b/config/config.go index 9a61d11..945f063 100644 --- a/config/config.go +++ b/config/config.go @@ -1,35 +1,24 @@ package config import ( - "log" + "sync" "github.com/BurntSushi/toml" ) -type Config struct { - Server struct { - APIURL string - POSTURL string - } - Group struct { - AllowGroup []string - AllowUser []string - AllowRole []string - BlockGroup []string - BlockUser []string - GroupNotAllow []string - UserNotAllow []string - RoleNotAllow []string - } -} +var ( + config map[string]interface{} + once sync.Once +) -var GlobalConfig Config +func loadConfig() { -func init() { - // var config Config - if _, err := toml.DecodeFile("config.toml", &GlobalConfig); err != nil { - println("配置文件不正确,请修改正确的配置文件!") - log.Fatal(err) + if _, err := toml.DecodeFile("config.toml", &config); err != nil { + panic(err) } - // fmt.Println(config.Group) + +} +func GetConfig() map[string]interface{} { + once.Do(loadConfig) + return config } diff --git a/main.go b/main.go index 94a1c6c..39d8ba3 100644 --- a/main.go +++ b/main.go @@ -114,7 +114,13 @@ func handlePost(w http.ResponseWriter, r *http.Request) { } func main() { - APIURL := config.GlobalConfig.Server.APIURL + // var config map[string]interface{} + // if _, err := toml.DecodeFile("config.toml", &config); err != nil { + // println("配置文件不正确,请修改正确的配置文件!") + // log.Fatal(err) + // } + cfg := config.GetConfig() + APIURL := cfg["APIURL"].(string) // PORT := config.GlobalConfig.Server.Port // fmt.Println(APIURL) diff --git a/workers/core.go b/workers/core.go index 110af79..8c51662 100644 --- a/workers/core.go +++ b/workers/core.go @@ -25,7 +25,13 @@ type StdAns struct { RawMsg string } +var cfg map[string]interface{} + +func init() { + cfg = config.GetConfig() +} func NewStdAns(parms []string, uid, gid, role, mid, rawMsg string) *StdAns { + return &StdAns{ Parms: parms, UID: uid, @@ -33,11 +39,11 @@ func NewStdAns(parms []string, uid, gid, role, mid, rawMsg string) *StdAns { Role: role, MID: mid, RawMsg: rawMsg, - AllowGroup: config.GlobalConfig.Group.AllowGroup, - AllowUser: config.GlobalConfig.Group.AllowUser, - AllowRole: config.GlobalConfig.Group.AllowRole, - BlockGroup: config.GlobalConfig.Group.BlockGroup, - BlockUser: config.GlobalConfig.Group.BlockUser, + AllowGroup: cfg["AllowGroup"].([]string), + AllowUser: cfg["AllowUser"].([]string), + AllowRole: cfg["AllowRole"].([]string), + BlockGroup: cfg["BlockGroup"].([]string), + BlockUser: cfg["BlockUser"].([]string), GroupNotAllow: "汝所在的群组不被允许这样命令咱呢.", UserNotAllow: "汝不被允许呢.", RoleNotAllow: "汝的角色不被允许哦.", @@ -99,7 +105,7 @@ func (s *StdAns) SendMsg(msg string) bool { } // fmt.Println(string(re)) - url := config.GlobalConfig.Server.POSTURL + url := cfg["POSTURL"].(string) // println("core:", url) // fmt.Println("请求地址:", url) fmt.Println("响应信息:\n", msg) From 13483b964324065fd493175dd5db11329a51750f Mon Sep 17 00:00:00 2001 From: liyp Date: Sun, 30 Jun 2024 21:56:34 +0800 Subject: [PATCH 2/6] =?UTF-8?q?feat(config):=20=E6=B7=BB=E5=8A=A0OpenAI=20?= =?UTF-8?q?API=E9=85=8D=E7=BD=AE=E5=B9=B6=E4=BC=98=E5=8C=96=E6=89=93?= =?UTF-8?q?=E5=8D=B0=E9=85=8D=E7=BD=AE=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在config.toml中添加了OPENAI_API_KEY、OPENAI_BaseURL和MODEL配置项,以支持OpenAI API的集成。 同时,优化了PrintConfig函数,使其能够递归打印嵌套的配置结构,提高了配置管理的可读性和易用性。 --- config/config.go | 26 +++++++++++++++ go.mod | 7 ++++ go.sum | 8 +++++ main.go | 11 ++----- test/test.go | 7 ++-- workers/ai.go | 78 ++++++++++++++++++++++++++++++++++++++++++++ workers/core.go | 31 ++++++++++-------- workers/lsp.go | 2 +- workers/newworker.go | 5 +++ 9 files changed, 150 insertions(+), 25 deletions(-) create mode 100644 workers/ai.go diff --git a/config/config.go b/config/config.go index 945f063..af01f86 100644 --- a/config/config.go +++ b/config/config.go @@ -1,6 +1,8 @@ package config import ( + "fmt" + "reflect" "sync" "github.com/BurntSushi/toml" @@ -20,5 +22,29 @@ func loadConfig() { } func GetConfig() map[string]interface{} { once.Do(loadConfig) + // print(config) return config } + +func PrintConfig(m map[string]interface{}, indent string) { + for key, value := range m { + switch v := value.(type) { + case map[string]interface{}: + fmt.Printf("%s%s (type: %s):\n", indent, key, reflect.TypeOf(v)) + PrintConfig(v, indent+" ") + case []interface{}: + fmt.Printf("%s%s:\n", indent, key) + for i, item := range v { + switch itemValue := item.(type) { + case map[string]interface{}: + fmt.Printf("%s [%d] (type: %s):\n", indent, i, reflect.TypeOf(itemValue)) + PrintConfig(itemValue, indent+" ") + default: + fmt.Printf("%s [%d] (type: %s): %v\n", indent, i, reflect.TypeOf(itemValue), item) + } + } + default: + fmt.Printf("%s%s (type: %s): %v\n", indent, key, reflect.TypeOf(value), value) + } + } +} diff --git a/go.mod b/go.mod index 91eeedc..c133698 100644 --- a/go.mod +++ b/go.mod @@ -8,3 +8,10 @@ require ( github.com/goccy/go-json v0.10.2 github.com/mattn/go-sqlite3 v1.14.22 ) + +require ( + github.com/moul/http2curl v1.0.0 // indirect + github.com/parnurzeal/gorequest v0.3.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + golang.org/x/net v0.26.0 // indirect +) diff --git a/go.sum b/go.sum index fa68fcb..665bca3 100644 --- a/go.sum +++ b/go.sum @@ -6,5 +6,13 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/ github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/parnurzeal/gorequest v0.3.0 h1:SoFyqCDC9COr1xuS6VA8fC8RU7XyrJZN2ona1kEX7FI= +github.com/parnurzeal/gorequest v0.3.0/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= diff --git a/main.go b/main.go index 39d8ba3..2820249 100644 --- a/main.go +++ b/main.go @@ -114,17 +114,12 @@ func handlePost(w http.ResponseWriter, r *http.Request) { } func main() { - // var config map[string]interface{} - // if _, err := toml.DecodeFile("config.toml", &config); err != nil { - // println("配置文件不正确,请修改正确的配置文件!") - // log.Fatal(err) - // } + cfg := config.GetConfig() APIURL := cfg["APIURL"].(string) + // config.PrintConfig(cfg, "") + // print(cfg["AllowGroup"].([]interface{})[0].(string)) - // PORT := config.GlobalConfig.Server.Port - // fmt.Println(APIURL) - // fmt.Println(PORT) http.HandleFunc("/", handlePost) // 协程支持 // http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { diff --git a/test/test.go b/test/test.go index 236bd51..e8d1c0b 100644 --- a/test/test.go +++ b/test/test.go @@ -11,12 +11,15 @@ import ( func main() { for { reader := bufio.NewReader(os.Stdin) - + // cfg := config.GetConfig() + // config.PrintConfig(cfg, "") fmt.Print("输入指令(不要带/):") raw_msg, _ := reader.ReadString('\n') // 去除末尾的换行符 // raw_msg = strings.TrimRight(raw_msg, "\r\n") - + if raw_msg == "" { + raw_msg = "ping" + } parms := strings.Fields(raw_msg) worker := workers.NewWorker(parms, "11", "111", "111", "222", raw_msg) diff --git a/workers/ai.go b/workers/ai.go new file mode 100644 index 0000000..457b2fe --- /dev/null +++ b/workers/ai.go @@ -0,0 +1,78 @@ +package workers + +import ( + "log" + + "github.com/goccy/go-json" + "github.com/parnurzeal/gorequest" +) + +type AI struct { + *StdAns +} + +func (a *AI) GetMsg() string { + if len(a.Parms) < 2 { + return "使用!ai xxx 向我提问吧" + + } + var msg string + var OPENAI_API_KEY string + if cfg["OPENAI_API_KEY"] != nil { + OPENAI_API_KEY = cfg["OPENAI_API_KEY"].(string) + } else { + log.Println("OPENAI_API_KEY 未配置") + return "OPENAI_API_KEY 未配置" + } + var OPENAI_BaseURL string + if cfg["OPENAI_BaseURL"] != nil { + OPENAI_BaseURL = cfg["OPENAI_BaseURL"].(string) + } else { + log.Println("OPENAI_BaseURL 未配置,使用openai默认配置") + OPENAI_BaseURL = "https://api.openai.com/v1/chat/completions" + } + var MODEL string + if cfg["MODEL"] != nil { + MODEL = cfg["MODEL"].(string) + } else { + log.Println("模型 未配置,使用默认chatglm_pro模型") + MODEL = "chatglm_pro" + } + ask := a.Parms[1] + if ask == "" { + return "不问问题你说个屁!" + } + requestBody := map[string]interface{}{ + "model": MODEL, + "messages": []map[string]string{{"role": "user", "content": ask}}, + "temperature": 0.7, + } + request := gorequest.New() + resp, body, errs := request.Post(OPENAI_BaseURL). + Set("Content-Type", "application/json"). + Set("Authorization", "Bearer "+OPENAI_API_KEY). + Send(requestBody). + End() + if errs != nil { + log.Println(errs) + return "请求失败" + } else { + if resp.StatusCode == 200 { + var responseBody map[string]interface{} + if err := json.Unmarshal([]byte(body), &responseBody); err != nil { + log.Println(err) + return "解析失败" + } + choices := responseBody["choices"].([]interface{}) + if len(choices) > 0 { + choice := choices[0].(map[string]interface{}) + msg = choice["message"].(map[string]interface{})["content"].(string) + } else { + log.Println("choices为空") + } + } + } + + return msg + +} diff --git a/workers/core.go b/workers/core.go index 8c51662..23842fd 100644 --- a/workers/core.go +++ b/workers/core.go @@ -9,11 +9,11 @@ import ( ) type StdAns struct { - AllowGroup []string - AllowUser []string - AllowRole []string - BlockGroup []string - BlockUser []string + AllowGroup []interface{} + AllowUser []interface{} + AllowRole []interface{} + BlockGroup []interface{} + BlockUser []interface{} GroupNotAllow string UserNotAllow string RoleNotAllow string @@ -27,11 +27,14 @@ type StdAns struct { var cfg map[string]interface{} -func init() { - cfg = config.GetConfig() -} +// func init() { +// cfg = config.GetConfig() +// } func NewStdAns(parms []string, uid, gid, role, mid, rawMsg string) *StdAns { + // var cfg map[string]interface{} + cfg = config.GetConfig() + // println("AllowGroup:", cfg["AllowGroup"].([]interface{})) return &StdAns{ Parms: parms, UID: uid, @@ -39,11 +42,11 @@ func NewStdAns(parms []string, uid, gid, role, mid, rawMsg string) *StdAns { Role: role, MID: mid, RawMsg: rawMsg, - AllowGroup: cfg["AllowGroup"].([]string), - AllowUser: cfg["AllowUser"].([]string), - AllowRole: cfg["AllowRole"].([]string), - BlockGroup: cfg["BlockGroup"].([]string), - BlockUser: cfg["BlockUser"].([]string), + AllowGroup: cfg["AllowGroup"].([]interface{}), + AllowUser: cfg["AllowUser"].([]interface{}), + AllowRole: cfg["AllowRole"].([]interface{}), + BlockGroup: cfg["BlockGroup"].([]interface{}), + BlockUser: cfg["BlockUser"].([]interface{}), GroupNotAllow: "汝所在的群组不被允许这样命令咱呢.", UserNotAllow: "汝不被允许呢.", RoleNotAllow: "汝的角色不被允许哦.", @@ -62,7 +65,7 @@ func (s *StdAns) CheckPermission() string { } return "0" } -func contains(slice []string, value string) bool { +func contains(slice []interface{}, value string) bool { for _, item := range slice { if item == value { return true diff --git a/workers/lsp.go b/workers/lsp.go index 0255b5b..0845549 100644 --- a/workers/lsp.go +++ b/workers/lsp.go @@ -14,7 +14,7 @@ type Lsp struct { } func (a *Lsp) GetMsg() string { - a.AllowGroup = []string{"313047773"} + a.AllowGroup = append(a.AllowGroup, []string{"313047773"}) url := "https://api.lolicon.app/setu/v2?r18=0&size=small" resp, err := http.Get(url) if err != nil { diff --git a/workers/newworker.go b/workers/newworker.go index 9992d51..516b267 100644 --- a/workers/newworker.go +++ b/workers/newworker.go @@ -5,6 +5,7 @@ import "fmt" func NewWorker(parms []string, uid, gid, role, mid, rawMsg string) Worker { fmt.Println("NewWorker:", parms) switch parms[0] { + case "ping": return &Ping{ StdAns: NewStdAns(parms, uid, gid, role, mid, rawMsg), @@ -26,6 +27,10 @@ func NewWorker(parms []string, uid, gid, role, mid, rawMsg string) Worker { return &Lsp{ StdAns: NewStdAns(parms, uid, gid, role, mid, rawMsg), } + case "ai": + return &AI{ + StdAns: NewStdAns(parms, uid, gid, role, mid, rawMsg), + } default: return &Emm{ StdAns: NewStdAns(parms, uid, gid, role, mid, rawMsg)} From be83757074cfe8a7648cb6c77bc00c42e54e8969 Mon Sep 17 00:00:00 2001 From: liyp Date: Sun, 30 Jun 2024 23:34:00 +0800 Subject: [PATCH 3/6] =?UTF-8?q?feat(workers):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=AF=B9OpenAI=E6=A8=A1=E5=9E=8B=E5=88=97=E8=A1=A8=E7=9A=84?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 向AI工作者添加了查询OpenAI支持模型列表的功能。当用户输入特定的 命令时,AI将返回可用模型的列表。这增强了AI的实用性并为用户提供 了更多资源的信息。 同时,对配置加载方式进行了优化,确保了配置的正确性和系统的稳定性。 还对AI的响应消息进行了改进,增加了语言的灵活性和友好性。 BREAKING CHANGE: 配置文件格式有所更改,新增了PROMPT配置项,并调整了 APIURL和MODEL的配置。需要更新配置文件以适配这些变化。 --- main.go | 5 ++- workers/ai.go | 109 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 82 insertions(+), 32 deletions(-) diff --git a/main.go b/main.go index 2820249..99d992b 100644 --- a/main.go +++ b/main.go @@ -116,7 +116,10 @@ func handlePost(w http.ResponseWriter, r *http.Request) { func main() { cfg := config.GetConfig() - APIURL := cfg["APIURL"].(string) + APIURL, ok := cfg["APIURL"].(string) + if !ok { + log.Fatal("加载配置失败!") + } // config.PrintConfig(cfg, "") // print(cfg["AllowGroup"].([]interface{})[0].(string)) diff --git a/workers/ai.go b/workers/ai.go index 457b2fe..382a1e5 100644 --- a/workers/ai.go +++ b/workers/ai.go @@ -2,6 +2,7 @@ package workers import ( "log" + "strings" "github.com/goccy/go-json" "github.com/parnurzeal/gorequest" @@ -16,6 +17,10 @@ func (a *AI) GetMsg() string { return "使用!ai xxx 向我提问吧" } + ask := a.Parms[1] + if ask == "" { + return "不问问题你说个屁!" + } var msg string var OPENAI_API_KEY string if cfg["OPENAI_API_KEY"] != nil { @@ -29,7 +34,7 @@ func (a *AI) GetMsg() string { OPENAI_BaseURL = cfg["OPENAI_BaseURL"].(string) } else { log.Println("OPENAI_BaseURL 未配置,使用openai默认配置") - OPENAI_BaseURL = "https://api.openai.com/v1/chat/completions" + OPENAI_BaseURL = "https://api.openai.com/v1" } var MODEL string if cfg["MODEL"] != nil { @@ -38,37 +43,79 @@ func (a *AI) GetMsg() string { log.Println("模型 未配置,使用默认chatglm_pro模型") MODEL = "chatglm_pro" } - ask := a.Parms[1] - if ask == "" { - return "不问问题你说个屁!" - } - requestBody := map[string]interface{}{ - "model": MODEL, - "messages": []map[string]string{{"role": "user", "content": ask}}, - "temperature": 0.7, - } - request := gorequest.New() - resp, body, errs := request.Post(OPENAI_BaseURL). - Set("Content-Type", "application/json"). - Set("Authorization", "Bearer "+OPENAI_API_KEY). - Send(requestBody). - End() - if errs != nil { - log.Println(errs) - return "请求失败" - } else { - if resp.StatusCode == 200 { - var responseBody map[string]interface{} - if err := json.Unmarshal([]byte(body), &responseBody); err != nil { - log.Println(err) - return "解析失败" - } - choices := responseBody["choices"].([]interface{}) - if len(choices) > 0 { - choice := choices[0].(map[string]interface{}) - msg = choice["message"].(map[string]interface{})["content"].(string) + + if strings.ToLower(a.Parms[1]) == "models" { + OPENAI_BaseURL = OPENAI_BaseURL + "/models" + request := gorequest.New() + resp, body, errs := request.Get(OPENAI_BaseURL). + Set("Content-Type", "application/json"). + Set("Authorization", "Bearer "+OPENAI_API_KEY). + End() + if errs != nil { + log.Println(errs) + return "请求失败" + } else { + if resp.StatusCode == 200 { + var responseBody map[string]interface{} + if err := json.Unmarshal([]byte(body), &responseBody); err != nil { + log.Println(err) + return "解析模型列表失败" + } + choices := responseBody["data"].([]interface{}) + if len(choices) > 0 { + msg = "支持的模型列表:\n" + for _, choice := range choices { + msg = msg + choice.(map[string]interface{})["id"].(string) + "\n" + } + } else { + msg = "没查到支持模型列表" + } + return msg } else { - log.Println("choices为空") + log.Println("请求失败") + return "请求模型列表失败" + } + } + } else { + OPENAI_BaseURL = OPENAI_BaseURL + "/chat/completions" + PROMPT, ok := cfg["PROMPT"].(string) + if !ok { + log.Println("PROMRT 未配置") + PROMPT = "" + } + println("PROMPT:", PROMPT) + requestBody := map[string]interface{}{ + "model": MODEL, + "messages": []map[string]string{{ + "role": "system", + "content": PROMPT, + }, + {"role": "user", "content": ask}}, + "temperature": 0.7, + } + request := gorequest.New() + resp, body, errs := request.Post(OPENAI_BaseURL). + Set("Content-Type", "application/json"). + Set("Authorization", "Bearer "+OPENAI_API_KEY). + Send(requestBody). + End() + if errs != nil { + log.Println(errs) + return "请求失败" + } else { + if resp.StatusCode == 200 { + var responseBody map[string]interface{} + if err := json.Unmarshal([]byte(body), &responseBody); err != nil { + log.Println(err) + return "解析失败" + } + choices := responseBody["choices"].([]interface{}) + if len(choices) > 0 { + choice := choices[0].(map[string]interface{}) + msg = choice["message"].(map[string]interface{})["content"].(string) + } else { + log.Println("choices为空") + } } } } From 21296b7878476c6b0889785d6e2e5c29e5e86136 Mon Sep 17 00:00:00 2001 From: liyp Date: Sun, 30 Jun 2024 23:36:17 +0800 Subject: [PATCH 4/6] =?UTF-8?q?refactor(workers):=20=E4=BC=98=E5=8C=96AI?= =?UTF-8?q?=E5=92=8CLSP=E5=B7=A5=E4=BD=9C=E8=80=85=E7=9A=84=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E5=A4=84=E7=90=86=E5=92=8C=E6=97=A5=E5=BF=97=E8=BE=93?= =?UTF-8?q?=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- workers/ai.go | 2 +- workers/lsp.go | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/workers/ai.go b/workers/ai.go index 382a1e5..4abacac 100644 --- a/workers/ai.go +++ b/workers/ai.go @@ -83,7 +83,7 @@ func (a *AI) GetMsg() string { log.Println("PROMRT 未配置") PROMPT = "" } - println("PROMPT:", PROMPT) + // println("PROMPT:", PROMPT) requestBody := map[string]interface{}{ "model": MODEL, "messages": []map[string]string{{ diff --git a/workers/lsp.go b/workers/lsp.go index 0845549..ebd1ea5 100644 --- a/workers/lsp.go +++ b/workers/lsp.go @@ -18,10 +18,13 @@ func (a *Lsp) GetMsg() string { url := "https://api.lolicon.app/setu/v2?r18=0&size=small" resp, err := http.Get(url) if err != nil { - return "获取失败" + return "请求图片失败" } defer resp.Body.Close() budy, err := io.ReadAll(resp.Body) + if err != nil { + return "读取失败" + } var res map[string]interface{} err = json.Unmarshal(budy, &res) if err != nil { From eedb68a282cf5bd9a24687f5dd54f338fd8efa2a Mon Sep 17 00:00:00 2001 From: liyp Date: Mon, 1 Jul 2024 00:26:26 +0800 Subject: [PATCH 5/6] =?UTF-8?q?feat(workers):=20=E6=94=B9=E8=BF=9BAI?= =?UTF-8?q?=E5=9B=9E=E5=A4=8D=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- config example.toml | 3 +-- workers/ai.go | 12 ++++++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 2666aab..96107ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ data.db test.json +*.exe + config.toml -*.exe \ No newline at end of file diff --git a/config example.toml b/config example.toml index fc3a200..13f6038 100644 --- a/config example.toml +++ b/config example.toml @@ -1,8 +1,7 @@ -[Server] APIURL = "0.0.0.0:5580" POSTURL = "http://0.0.0.0:5700" -[Group] + AllowGroup = [] AllowUser = [] AllowRole = [] diff --git a/workers/ai.go b/workers/ai.go index 4abacac..45dbf9c 100644 --- a/workers/ai.go +++ b/workers/ai.go @@ -65,7 +65,13 @@ func (a *AI) GetMsg() string { if len(choices) > 0 { msg = "支持的模型列表:\n" for _, choice := range choices { - msg = msg + choice.(map[string]interface{})["id"].(string) + "\n" + models := choice.(map[string]interface{})["id"].(string) + if models == MODEL { + msg = msg + models + "\t ✔\n" + } else { + msg = msg + models + "\n" + } + } } else { msg = "没查到支持模型列表" @@ -85,12 +91,14 @@ func (a *AI) GetMsg() string { } // println("PROMPT:", PROMPT) requestBody := map[string]interface{}{ - "model": MODEL, + "model": MODEL, + "stream": false, "messages": []map[string]string{{ "role": "system", "content": PROMPT, }, {"role": "user", "content": ask}}, + "max_tokens": 75, "temperature": 0.7, } request := gorequest.New() From 8ca0d2797639c74063f70c2a66670655c89ece77 Mon Sep 17 00:00:00 2001 From: liyp Date: Mon, 1 Jul 2024 10:05:42 +0800 Subject: [PATCH 6/6] =?UTF-8?q?feat(config):=20=E5=8A=A8=E6=80=81=E4=BF=AE?= =?UTF-8?q?=E6=94=B9AI=E6=A8=A1=E5=9E=8B=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 通过新增的ModifyConfig函数,现在可以在运行时动态修改AI的配置,包括更换模型。 --- config/config.go | 33 +++++++++++++++++++++++++++++++-- test/test.go | 4 ++-- workers/ai.go | 43 ++++++++++++++++++++++++++++++++++--------- workers/core.go | 2 +- 4 files changed, 68 insertions(+), 14 deletions(-) diff --git a/config/config.go b/config/config.go index af01f86..f989a22 100644 --- a/config/config.go +++ b/config/config.go @@ -2,6 +2,7 @@ package config import ( "fmt" + "os" "reflect" "sync" @@ -10,10 +11,12 @@ import ( var ( config map[string]interface{} - once sync.Once + mu sync.Mutex ) func loadConfig() { + mu.Lock() + defer mu.Unlock() if _, err := toml.DecodeFile("config.toml", &config); err != nil { panic(err) @@ -21,10 +24,36 @@ func loadConfig() { } func GetConfig() map[string]interface{} { - once.Do(loadConfig) + // mu.Lock() + // defer mu.Unlock() // print(config) + if config == nil { + loadConfig() + } return config } +func ReloadConfig() { + loadConfig() +} +func ModifyConfig(key string, value interface{}) { + mu.Lock() + defer mu.Unlock() + + // 修改配置 + config[key] = value + // fmt.Println("修改后的配置:") + // 将修改后的配置写回文件 + file, err := os.Create("config.toml") + if err != nil { + panic(err) + } + defer file.Close() + + encoder := toml.NewEncoder(file) + if err := encoder.Encode(config); err != nil { + panic(err) + } +} func PrintConfig(m map[string]interface{}, indent string) { for key, value := range m { diff --git a/test/test.go b/test/test.go index e8d1c0b..0d1618e 100644 --- a/test/test.go +++ b/test/test.go @@ -22,8 +22,8 @@ func main() { } parms := strings.Fields(raw_msg) - worker := workers.NewWorker(parms, "11", "111", "111", "222", raw_msg) - fmt.Println("Test:", worker.CheckPermission()) + worker := workers.NewWorker(parms, "794508986", "111", "111", "222", raw_msg) + fmt.Println("TestPermission:", worker.CheckPermission()) message := worker.GetMsg() fmt.Println("message:", message) diff --git a/workers/ai.go b/workers/ai.go index 45dbf9c..a6426c8 100644 --- a/workers/ai.go +++ b/workers/ai.go @@ -1,6 +1,7 @@ package workers import ( + "go-bot/config" "log" "strings" @@ -45,6 +46,7 @@ func (a *AI) GetMsg() string { } if strings.ToLower(a.Parms[1]) == "models" { + OPENAI_BaseURL = OPENAI_BaseURL + "/models" request := gorequest.New() resp, body, errs := request.Get(OPENAI_BaseURL). @@ -62,20 +64,41 @@ func (a *AI) GetMsg() string { return "解析模型列表失败" } choices := responseBody["data"].([]interface{}) + var models []interface{} if len(choices) > 0 { msg = "支持的模型列表:\n" for _, choice := range choices { - models := choice.(map[string]interface{})["id"].(string) - if models == MODEL { - msg = msg + models + "\t ✔\n" + model := choice.(map[string]interface{})["id"].(string) + if model == MODEL { + msg = msg + model + "\t ✔\n" } else { - msg = msg + models + "\n" + msg = msg + model + "\n" } + models = append(models, model) } + } else { msg = "没查到支持模型列表" } + if len(a.Parms) > 3 && strings.ToLower(a.Parms[2]) == "set" { + // 判断允许设置权限,需要AllowUser和发消息用户账号相同 + if a.AllowUser != nil && contains(a.AllowUser, a.UID) { + if contains(models, a.Parms[3]) { + cfg["MODEL"] = a.Parms[3] + msg = "已设置模型为 " + a.Parms[3] + config.ModifyConfig("MODEL", a.Parms[3]) + config.ReloadConfig() + config.PrintConfig(cfg, "") + } else { + msg = "不支持的模型" + } + + } else { + msg = "无权限设置模型" + } + + } return msg } else { log.Println("请求失败") @@ -89,16 +112,18 @@ func (a *AI) GetMsg() string { log.Println("PROMRT 未配置") PROMPT = "" } + // PROMPT = "" // println("PROMPT:", PROMPT) requestBody := map[string]interface{}{ "model": MODEL, "stream": false, - "messages": []map[string]string{{ - "role": "system", - "content": PROMPT, - }, + "messages": []map[string]string{ + { + "role": "system", + "content": PROMPT, + }, {"role": "user", "content": ask}}, - "max_tokens": 75, + "max_tokens": 200, "temperature": 0.7, } request := gorequest.New() diff --git a/workers/core.go b/workers/core.go index 23842fd..6d341ce 100644 --- a/workers/core.go +++ b/workers/core.go @@ -63,7 +63,7 @@ func (s *StdAns) CheckPermission() string { if len(s.AllowRole) > 0 && !contains(s.AllowRole, s.Role) { return s.RoleNotAllow } - return "0" + return "ok" } func contains(slice []interface{}, value string) bool { for _, item := range slice {