6
6
"os"
7
7
"strconv"
8
8
"strings"
9
- "sync/atomic"
10
- "unsafe"
11
9
12
10
"github.com/fumiama/deepinfra"
13
11
"github.com/fumiama/deepinfra/model"
@@ -24,13 +22,15 @@ import (
24
22
)
25
23
26
24
var (
27
- api * deepinfra. API
28
- en = control .AutoRegister (& ctrl.Options [* zero.Ctx ]{
25
+ // en data [4 type] [8 temp] [8 rate] LSB
26
+ en = control .AutoRegister (& ctrl.Options [* zero.Ctx ]{
29
27
DisableOnDefault : false ,
30
28
Extra : control .ExtraFromString ("aichat" ),
31
29
Brief : "OpenAI聊天" ,
32
30
Help : "- 设置AI聊天触发概率10\n " +
33
31
"- 设置AI聊天温度80\n " +
32
+ "- 设置AI聊天接口类型[OpenAI|OLLaMA|GenAI]\n " +
33
+ "- 设置AI聊天接口地址https://xxx\n " +
34
34
"- 设置AI聊天密钥xxx\n " +
35
35
"- 设置AI聊天模型名xxx\n " +
36
36
"- 重置AI聊天系统提示词\n " +
@@ -44,14 +44,22 @@ var (
44
44
var (
45
45
modelname = model .ModelDeepDeek
46
46
systemprompt = chat .SystemPrompt
47
+ api = deepinfra .OpenAIDeepInfra
47
48
sepstr = ""
48
49
noreplyat = false
49
50
)
50
51
52
+ var apitypes = map [string ]uint8 {
53
+ "OpenAI" : 0 ,
54
+ "OLLaMA" : 1 ,
55
+ "GenAI" : 2 ,
56
+ }
57
+
51
58
func init () {
52
59
mf := en .DataFolder () + "model.txt"
53
60
sf := en .DataFolder () + "system.txt"
54
61
pf := en .DataFolder () + "sep.txt"
62
+ af := en .DataFolder () + "api.txt"
55
63
nf := en .DataFolder () + "NoReplyAT"
56
64
if file .IsExist (mf ) {
57
65
data , err := os .ReadFile (mf )
@@ -77,6 +85,14 @@ func init() {
77
85
sepstr = string (data )
78
86
}
79
87
}
88
+ if file .IsExist (af ) {
89
+ data , err := os .ReadFile (af )
90
+ if err != nil {
91
+ logrus .Warnln ("read api" , err )
92
+ } else {
93
+ api = string (data )
94
+ }
95
+ }
80
96
noreplyat = file .IsExist (nf )
81
97
82
98
en .OnMessage (func (ctx * zero.Ctx ) bool {
@@ -92,6 +108,7 @@ func init() {
92
108
}
93
109
rate := c .GetData (gid )
94
110
temp := (rate >> 8 ) & 0xff
111
+ typ := (rate >> 16 ) & 0x0f
95
112
rate &= 0xff
96
113
if ! ctx .Event .IsToMe && rand .Intn (100 ) >= int (rate ) {
97
114
return
@@ -109,29 +126,47 @@ func init() {
109
126
logrus .Warnln ("ERROR: get extra err: empty key" )
110
127
return
111
128
}
112
- var x deepinfra.API
113
- y := & x
114
- if api == nil {
115
- x = deepinfra .NewAPI (deepinfra .APIDeepInfra , key )
116
- atomic .StorePointer ((* unsafe .Pointer )(unsafe .Pointer (& api )), unsafe .Pointer (& x ))
117
- } else {
118
- y = api
119
- }
129
+
120
130
if temp <= 0 {
121
131
temp = 70 // default setting
122
132
}
123
133
if temp > 100 {
124
134
temp = 100
125
135
}
126
136
127
- data , err := y .Request (chat .Ask (model .NewOpenAI (
128
- modelname , sepstr ,
129
- float32 (temp )/ 100 , 0.9 , 4096 ,
130
- ), gid , systemprompt ))
137
+ var x deepinfra.API
138
+ var mod model.Protocol
139
+
140
+ switch typ {
141
+ case 0 :
142
+ x = deepinfra .NewAPI (api , key )
143
+ mod = model .NewOpenAI (
144
+ modelname , sepstr ,
145
+ float32 (temp )/ 100 , 0.9 , 4096 ,
146
+ )
147
+ case 1 :
148
+ x = deepinfra .NewAPI (api , key )
149
+ mod = model .NewOLLaMA (
150
+ modelname , sepstr ,
151
+ float32 (temp )/ 100 , 0.9 , 4096 ,
152
+ )
153
+ case 2 :
154
+ x = deepinfra .NewAPI (api , key )
155
+ mod = model .NewGenAI (
156
+ modelname ,
157
+ float32 (temp )/ 100 , 0.9 , 4096 ,
158
+ )
159
+ default :
160
+ logrus .Warnln ("[aichat] unsupported AI type" , typ )
161
+ return
162
+ }
163
+
164
+ data , err := x .Request (chat .Ask (mod , gid , systemprompt ))
131
165
if err != nil {
132
- logrus .Warnln ("[niniqun ] post err:" , err )
166
+ logrus .Warnln ("[aichat ] post err:" , err )
133
167
return
134
168
}
169
+
135
170
txt := chat .Sanitize (strings .Trim (data , "\n " ))
136
171
if len (txt ) > 0 {
137
172
chat .Reply (gid , txt )
@@ -221,6 +256,48 @@ func init() {
221
256
}
222
257
ctx .SendChain (message .Text ("成功" ))
223
258
})
259
+ en .OnPrefix ("设置AI聊天接口类型" , zero .SuperUserPermission ).SetBlock (true ).Handle (func (ctx * zero.Ctx ) {
260
+ args := strings .TrimSpace (ctx .State ["args" ].(string ))
261
+ if args == "" {
262
+ ctx .SendChain (message .Text ("ERROR: empty args" ))
263
+ return
264
+ }
265
+ c , ok := ctx .State ["manager" ].(* ctrl.Control [* zero.Ctx ])
266
+ if ! ok {
267
+ ctx .SendChain (message .Text ("ERROR: no such plugin" ))
268
+ return
269
+ }
270
+ typ , ok := apitypes [args ]
271
+ if ! ok {
272
+ ctx .SendChain (message .Text ("ERROR: 未知类型 " , args ))
273
+ return
274
+ }
275
+ gid := ctx .Event .GroupID
276
+ if gid == 0 {
277
+ gid = - ctx .Event .UserID
278
+ }
279
+ val := c .GetData (gid ) & (^ 0x0f0000 )
280
+ err := c .SetData (gid , val | (int64 (typ & 0x0f )<< 16 ))
281
+ if err != nil {
282
+ ctx .SendChain (message .Text ("ERROR: set data err: " , err ))
283
+ return
284
+ }
285
+ ctx .SendChain (message .Text ("成功" ))
286
+ })
287
+ en .OnPrefix ("设置AI聊天接口地址" , zero .OnlyPrivate , zero .SuperUserPermission ).SetBlock (true ).Handle (func (ctx * zero.Ctx ) {
288
+ args := strings .TrimSpace (ctx .State ["args" ].(string ))
289
+ if args == "" {
290
+ ctx .SendChain (message .Text ("ERROR: empty args" ))
291
+ return
292
+ }
293
+ api = args
294
+ err := os .WriteFile (af , []byte (args ), 0644 )
295
+ if err != nil {
296
+ ctx .SendChain (message .Text ("ERROR: " , err ))
297
+ return
298
+ }
299
+ ctx .SendChain (message .Text ("成功" ))
300
+ })
224
301
en .OnPrefix ("设置AI聊天密钥" , zero .OnlyPrivate , zero .SuperUserPermission ).SetBlock (true ).Handle (func (ctx * zero.Ctx ) {
225
302
args := strings .TrimSpace (ctx .State ["args" ].(string ))
226
303
if args == "" {
0 commit comments