Skip to content

Commit 34f3b9b

Browse files
authored
feat(aiimage&aichat): add new plugin & summary of group chat (FloatTech#1187)
1 parent 2fa7868 commit 34f3b9b

File tree

9 files changed

+379
-61
lines changed

9 files changed

+379
-61
lines changed

README.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,18 @@ print("run[CQ:image,file="+j["img"]+"]")
412412

413413
- [x] 设置默认限速为每 m [分钟 | 秒] n 次触发
414414

415+
</details>
416+
<details>
417+
<summary>aiimage</summary>
418+
419+
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/aiimage"`
420+
421+
- [x] 设置AI画图密钥xxx
422+
- [x] 设置AI画图接口地址https://api.siliconflow.cn/v1/images/generations
423+
- [x] 设置AI画图模型名Kwai-Kolors/Kolors
424+
- [x] 查看AI画图配置
425+
- [x] AI画图 [描述]
426+
415427
</details>
416428
<details>
417429
<summary>AIWife</summary>
@@ -1496,7 +1508,7 @@ print("run[CQ:image,file="+j["img"]+"]")
14961508

14971509
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/word_count"`
14981510

1499-
- [x] 热词 [群号] [消息数目]|热词 123456 1000
1511+
- [x] 热词 [消息数目]|热词 1000
15001512

15011513
</details>
15021514
<details>
@@ -1612,9 +1624,9 @@ print("run[CQ:image,file="+j["img"]+"]")
16121624
- [x] 设置AI聊天温度80
16131625
- [x] 设置AI聊天接口类型[OpenAI|OLLaMA|GenAI]
16141626
- [x] 设置AI聊天(不)支持系统提示词
1615-
- [x] 设置AI聊天接口地址https://api.deepseek.com/chat/completions
1627+
- [x] 设置AI聊天接口地址https://api.siliconflow.cn/v1/chat/completions
16161628
- [x] 设置AI聊天密钥xxx
1617-
- [x] 设置AI聊天模型名xxx
1629+
- [x] 设置AI聊天模型名Qwen/Qwen3-8B
16181630
- [x] 查看AI聊天系统提示词
16191631
- [x] 重置AI聊天系统提示词
16201632
- [x] 设置AI聊天系统提示词xxx
@@ -1624,6 +1636,8 @@ print("run[CQ:image,file="+j["img"]+"]")
16241636
- [x] 设置AI聊天TopP 0.9
16251637
- [x] 设置AI聊天(不)以AI语音输出
16261638
- [x] 查看AI聊天配置
1639+
- [x] 重置AI聊天
1640+
- [x] 群聊总结 [消息数目]|群聊总结 1000
16271641

16281642
</details>
16291643
<details>

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ require (
1212
github.com/FloatTech/sqlite v1.7.1
1313
github.com/FloatTech/ttl v0.0.0-20240716161252-965925764562
1414
github.com/FloatTech/zbpctrl v1.7.0
15-
github.com/FloatTech/zbputils v1.7.2-0.20250614165821-95cf57cf2434
15+
github.com/FloatTech/zbputils v1.7.2-0.20250812085410-2741050f465f
1616
github.com/RomiChan/syncx v0.0.0-20240418144900-b7402ffdebc7
1717
github.com/RomiChan/websocket v1.4.3-0.20220227141055-9b2c6168c9c5
1818
github.com/Tnze/go-mc v1.20.2
@@ -22,7 +22,7 @@ require (
2222
github.com/disintegration/imaging v1.6.2
2323
github.com/fumiama/ahsai v0.1.0
2424
github.com/fumiama/cron v1.3.0
25-
github.com/fumiama/deepinfra v0.0.0-20250601112706-0175c95164c1
25+
github.com/fumiama/deepinfra v0.0.0-20250812083039-f1b27f21d8c9
2626
github.com/fumiama/go-base16384 v1.7.0
2727
github.com/fumiama/go-registry v0.2.7
2828
github.com/fumiama/gotracemoe v0.0.3
@@ -45,7 +45,7 @@ require (
4545
github.com/sirupsen/logrus v1.9.3
4646
github.com/tidwall/gjson v1.18.0
4747
github.com/wcharczuk/go-chart/v2 v2.1.2
48-
github.com/wdvxdr1123/ZeroBot v1.8.2-0.20250707133321-6197b8ee5df7
48+
github.com/wdvxdr1123/ZeroBot v1.8.2-0.20250804063440-ccc03e33ac20
4949
gitlab.com/gomidi/midi/v2 v2.1.7
5050
golang.org/x/image v0.24.0
5151
golang.org/x/sys v0.30.0

go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ github.com/FloatTech/ttl v0.0.0-20240716161252-965925764562 h1:snfw7FNFym1eNnLrQ
1717
github.com/FloatTech/ttl v0.0.0-20240716161252-965925764562/go.mod h1:fHZFWGquNXuHttu9dUYoKuNbm3dzLETnIOnm1muSfDs=
1818
github.com/FloatTech/zbpctrl v1.7.0 h1:Hxo6EIhJo+pHjcQP9QgIJgluaT1pHH99zkk3njqTNMo=
1919
github.com/FloatTech/zbpctrl v1.7.0/go.mod h1:xmM4dSwHA02Gei3ogCRiG+RTrw/7Z69PfrN5NYf8BPE=
20-
github.com/FloatTech/zbputils v1.7.2-0.20250614165821-95cf57cf2434 h1:oEYQFQ2/qx10FtZKCNbW3Ohj/Iw71aM4RWpIu+LMmf8=
21-
github.com/FloatTech/zbputils v1.7.2-0.20250614165821-95cf57cf2434/go.mod h1:ArZ0fMAcmPEIXOqDmfzbSx+oYH8sssApQnbCu694iS8=
20+
github.com/FloatTech/zbputils v1.7.2-0.20250812085410-2741050f465f h1:5jnrFe9FTydb/pcUhxkWHuQVCwmYIZmneOkvmgHOwGI=
21+
github.com/FloatTech/zbputils v1.7.2-0.20250812085410-2741050f465f/go.mod h1:HG/yZwExV3b1Vqu4chbqwhfX4hx7gDS07QO436JkwIg=
2222
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
2323
github.com/RomiChan/syncx v0.0.0-20240418144900-b7402ffdebc7 h1:S/ferNiehVjNaBMNNBxUjLtVmP/YWD6Yh79RfPv4ehU=
2424
github.com/RomiChan/syncx v0.0.0-20240418144900-b7402ffdebc7/go.mod h1:vD7Ra3Q9onRtojoY5sMCLQ7JBgjUsrXDnDKyFxqpf9w=
@@ -59,8 +59,8 @@ github.com/fumiama/ahsai v0.1.0 h1:LXD61Kaj6kJHa3AEGsLIfKNzcgaVxg7JB72OR4yNNZ4=
5959
github.com/fumiama/ahsai v0.1.0/go.mod h1:fFeNnqgo44i8FIaguK659aQryuZeFy+4klYLQu/rfdk=
6060
github.com/fumiama/cron v1.3.0 h1:ZWlwuexF+HQHl3cYytEE5HNwD99q+3vNZF1GrEiXCFo=
6161
github.com/fumiama/cron v1.3.0/go.mod h1:bz5Izvgi/xEUI8tlBN8BI2jr9Moo8N4or0KV8xXuPDY=
62-
github.com/fumiama/deepinfra v0.0.0-20250601112706-0175c95164c1 h1:qE3l/y4Y1gMD2NokQ5Nw4NIUjL8ZwYLPIHOExQNu4hM=
63-
github.com/fumiama/deepinfra v0.0.0-20250601112706-0175c95164c1/go.mod h1:wW05PQSn8mo1mZIoa6LBUE+3xIBjkoONvnfPTV5ZOhY=
62+
github.com/fumiama/deepinfra v0.0.0-20250812083039-f1b27f21d8c9 h1:X2h8RnCgC04LmwBoizYbFawXh/h6CouXmhYtaVuUn7k=
63+
github.com/fumiama/deepinfra v0.0.0-20250812083039-f1b27f21d8c9/go.mod h1:wW05PQSn8mo1mZIoa6LBUE+3xIBjkoONvnfPTV5ZOhY=
6464
github.com/fumiama/go-base16384 v1.7.0 h1:6fep7XPQWxRlh4Hu+KsdH+6+YdUp+w6CwRXtMWSsXCA=
6565
github.com/fumiama/go-base16384 v1.7.0/go.mod h1:OEn+947GV5gsbTAnyuUW/SrfxJYUdYupSIQXOuGOcXM=
6666
github.com/fumiama/go-registry v0.2.7 h1:tLEqgEpsiybQMqBv0dLHm5leia/z1DhajMupwnOHeNs=
@@ -199,8 +199,8 @@ github.com/vcaesar/cedar v0.20.2/go.mod h1:lyuGvALuZZDPNXwpzv/9LyxW+8Y6faN7zauFe
199199
github.com/vcaesar/tt v0.20.1 h1:D/jUeeVCNbq3ad8M7hhtB3J9x5RZ6I1n1eZ0BJp7M+4=
200200
github.com/wcharczuk/go-chart/v2 v2.1.2 h1:Y17/oYNuXwZg6TFag06qe8sBajwwsuvPiJJXcUcLL6E=
201201
github.com/wcharczuk/go-chart/v2 v2.1.2/go.mod h1:Zi4hbaqlWpYajnXB2K22IUYVXRXaLfSGNNR7P4ukyyQ=
202-
github.com/wdvxdr1123/ZeroBot v1.8.2-0.20250707133321-6197b8ee5df7 h1:ya+lVbCC/EN5JumpQDDlVCSrWzLwHl4CHzlTANKDvrU=
203-
github.com/wdvxdr1123/ZeroBot v1.8.2-0.20250707133321-6197b8ee5df7/go.mod h1:C86nQ0gIdAri4K2vg8IIQIslt08zzrKMcqYt8zhkx1M=
202+
github.com/wdvxdr1123/ZeroBot v1.8.2-0.20250804063440-ccc03e33ac20 h1:Yzd+cbiJQYtf6cZDP5ZB/LqjNWiV752+5P6Eua+wnic=
203+
github.com/wdvxdr1123/ZeroBot v1.8.2-0.20250804063440-ccc03e33ac20/go.mod h1:C86nQ0gIdAri4K2vg8IIQIslt08zzrKMcqYt8zhkx1M=
204204
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
205205
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
206206
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=

main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import (
6767
_ "github.com/FloatTech/ZeroBot-Plugin/custom" // 自定义插件合集
6868
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ahsai" // ahsai tts
6969
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/aifalse" // 服务器监控
70+
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/aiimage" // AI画图
7071
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/aiwife" // 随机老婆
7172
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/alipayvoice" // 支付宝到账语音
7273
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/animetrace" // AnimeTrace 动画/Galgame识别

plugin/aichat/main.go

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
// Package aichat OpenAI聊天
1+
// Package aichat OpenAI聊天和群聊总结
22
package aichat
33

44
import (
55
"math/rand"
66
"strconv"
77
"strings"
8+
"time"
89

910
"github.com/fumiama/deepinfra"
1011
"github.com/fumiama/deepinfra/model"
1112
"github.com/sirupsen/logrus"
13+
"github.com/tidwall/gjson"
1214

1315
zero "github.com/wdvxdr1123/ZeroBot"
1416
"github.com/wdvxdr1123/ZeroBot/message"
@@ -18,6 +20,7 @@ import (
1820
ctrl "github.com/FloatTech/zbpctrl"
1921
"github.com/FloatTech/zbputils/chat"
2022
"github.com/FloatTech/zbputils/control"
23+
"github.com/FloatTech/zbputils/ctxext"
2124
)
2225

2326
var (
@@ -30,9 +33,9 @@ var (
3033
"- 设置AI聊天温度80\n" +
3134
"- 设置AI聊天接口类型[OpenAI|OLLaMA|GenAI]\n" +
3235
"- 设置AI聊天(不)支持系统提示词\n" +
33-
"- 设置AI聊天接口地址https://api.deepseek.com/chat/completions\n" +
36+
"- 设置AI聊天接口地址https://api.siliconflow.cn/v1/chat/completions\n" +
3437
"- 设置AI聊天密钥xxx\n" +
35-
"- 设置AI聊天模型名xxx\n" +
38+
"- 设置AI聊天模型名Qwen/Qwen3-8B\n" +
3639
"- 查看AI聊天系统提示词\n" +
3740
"- 重置AI聊天系统提示词\n" +
3841
"- 设置AI聊天系统提示词xxx\n" +
@@ -41,7 +44,9 @@ var (
4144
"- 设置AI聊天最大长度4096\n" +
4245
"- 设置AI聊天TopP 0.9\n" +
4346
"- 设置AI聊天(不)以AI语音输出\n" +
44-
"- 查看AI聊天配置\n",
47+
"- 查看AI聊天配置\n" +
48+
"- 重置AI聊天\n" +
49+
"- 群聊总结 [消息数目]|群聊总结 1000\n",
4550
PrivateDataFolder: "aichat",
4651
})
4752
)
@@ -53,6 +58,7 @@ var (
5358
"GenAI": 2,
5459
}
5560
apilist = [3]string{"OpenAI", "OLLaMA", "GenAI"}
61+
limit = ctxext.NewLimiterManager(time.Second*30, 1)
5662
)
5763

5864
func init() {
@@ -305,4 +311,93 @@ func init() {
305311
}
306312
ctx.SendChain(message.Text(printConfig(rate, temp, cfg)))
307313
})
314+
en.OnFullMatch("重置AI聊天", ensureconfig, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
315+
chat.Reset()
316+
ctx.SendChain(message.Text("成功"))
317+
})
318+
319+
// 添加群聊总结功能
320+
en.OnRegex(`^群聊总结\s?(\d*)$`, ensureconfig, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).Limit(limit.LimitByGroup).Handle(func(ctx *zero.Ctx) {
321+
ctx.SendChain(message.Text("少女思考中..."))
322+
p, _ := strconv.ParseInt(ctx.State["regex_matched"].([]string)[1], 10, 64)
323+
if p > 1000 {
324+
p = 1000
325+
}
326+
if p == 0 {
327+
p = 200
328+
}
329+
gid := ctx.Event.GroupID
330+
group := ctx.GetGroupInfo(gid, false)
331+
if group.MemberCount == 0 {
332+
ctx.SendChain(message.Text(zero.BotConfig.NickName[0], "未加入", group.Name, "(", gid, "),无法获取摘要"))
333+
return
334+
}
335+
336+
var messages []string
337+
338+
h := ctx.GetGroupMessageHistory(gid, 0, p, false)
339+
h.Get("messages").ForEach(func(_, msgObj gjson.Result) bool {
340+
nickname := msgObj.Get("sender.nickname").Str
341+
text := strings.TrimSpace(message.ParseMessageFromString(msgObj.Get("raw_message").Str).ExtractPlainText())
342+
if text != "" {
343+
messages = append(messages, nickname+": "+text)
344+
}
345+
return true
346+
})
347+
348+
if len(messages) == 0 {
349+
ctx.SendChain(message.Text("ERROR: 历史消息为空或者无法获得历史消息"))
350+
return
351+
}
352+
353+
// 调用大模型API进行摘要
354+
summary, err := summarizeMessages(messages)
355+
if err != nil {
356+
ctx.SendChain(message.Text("ERROR: ", err))
357+
return
358+
}
359+
360+
var b strings.Builder
361+
b.WriteString("群 ")
362+
b.WriteString(group.Name)
363+
b.WriteByte('(')
364+
b.WriteString(strconv.FormatInt(gid, 10))
365+
b.WriteString(") 的 ")
366+
b.WriteString(strconv.FormatInt(p, 10))
367+
b.WriteString(" 条消息总结:\n\n")
368+
b.WriteString(summary)
369+
370+
// 分割总结内容为多段
371+
parts := strings.Split(b.String(), "\n\n")
372+
msg := make(message.Message, 0, len(parts))
373+
for _, part := range parts {
374+
if part != "" {
375+
msg = append(msg, ctxext.FakeSenderForwardNode(ctx, message.Text(part)))
376+
}
377+
}
378+
if len(msg) > 0 {
379+
ctx.Send(msg)
380+
}
381+
})
382+
}
383+
384+
// summarizeMessages 调用大模型API进行消息摘要
385+
func summarizeMessages(messages []string) (string, error) {
386+
// 使用现有的AI配置进行摘要
387+
x := deepinfra.NewAPI(cfg.API, cfg.Key)
388+
mod := model.NewOpenAI(
389+
cfg.ModelName, cfg.Separator,
390+
float32(70)/100, 0.9, 4096,
391+
)
392+
393+
// 构造摘要请求提示
394+
summaryPrompt := "请总结这个群聊内容,要求按发言顺序梳理,明确标注每个发言者的昵称,并完整呈现其核心观点、提出的问题、发表的看法或做出的回应,确保不遗漏关键信息,且能体现成员间的对话逻辑和互动关系:\n\n" +
395+
strings.Join(messages, "\n---\n")
396+
397+
data, err := x.Request(mod.User(summaryPrompt))
398+
if err != nil {
399+
return "", err
400+
}
401+
402+
return strings.TrimSpace(data), nil
308403
}

plugin/aiimage/config.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Package aiimage 提供AI画图功能配置
2+
package aiimage
3+
4+
import (
5+
"fmt"
6+
"strings"
7+
"sync"
8+
9+
sql "github.com/FloatTech/sqlite"
10+
)
11+
12+
// storage 管理画图配置存储
13+
type storage struct {
14+
sync.RWMutex
15+
db sql.Sqlite
16+
}
17+
18+
// imageConfig 存储AI画图配置信息
19+
type imageConfig struct {
20+
ID int64 `db:"id"` // 主键ID
21+
APIKey string `db:"apiKey"` // API密钥
22+
APIURL string `db:"apiUrl"` // API地址
23+
ModelName string `db:"modelName"` // 画图模型名称
24+
}
25+
26+
// getConfig 获取当前配置
27+
func (sdb *storage) getConfig() imageConfig {
28+
sdb.RLock()
29+
defer sdb.RUnlock()
30+
cfg := imageConfig{}
31+
_ = sdb.db.Find("config", &cfg, "WHERE id = 1")
32+
return cfg
33+
}
34+
35+
// setConfig 设置AI画图配置
36+
func (sdb *storage) setConfig(apiKey, apiURL, modelName string) error {
37+
sdb.Lock()
38+
defer sdb.Unlock()
39+
return sdb.db.Insert("config", &imageConfig{
40+
ID: 1,
41+
APIKey: apiKey,
42+
APIURL: apiURL,
43+
ModelName: modelName,
44+
})
45+
}
46+
47+
// PrintConfig 返回格式化后的配置信息
48+
func (sdb *storage) PrintConfig() string {
49+
cfg := sdb.getConfig()
50+
var builder strings.Builder
51+
builder.WriteString("当前AI画图配置:\n")
52+
builder.WriteString(fmt.Sprintf("• 密钥: %s\n", cfg.APIKey))
53+
builder.WriteString(fmt.Sprintf("• 接口地址: %s\n", cfg.APIURL))
54+
builder.WriteString(fmt.Sprintf("• 模型名: %s\n", cfg.ModelName))
55+
return builder.String()
56+
}

0 commit comments

Comments
 (0)