mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-18 20:50:12 +08:00
optimize(aichat): use config struct
This commit is contained in:
parent
62e9fe69ed
commit
d5227f1159
96
plugin/aichat/cfg.go
Normal file
96
plugin/aichat/cfg.go
Normal file
@ -0,0 +1,96 @@
|
||||
package aichat
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/chat"
|
||||
"github.com/fumiama/deepinfra"
|
||||
"github.com/fumiama/deepinfra/model"
|
||||
"github.com/sirupsen/logrus"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
)
|
||||
|
||||
var cfg = newconfig()
|
||||
|
||||
type config struct {
|
||||
ModelName string
|
||||
Type int
|
||||
SystemP string
|
||||
API string
|
||||
Key string
|
||||
Separator string
|
||||
NoReplyAT bool
|
||||
NoSystemP bool
|
||||
}
|
||||
|
||||
func newconfig() config {
|
||||
return config{
|
||||
ModelName: model.ModelDeepDeek,
|
||||
SystemP: chat.SystemPrompt,
|
||||
API: deepinfra.OpenAIDeepInfra,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *config) isvalid() bool {
|
||||
return c.ModelName != "" && c.API != "" && c.Key != ""
|
||||
}
|
||||
|
||||
func ensureconfig(ctx *zero.Ctx) bool {
|
||||
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if !cfg.isvalid() {
|
||||
err := c.GetExtra(&cfg)
|
||||
if err != nil {
|
||||
logrus.Warnln("ERROR: get extra err:", err)
|
||||
}
|
||||
if !cfg.isvalid() {
|
||||
cfg = newconfig()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func newextrasetstr(ptr *string) func(ctx *zero.Ctx) {
|
||||
return func(ctx *zero.Ctx) {
|
||||
args := strings.TrimSpace(ctx.State["args"].(string))
|
||||
if args == "" {
|
||||
ctx.SendChain(message.Text("ERROR: empty args"))
|
||||
return
|
||||
}
|
||||
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
||||
if !ok {
|
||||
ctx.SendChain(message.Text("ERROR: no such plugin"))
|
||||
return
|
||||
}
|
||||
*ptr = args
|
||||
err := c.SetExtra(&cfg)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: set extra err: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text("成功"))
|
||||
}
|
||||
}
|
||||
|
||||
func newextrasetbool(ptr *bool) func(ctx *zero.Ctx) {
|
||||
return func(ctx *zero.Ctx) {
|
||||
args := ctx.State["regex_matched"].([]string)
|
||||
isno := args[1] == "不"
|
||||
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
||||
if !ok {
|
||||
ctx.SendChain(message.Text("ERROR: no such plugin"))
|
||||
return
|
||||
}
|
||||
*ptr = isno
|
||||
err := c.SetExtra(&cfg)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: set extra err: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text("成功"))
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,6 @@ package aichat
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -14,7 +13,6 @@ import (
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/process"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/chat"
|
||||
@ -22,7 +20,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// en data [4 cfg] [4 type] [8 temp] [8 rate] LSB
|
||||
// en data [8 temp] [8 rate] LSB
|
||||
en = control.AutoRegister(&ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Extra: control.ExtraFromString("aichat"),
|
||||
@ -43,15 +41,6 @@ var (
|
||||
})
|
||||
)
|
||||
|
||||
var (
|
||||
modelname = model.ModelDeepDeek
|
||||
systemprompt = chat.SystemPrompt
|
||||
api = deepinfra.OpenAIDeepInfra
|
||||
sepstr = ""
|
||||
noreplyat = false
|
||||
nosystemprompt = false
|
||||
)
|
||||
|
||||
var apitypes = map[string]uint8{
|
||||
"OpenAI": 0,
|
||||
"OLLaMA": 1,
|
||||
@ -59,49 +48,9 @@ var apitypes = map[string]uint8{
|
||||
}
|
||||
|
||||
func init() {
|
||||
mf := en.DataFolder() + "model.txt"
|
||||
sf := en.DataFolder() + "system.txt"
|
||||
pf := en.DataFolder() + "sep.txt"
|
||||
af := en.DataFolder() + "api.txt"
|
||||
nf := en.DataFolder() + "NoReplyAT"
|
||||
syspf := en.DataFolder() + "NoSystemPrompt"
|
||||
if file.IsExist(mf) {
|
||||
data, err := os.ReadFile(mf)
|
||||
if err != nil {
|
||||
logrus.Warnln("read model", err)
|
||||
} else {
|
||||
modelname = string(data)
|
||||
}
|
||||
}
|
||||
if file.IsExist(sf) {
|
||||
data, err := os.ReadFile(sf)
|
||||
if err != nil {
|
||||
logrus.Warnln("read system", err)
|
||||
} else {
|
||||
systemprompt = string(data)
|
||||
}
|
||||
}
|
||||
if file.IsExist(pf) {
|
||||
data, err := os.ReadFile(pf)
|
||||
if err != nil {
|
||||
logrus.Warnln("read sep", err)
|
||||
} else {
|
||||
sepstr = string(data)
|
||||
}
|
||||
}
|
||||
if file.IsExist(af) {
|
||||
data, err := os.ReadFile(af)
|
||||
if err != nil {
|
||||
logrus.Warnln("read api", err)
|
||||
} else {
|
||||
api = string(data)
|
||||
}
|
||||
}
|
||||
noreplyat = file.IsExist(nf)
|
||||
nosystemprompt = file.IsExist(syspf)
|
||||
|
||||
en.OnMessage(func(ctx *zero.Ctx) bool {
|
||||
return ctx.ExtractPlainText() != "" && (!noreplyat || (noreplyat && !ctx.Event.IsToMe))
|
||||
en.OnMessage(ensureconfig, func(ctx *zero.Ctx) bool {
|
||||
return ctx.ExtractPlainText() != "" &&
|
||||
(!cfg.NoReplyAT || (cfg.NoReplyAT && !ctx.Event.IsToMe))
|
||||
}).SetBlock(false).Handle(func(ctx *zero.Ctx) {
|
||||
gid := ctx.Event.GroupID
|
||||
if gid == 0 {
|
||||
@ -113,7 +62,6 @@ func init() {
|
||||
}
|
||||
rate := c.GetData(gid)
|
||||
temp := (rate >> 8) & 0xff
|
||||
typ := (rate >> 16) & 0x0f
|
||||
rate &= 0xff
|
||||
if !ctx.Event.IsToMe && rand.Intn(100) >= int(rate) {
|
||||
return
|
||||
@ -121,13 +69,7 @@ func init() {
|
||||
if ctx.Event.IsToMe {
|
||||
ctx.Block()
|
||||
}
|
||||
key := ""
|
||||
err := c.GetExtra(&key)
|
||||
if err != nil {
|
||||
logrus.Warnln("ERROR: get extra err:", err)
|
||||
return
|
||||
}
|
||||
if key == "" {
|
||||
if cfg.Key == "" {
|
||||
logrus.Warnln("ERROR: get extra err: empty key")
|
||||
return
|
||||
}
|
||||
@ -139,31 +81,31 @@ func init() {
|
||||
temp = 100
|
||||
}
|
||||
|
||||
x := deepinfra.NewAPI(api, key)
|
||||
x := deepinfra.NewAPI(cfg.API, cfg.Key)
|
||||
var mod model.Protocol
|
||||
|
||||
switch typ {
|
||||
switch cfg.Type {
|
||||
case 0:
|
||||
mod = model.NewOpenAI(
|
||||
modelname, sepstr,
|
||||
cfg.ModelName, cfg.Separator,
|
||||
float32(temp)/100, 0.9, 4096,
|
||||
)
|
||||
case 1:
|
||||
mod = model.NewOLLaMA(
|
||||
modelname, sepstr,
|
||||
cfg.ModelName, cfg.Separator,
|
||||
float32(temp)/100, 0.9, 4096,
|
||||
)
|
||||
case 2:
|
||||
mod = model.NewGenAI(
|
||||
modelname,
|
||||
cfg.ModelName,
|
||||
float32(temp)/100, 0.9, 4096,
|
||||
)
|
||||
default:
|
||||
logrus.Warnln("[aichat] unsupported AI type", typ)
|
||||
logrus.Warnln("[aichat] unsupported AI type", cfg.Type)
|
||||
return
|
||||
}
|
||||
|
||||
data, err := x.Request(chat.Ask(mod, gid, systemprompt, nosystemprompt))
|
||||
data, err := x.Request(chat.Ask(mod, gid, cfg.SystemP, cfg.NoSystemP))
|
||||
if err != nil {
|
||||
logrus.Warnln("[aichat] post err:", err)
|
||||
return
|
||||
@ -258,7 +200,7 @@ func init() {
|
||||
}
|
||||
ctx.SendChain(message.Text("成功"))
|
||||
})
|
||||
en.OnPrefix("设置AI聊天接口类型", zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
en.OnPrefix("设置AI聊天接口类型", ensureconfig, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
args := strings.TrimSpace(ctx.State["args"].(string))
|
||||
if args == "" {
|
||||
ctx.SendChain(message.Text("ERROR: empty args"))
|
||||
@ -274,144 +216,43 @@ func init() {
|
||||
ctx.SendChain(message.Text("ERROR: 未知类型 ", args))
|
||||
return
|
||||
}
|
||||
gid := ctx.Event.GroupID
|
||||
if gid == 0 {
|
||||
gid = -ctx.Event.UserID
|
||||
}
|
||||
val := c.GetData(gid) & (^0x0f0000)
|
||||
err := c.SetData(gid, val|(int64(typ&0x0f)<<16))
|
||||
cfg.Type = int(typ)
|
||||
err := c.SetExtra(&cfg)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: set data err: ", err))
|
||||
ctx.SendChain(message.Text("ERROR: set extra err: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text("成功"))
|
||||
})
|
||||
en.OnPrefix("设置AI聊天接口地址", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
args := strings.TrimSpace(ctx.State["args"].(string))
|
||||
if args == "" {
|
||||
ctx.SendChain(message.Text("ERROR: empty args"))
|
||||
return
|
||||
}
|
||||
api = args
|
||||
err := os.WriteFile(af, []byte(args), 0644)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text("成功"))
|
||||
en.OnPrefix("设置AI聊天接口地址", ensureconfig, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).
|
||||
Handle(newextrasetstr(&cfg.API))
|
||||
en.OnPrefix("设置AI聊天密钥", ensureconfig, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).
|
||||
Handle(newextrasetstr(&cfg.Key))
|
||||
en.OnPrefix("设置AI聊天模型名", ensureconfig, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).
|
||||
Handle(newextrasetstr(&cfg.ModelName))
|
||||
en.OnPrefix("设置AI聊天系统提示词", ensureconfig, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).
|
||||
Handle(newextrasetstr(&cfg.SystemP))
|
||||
en.OnFullMatch("查看AI聊天系统提示词", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SendChain(message.Text(cfg.SystemP))
|
||||
})
|
||||
en.OnPrefix("设置AI聊天密钥", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
args := strings.TrimSpace(ctx.State["args"].(string))
|
||||
if args == "" {
|
||||
ctx.SendChain(message.Text("ERROR: empty args"))
|
||||
return
|
||||
}
|
||||
en.OnFullMatch("重置AI聊天系统提示词", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
||||
if !ok {
|
||||
ctx.SendChain(message.Text("ERROR: no such plugin"))
|
||||
return
|
||||
}
|
||||
err := c.SetExtra(&args)
|
||||
cfg.SystemP = chat.SystemPrompt
|
||||
err := c.SetExtra(&cfg)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
ctx.SendChain(message.Text("ERROR: set extra err: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text("成功"))
|
||||
})
|
||||
en.OnPrefix("设置AI聊天模型名", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
args := strings.TrimSpace(ctx.State["args"].(string))
|
||||
if args == "" {
|
||||
ctx.SendChain(message.Text("ERROR: empty args"))
|
||||
return
|
||||
}
|
||||
modelname = args
|
||||
err := os.WriteFile(mf, []byte(args), 0644)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text("成功"))
|
||||
})
|
||||
en.OnPrefix("设置AI聊天系统提示词", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
args := strings.TrimSpace(ctx.State["args"].(string))
|
||||
if args == "" {
|
||||
ctx.SendChain(message.Text("ERROR: empty args"))
|
||||
return
|
||||
}
|
||||
systemprompt = args
|
||||
err := os.WriteFile(sf, []byte(args), 0644)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text("成功"))
|
||||
})
|
||||
en.OnFullMatch("查看AI聊天系统提示词", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SendChain(message.Text(systemprompt))
|
||||
})
|
||||
en.OnFullMatch("重置AI聊天系统提示词", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
systemprompt = chat.SystemPrompt
|
||||
_ = os.Remove(sf)
|
||||
ctx.SendChain(message.Text("成功"))
|
||||
})
|
||||
en.OnPrefix("设置AI聊天分隔符", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
args := strings.TrimSpace(ctx.State["args"].(string))
|
||||
if args == "" {
|
||||
sepstr = ""
|
||||
_ = os.Remove(pf)
|
||||
ctx.SendChain(message.Text("清除成功"))
|
||||
return
|
||||
}
|
||||
sepstr = args
|
||||
err := os.WriteFile(pf, []byte(args), 0644)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text("设置成功"))
|
||||
})
|
||||
en.OnRegex("^设置AI聊天(不)?响应AT$", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
args := ctx.State["regex_matched"].([]string)
|
||||
isno := args[1] == "不"
|
||||
if isno {
|
||||
f, err := os.Create(nf)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = f.WriteString("PLACEHOLDER")
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
noreplyat = true
|
||||
} else {
|
||||
_ = os.Remove(nf)
|
||||
noreplyat = false
|
||||
}
|
||||
ctx.SendChain(message.Text("成功"))
|
||||
})
|
||||
en.OnRegex("^设置AI聊天(不)?支持系统提示词$", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
args := ctx.State["regex_matched"].([]string)
|
||||
isno := args[1] == "不"
|
||||
if isno {
|
||||
f, err := os.Create(syspf)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = f.WriteString("PLACEHOLDER")
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
nosystemprompt = true
|
||||
} else {
|
||||
_ = os.Remove(syspf)
|
||||
nosystemprompt = false
|
||||
}
|
||||
ctx.SendChain(message.Text("成功"))
|
||||
})
|
||||
en.OnPrefix("设置AI聊天分隔符", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).
|
||||
Handle(newextrasetstr(&cfg.Separator))
|
||||
en.OnRegex("^设置AI聊天(不)?响应AT$", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).
|
||||
Handle(newextrasetbool(&cfg.NoReplyAT))
|
||||
en.OnRegex("^设置AI聊天(不)?支持系统提示词$", zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).
|
||||
Handle(newextrasetbool(&cfg.NoSystemP))
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user