66 "os"
77 "strconv"
88 "strings"
9- "sync/atomic"
10- "unsafe"
119
1210 "github.com/fumiama/deepinfra"
1311 "github.com/fumiama/deepinfra/model"
@@ -24,13 +22,15 @@ import (
2422)
2523
2624var (
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 ]{
2927 DisableOnDefault : false ,
3028 Extra : control .ExtraFromString ("aichat" ),
3129 Brief : "OpenAI聊天" ,
3230 Help : "- 设置AI聊天触发概率10\n " +
3331 "- 设置AI聊天温度80\n " +
32+ "- 设置AI聊天接口类型[OpenAI|OLLaMA|GenAI]\n " +
33+ "- 设置AI聊天接口地址https://xxx\n " +
3434 "- 设置AI聊天密钥xxx\n " +
3535 "- 设置AI聊天模型名xxx\n " +
3636 "- 重置AI聊天系统提示词\n " +
@@ -44,14 +44,22 @@ var (
4444var (
4545 modelname = model .ModelDeepDeek
4646 systemprompt = chat .SystemPrompt
47+ api = deepinfra .OpenAIDeepInfra
4748 sepstr = ""
4849 noreplyat = false
4950)
5051
52+ var apitypes = map [string ]uint8 {
53+ "OpenAI" : 0 ,
54+ "OLLaMA" : 1 ,
55+ "GenAI" : 2 ,
56+ }
57+
5158func init () {
5259 mf := en .DataFolder () + "model.txt"
5360 sf := en .DataFolder () + "system.txt"
5461 pf := en .DataFolder () + "sep.txt"
62+ af := en .DataFolder () + "api.txt"
5563 nf := en .DataFolder () + "NoReplyAT"
5664 if file .IsExist (mf ) {
5765 data , err := os .ReadFile (mf )
@@ -77,6 +85,14 @@ func init() {
7785 sepstr = string (data )
7886 }
7987 }
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+ }
8096 noreplyat = file .IsExist (nf )
8197
8298 en .OnMessage (func (ctx * zero.Ctx ) bool {
@@ -92,6 +108,7 @@ func init() {
92108 }
93109 rate := c .GetData (gid )
94110 temp := (rate >> 8 ) & 0xff
111+ typ := (rate >> 16 ) & 0x0f
95112 rate &= 0xff
96113 if ! ctx .Event .IsToMe && rand .Intn (100 ) >= int (rate ) {
97114 return
@@ -109,29 +126,47 @@ func init() {
109126 logrus .Warnln ("ERROR: get extra err: empty key" )
110127 return
111128 }
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+
120130 if temp <= 0 {
121131 temp = 70 // default setting
122132 }
123133 if temp > 100 {
124134 temp = 100
125135 }
126136
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 ))
131165 if err != nil {
132- logrus .Warnln ("[niniqun ] post err:" , err )
166+ logrus .Warnln ("[aichat ] post err:" , err )
133167 return
134168 }
169+
135170 txt := chat .Sanitize (strings .Trim (data , "\n " ))
136171 if len (txt ) > 0 {
137172 chat .Reply (gid , txt )
@@ -221,6 +256,48 @@ func init() {
221256 }
222257 ctx .SendChain (message .Text ("成功" ))
223258 })
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+ })
224301 en .OnPrefix ("设置AI聊天密钥" , zero .OnlyPrivate , zero .SuperUserPermission ).SetBlock (true ).Handle (func (ctx * zero.Ctx ) {
225302 args := strings .TrimSpace (ctx .State ["args" ].(string ))
226303 if args == "" {
0 commit comments