Skip to content

Commit fd55bfc

Browse files
authored
fix(chatgpt): 修复因全局禁用插件导致开启会话重复消费,修复多个聊天室内禁用chatgpt插件失败 (#42)
1 parent 3de5d13 commit fd55bfc

File tree

4 files changed

+52
-32
lines changed

4 files changed

+52
-32
lines changed

engine/pkg/log/log.go

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package log
22

33
import (
4+
"bytes"
45
"fmt"
56
"os"
67
"path"
78
"runtime"
8-
"strings"
9+
"strconv"
910

1011
"github.com/sirupsen/logrus"
1112
)
@@ -20,30 +21,17 @@ var log = &logger{
2021
l: logrus.New(),
2122
}
2223

23-
type Formatter struct{}
24-
25-
func (s *Formatter) Format(entry *logrus.Entry) ([]byte, error) {
26-
timestamp := entry.Time.Format("2006-01-02 15:04:05")
27-
level := strings.ToUpper(entry.Level.String())
28-
if os.Getenv("DEBUG") == "true" || os.Getenv("DEBUG_LOG") == "true" {
29-
return []byte(fmt.Sprintf("[%s] [%s] [%s:%d] %s\n", timestamp, level, log.callerFile, log.callerLine, entry.Message)), nil
30-
} else {
31-
return []byte(fmt.Sprintf("[%s] [%s] %s\n", timestamp, level, entry.Message)), nil
32-
}
33-
}
34-
3524
func init() {
3625
log.l.SetLevel(logrus.TraceLevel)
3726
log.l.SetOutput(os.Stdout)
38-
//log.l.SetFormatter(&Formatter{})
3927
log.l.SetReportCaller(true)
4028
log.l.SetFormatter(&logrus.TextFormatter{
4129
ForceColors: true,
4230
FullTimestamp: true,
4331
TimestampFormat: "2006-01-02 15:04:05",
4432
CallerPrettyfier: func(frame *runtime.Frame) (function string, file string) {
4533
if os.Getenv("DEBUG") == "true" || os.Getenv("DEBUG_LOG") == "true" {
46-
return "", fmt.Sprintf("[%s:%d]", log.callerFile, log.callerLine)
34+
return "", fmt.Sprintf("[%s:%d] [GOID:%d]", log.callerFile, log.callerLine, getGoId())
4735
}
4836
return "", ""
4937
},
@@ -132,3 +120,12 @@ func Tracef(format string, args ...interface{}) {
132120
getCaller()
133121
log.l.Tracef(format, args...)
134122
}
123+
124+
func getGoId() uint64 {
125+
b := make([]byte, 64)
126+
b = b[:runtime.Stack(b, false)]
127+
b = bytes.TrimPrefix(b, []byte("goroutine "))
128+
b = b[:bytes.IndexByte(b, ' ')]
129+
n, _ := strconv.ParseUint(string(b), 10, 64)
130+
return n
131+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/glebarez/sqlite v1.7.0
99
github.com/go-co-op/gocron v1.18.0
1010
github.com/imroc/req/v3 v3.32.0
11-
github.com/sashabaranov/go-gpt3 v1.3.1
11+
github.com/sashabaranov/go-gpt3 v1.3.3
1212
github.com/sirupsen/logrus v1.9.0
1313
github.com/spf13/viper v1.15.0
1414
github.com/tidwall/gjson v1.14.4

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ github.com/sashabaranov/go-gpt3 v1.3.0 h1:IbvaK2yTnlm7f/oiC2HC9cbzu/4Znt4GkarFiw
235235
github.com/sashabaranov/go-gpt3 v1.3.0/go.mod h1:BIZdbwdzxZbCrcKGMGH6u2eyGe1xFuX9Anmh3tCP8lQ=
236236
github.com/sashabaranov/go-gpt3 v1.3.1 h1:ACQOAVX5CAV5rHt0oJOBMKo9BNcqVnmxEdjVxcjVAzw=
237237
github.com/sashabaranov/go-gpt3 v1.3.1/go.mod h1:BIZdbwdzxZbCrcKGMGH6u2eyGe1xFuX9Anmh3tCP8lQ=
238+
github.com/sashabaranov/go-gpt3 v1.3.3 h1:S8Zd4YybnBaNMK+w+XGGWgsjQY1R+6QE2n9SLzVna9k=
239+
github.com/sashabaranov/go-gpt3 v1.3.3/go.mod h1:BIZdbwdzxZbCrcKGMGH6u2eyGe1xFuX9Anmh3tCP8lQ=
238240
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
239241
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
240242
github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=

plugins/chatgpt/main.go

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,16 @@ import (
1717
)
1818

1919
var (
20-
db sqlite.DB // 数据库
21-
chatCTXMap sync.Map // 群号/私聊:消息上下文
22-
chatDone = make(chan struct{}) // 用于结束会话
20+
db sqlite.DB // 数据库
21+
msgContext sync.Map // 群号/私聊:消息上下文
22+
chatRoom = make(map[string]ChatRoom) // 连续会话聊天室
2323
)
2424

25+
type ChatRoom struct {
26+
wxId string
27+
done chan struct{}
28+
}
29+
2530
// ApiKey apikey表,存放openai key
2631
type ApiKey struct {
2732
Key string `gorm:"column:key;index"`
@@ -58,7 +63,11 @@ func init() {
5863
DataFolder: "chatgpt",
5964
OnDisable: func(ctx *robot.Ctx) {
6065
ctx.ReplyText("禁用成功")
61-
chatDone <- struct{}{}
66+
wxId := ctx.Event.FromUniqueID
67+
if room, ok := chatRoom[wxId]; ok {
68+
close(room.done)
69+
delete(chatRoom, wxId)
70+
}
6271
},
6372
})
6473

@@ -76,39 +85,51 @@ func init() {
7685

7786
// 连续会话
7887
engine.OnFullMatch("开始会话").SetBlock(true).Handle(func(ctx *robot.Ctx) {
88+
wxId := ctx.Event.FromUniqueID
7989
// 检查是否已经在进行会话
80-
if _, ok := chatCTXMap.Load(ctx.Event.FromUniqueID); ok {
90+
if _, ok := chatRoom[wxId]; ok {
8191
ctx.ReplyTextAndAt("当前已经在会话中了")
8292
return
8393
}
8494

85-
var nullMessage []gogpt.ChatCompletionMessage
95+
var (
96+
nullMessage []gogpt.ChatCompletionMessage
97+
room = ChatRoom{
98+
wxId: wxId,
99+
done: make(chan struct{}),
100+
}
101+
)
102+
103+
chatRoom[wxId] = room
86104

87105
// 开始会话
88106
recv, cancel := ctx.EventChannel(ctx.CheckGroupSession()).Repeat()
89107
defer cancel()
90-
chatCTXMap.LoadOrStore(ctx.Event.FromUniqueID, nullMessage)
108+
msgContext.LoadOrStore(wxId, nullMessage)
91109
ctx.ReplyTextAndAt("收到!已开始ChatGPT连续会话中,输入\"结束会话\"结束会话,或5分钟后自动结束,请开始吧!")
92110
for {
93111
select {
94112
case <-time.After(time.Minute * 5):
95-
chatCTXMap.LoadAndDelete(ctx.Event.FromUniqueID)
113+
msgContext.LoadAndDelete(wxId)
96114
ctx.ReplyTextAndAt("😊检测到您已有5分钟不再提问,那我先主动结束会话咯")
97115
return
98-
case <-chatDone:
99-
chatCTXMap.LoadAndDelete(ctx.Event.FromUniqueID)
100-
ctx.ReplyTextAndAt("已退出ChatGPT")
101-
return
116+
case <-room.done:
117+
if room.wxId == wxId {
118+
msgContext.LoadAndDelete(wxId)
119+
ctx.ReplyTextAndAt("已退出ChatGPT")
120+
return
121+
}
102122
case ctx := <-recv:
123+
wxId := ctx.Event.FromUniqueID
103124
msg := ctx.MessageString()
104125
if msg == "" {
105126
continue
106127
} else if msg == "结束会话" {
107-
chatCTXMap.LoadAndDelete(ctx.Event.FromUniqueID)
128+
msgContext.LoadAndDelete(wxId)
108129
ctx.ReplyTextAndAt("已结束聊天的上下文语境,您可以重新发起提问")
109130
return
110131
} else if msg == "清空会话" {
111-
chatCTXMap.Store(ctx.Event.FromUniqueID, nullMessage)
132+
msgContext.Store(wxId, nullMessage)
112133
ctx.ReplyTextAndAt("已清空会话,您可以继续提问新的问题")
113134
continue
114135
} else if strings.HasPrefix(msg, "作画") {
@@ -129,7 +150,7 @@ func init() {
129150
}
130151

131152
var messages []gogpt.ChatCompletionMessage
132-
if c, ok := chatCTXMap.Load(ctx.Event.FromUniqueID); ok {
153+
if c, ok := msgContext.Load(wxId); ok {
133154
messages = append(c.([]gogpt.ChatCompletionMessage), gogpt.ChatCompletionMessage{
134155
Role: "user",
135156
Content: msg,
@@ -152,7 +173,7 @@ func init() {
152173
Role: "assistant",
153174
Content: answer,
154175
})
155-
chatCTXMap.Store(ctx.Event.FromUniqueID, messages)
176+
msgContext.Store(wxId, messages)
156177
ctx.ReplyTextAndAt(answer)
157178
}
158179
}

0 commit comments

Comments
 (0)