Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beta47 #48

Merged
merged 49 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
ea4bcc6
beta1
Hoshinonyaruko Jan 21, 2024
5002a28
beta2
Hoshinonyaruko Jan 21, 2024
969841e
beta3
Hoshinonyaruko Jan 21, 2024
a2989c2
beta4
Hoshinonyaruko Jan 21, 2024
611cd8b
beta5
Hoshinonyaruko Jan 21, 2024
dbad42b
beta6
Hoshinonyaruko Jan 21, 2024
4f8895e
beta7
Hoshinonyaruko Jan 21, 2024
30a9cab
beta8
Hoshinonyaruko Jan 21, 2024
461d879
beta9
Hoshinonyaruko Jan 21, 2024
c90c2ee
beta10
Hoshinonyaruko Jan 21, 2024
5227c32
beta11
Hoshinonyaruko Jan 21, 2024
8e14e56
beta12
Hoshinonyaruko Jan 21, 2024
6adfb7f
beta13
Hoshinonyaruko Jan 21, 2024
b04f6c0
beta14
Hoshinonyaruko Jan 21, 2024
649e740
beta15
Hoshinonyaruko Jan 21, 2024
d55cf29
beta16
Hoshinonyaruko Jan 21, 2024
1cc351e
beta16
Hoshinonyaruko Jan 21, 2024
f1a373e
beta19
Hoshinonyaruko Jan 21, 2024
cbf2fe1
beta20
Hoshinonyaruko Jan 21, 2024
3485bfc
beta21
Hoshinonyaruko Jan 21, 2024
3e3bb1a
beta22
Hoshinonyaruko Jan 21, 2024
2e4f3fa
beta23
Hoshinonyaruko Mar 29, 2024
f74075d
beta24
Hoshinonyaruko Mar 29, 2024
f3913cf
beta25
Hoshinonyaruko Mar 29, 2024
4cfb51a
beta27
Hoshinonyaruko Mar 30, 2024
d9b26c0
beta28
Hoshinonyaruko Mar 31, 2024
19da709
beta29
Hoshinonyaruko Mar 31, 2024
e06dcbf
merge
Hoshinonyaruko Mar 31, 2024
c76923e
beta30
Hoshinonyaruko Mar 31, 2024
9ae21da
beta31
Hoshinonyaruko Apr 1, 2024
4f333bc
merge
Hoshinonyaruko Apr 1, 2024
5acba8f
beta33
Hoshinonyaruko Apr 1, 2024
c637fcd
beta34
Hoshinonyaruko Apr 1, 2024
4e85b37
beta35
Hoshinonyaruko Apr 1, 2024
970948e
beta36
Hoshinonyaruko Apr 1, 2024
14271c3
beta37
Hoshinonyaruko Apr 1, 2024
6154d1a
beta38
Hoshinonyaruko Apr 1, 2024
d5be5e6
beta39
Hoshinonyaruko Apr 3, 2024
54afe18
beta40
Hoshinonyaruko Apr 3, 2024
0b71855
beta41
Hoshinonyaruko Apr 3, 2024
8c5f9a3
merge
Hoshinonyaruko Apr 3, 2024
cf752d4
beta42
Hoshinonyaruko Apr 3, 2024
3698824
beta43
Hoshinonyaruko Apr 3, 2024
1e9c189
beta44
Hoshinonyaruko Apr 3, 2024
2adb4ac
beta45
Hoshinonyaruko Apr 4, 2024
79eb713
beta45
Hoshinonyaruko Apr 4, 2024
064f0d0
beta45
Hoshinonyaruko Apr 4, 2024
5a4a59e
beta46
Hoshinonyaruko Apr 5, 2024
df30a32
beta46
Hoshinonyaruko Apr 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# specific
config.yml
*.yml
*.sqlite
*.txt

Expand Down
61 changes: 11 additions & 50 deletions applogic/gensokyo.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func (app *App) GensokyoHandler(w http.ResponseWriter, r *http.Request) {
switch msg := message.Message.(type) {
case string:
// message.Message是一个string
fmtf.Printf("Received string message: %s\n", msg)
fmtf.Printf("userid:[%v]Received string message: %s\n", message.UserID, msg)

//是否过滤群信息
if !config.GetGroupmessage() {
Expand All @@ -125,6 +125,11 @@ func (app *App) GensokyoHandler(w http.ResponseWriter, r *http.Request) {
}
}

if utils.BlacklistIntercept(message) {
fmtf.Printf("userid:[%v]这位用户在黑名单中,被拦截", message.UserID)
return
}

//处理重置指令
if isResetCommand {
fmtf.Println("处理重置操作")
Expand All @@ -134,55 +139,7 @@ func (app *App) GensokyoHandler(w http.ResponseWriter, r *http.Request) {
if !config.GetUsePrivateSSE() {
utils.SendPrivateMessage(message.UserID, RestoreResponse)
} else {

// 将字符串转换为rune切片,以正确处理多字节字符
runes := []rune(RestoreResponse)

// 计算每部分应该包含的rune数量
partLength := len(runes) / 3

// 初始化用于存储分割结果的切片
parts := make([]string, 3)

// 按字符分割字符串
for i := 0; i < 3; i++ {
if i < 2 { // 前两部分
start := i * partLength
end := start + partLength
parts[i] = string(runes[start:end])
} else { // 最后一部分,包含所有剩余的字符
start := i * partLength
parts[i] = string(runes[start:])
}
}

// 开头
messageSSE := structs.InterfaceBody{
Content: parts[0],
State: 1,
}

utils.SendPrivateMessageSSE(message.UserID, messageSSE)

//中间
messageSSE = structs.InterfaceBody{
Content: parts[1],
State: 11,
}
utils.SendPrivateMessageSSE(message.UserID, messageSSE)

// 从配置中获取promptkeyboard
promptkeyboard := config.GetPromptkeyboard()

// 创建InterfaceBody结构体实例
messageSSE = structs.InterfaceBody{
Content: parts[2], // 假设空格字符串是期望的内容
State: 20, // 假设的状态码
PromptKeyboard: promptkeyboard, // 使用更新后的promptkeyboard
}

// 发送SSE私人消息
utils.SendPrivateMessageSSE(message.UserID, messageSSE)
utils.SendSSEPrivateRestoreMessage(message.UserID, RestoreResponse)
}
} else {
utils.SendGroupMessage(message.GroupID, RestoreResponse)
Expand Down Expand Up @@ -282,6 +239,10 @@ func (app *App) GensokyoHandler(w http.ResponseWriter, r *http.Request) {
responseText, err := app.GetRandomAnswer(similarTexts[0])
if err == nil {
fmtf.Printf("缓存命中,Q:%v,A:%v\n", newmsg, responseText)
//加入上下文
if app.AddSingleContext(message, responseText) {
fmtf.Printf("缓存加入上下文成功")
}
// 发送响应消息
if message.RealMessageType == "group_private" || message.MessageType == "private" {
if !config.GetUsePrivateSSE() {
Expand Down
50 changes: 50 additions & 0 deletions applogic/singlecontext.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package applogic

import (
"time"

"github.com/hoshinonyaruko/gensokyo-llm/fmtf"
"github.com/hoshinonyaruko/gensokyo-llm/structs"
)

// 直接根据缓存来储存上下文
// 其实向量缓存是一个单轮的QA缓存,因为这个项目很初步,很显然无法应对上下文场景的缓存
// 通过这种方式,将每次缓存的内容也加入上下文,可能会有一个初步的效果提升.
func (app *App) AddSingleContext(message structs.OnebotGroupMessage, responseText string) bool {
// 请求conversation api 增加当前用户上下文
conversationID, parentMessageID, err := app.handleUserContext(message.UserID)
if err != nil {
fmtf.Printf("error in AddSingleContext app.handleUserContex :%v", err)
return false
}

// 构造用户消息并添加到上下文
userMessage := structs.Message{
ConversationID: conversationID,
ParentMessageID: parentMessageID,
Text: message.Message.(string),
Role: "user",
CreatedAt: time.Now().Format(time.RFC3339),
}
userMessageID, err := app.addMessage(userMessage)
if err != nil {
fmtf.Printf("error in AddSingleContext app.addMessage(userMessage) :%v", err)
return false
}

// 构造助理消息并添加到上下文
assistantMessage := structs.Message{
ConversationID: conversationID,
ParentMessageID: userMessageID,
Text: responseText,
Role: "assistant",
CreatedAt: time.Now().Format(time.RFC3339),
}
_, err = app.addMessage(assistantMessage)
if err != nil {
fmtf.Printf("error in AddSingleContext app.addMessage(assistantMessage) :%v", err)
return false
}

return true
}
17 changes: 17 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ type Settings struct {
LanguagesResponseMessages []string `yaml:"langResponseMessages"`
QuestionMaxLenth int `yaml:"questionMaxLenth"`
QmlResponseMessages []string `yaml:"qmlResponseMessages"`
BlacklistResponseMessages []string `yaml:"blacklistResponseMessages"`
}

// LoadConfig 从文件中加载配置并初始化单例配置
Expand Down Expand Up @@ -850,3 +851,19 @@ func GetQmlResponseMessages() string {
}
return "" // 如果列表为空,返回空字符串
}

// BlacklistResponseMessages 返回语言拦截响应消息列表
func GetBlacklistResponseMessages() string {
mu.Lock()
defer mu.Unlock()
if instance != nil && len(instance.Settings.BlacklistResponseMessages) > 0 {
// 如果列表中只有一个消息,直接返回这个消息
if len(instance.Settings.BlacklistResponseMessages) == 1 {
return instance.Settings.BlacklistResponseMessages[0]
}
// 如果有多个消息,随机选择一个返回
index := rand.Intn(len(instance.Settings.BlacklistResponseMessages))
return instance.Settings.BlacklistResponseMessages[index]
}
return "" // 如果列表为空,返回空字符串
}
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ require (
)

require github.com/abadojack/whatlanggo v1.0.1

require (
github.com/fsnotify/fsnotify v1.7.0 // indirect
golang.org/x/sys v0.4.0 // indirect
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
github.com/abadojack/whatlanggo v1.0.1 h1:19N6YogDnf71CTHm3Mp2qhYfkRdyvbgwWdd2EPxJRG4=
github.com/abadojack/whatlanggo v1.0.1/go.mod h1:66WiQbSbJBIlOZMsvbKe5m6pzQovxCH9B/K8tQB2uoc=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI=
github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.839 h1:VGVFNQDaUpDsPkJrh8I9qOxHZ1yj5sJmg9ngsUvTAHM=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.839/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
56 changes: 44 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"log"
"net/http"
"os"
"path/filepath"

_ "github.com/mattn/go-sqlite3" // 只导入,作为驱动

Expand All @@ -19,25 +20,41 @@ import (
)

func main() {
testFlag := flag.Bool("test", false, "Run the test script,test.txt中的是虚拟信息,一行一条")
testFlag := flag.Bool("test", false, "Run the test script, test.txt中的是虚拟信息,一行一条")
ymlPath := flag.String("yml", "", "指定config.yml的路径")
flag.Parse()

if _, err := os.Stat("config.yml"); os.IsNotExist(err) {
// 如果用户指定了-yml参数
configFilePath := "config.yml" // 默认配置文件路径
if *ymlPath != "" {
configFilePath = *ymlPath
}

// 将修改后的配置写入 config.yml
err = os.WriteFile("config.yml", []byte(template.ConfigTemplate), 0644)
if err != nil {
fmtf.Println("Error writing config.yml:", err)
// 检查配置文件是否存在
if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
if *ymlPath == "" {
// 用户没有指定-yml参数,按照默认行为处理
err = os.WriteFile(configFilePath, []byte(template.ConfigTemplate), 0644)
if err != nil {
fmtf.Println("Error writing config.yml:", err)
return
}
fmtf.Println("请配置config.yml然后再次运行.")
fmtf.Print("按下 Enter 继续...")
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(0)
} else {
// 用户指定了-yml参数,但指定的文件不存在
fmtf.Println("指定的配置文件不存在:", *ymlPath)
return
}

fmtf.Println("请配置config.yml然后再次运行.")
fmtf.Print("按下 Enter 继续...")
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(0)
} else {
if *ymlPath != "" {
fmtf.Println("载入成功:", *ymlPath)
}
}
// 加载配置
conf, err := config.LoadConfig("config.yml")
conf, err := config.LoadConfig(configFilePath)
if err != nil {
log.Fatalf("error: %v", err)
}
Expand Down Expand Up @@ -125,6 +142,21 @@ func main() {
log.Printf("Unknown API type: %d", apiType)
}

exePath, err := os.Executable()
if err != nil {
log.Fatal(err)
}
exeDir := filepath.Dir(exePath)
blacklistPath := filepath.Join(exeDir, "blacklist.txt")

// 载入黑名单
if err := utils.LoadBlacklist(blacklistPath); err != nil {
log.Fatalf("Failed to load blacklist: %v", err)
}

// 启动黑名单文件变动监听
go utils.WatchBlacklist(blacklistPath)

http.HandleFunc("/gensokyo", app.GensokyoHandler)
port := config.GetPort()
portStr := fmtf.Sprintf(":%d", port)
Expand Down
3 changes: 2 additions & 1 deletion template/config_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ settings:
promptkeyboard : [""] #临时的promptkeyboard超过3个则随机,后期会增加一个ai生成的方式,也会是ai-agent
savelogs : false #本地落地日志.
#语言过滤
allowedLanguages : ["Cmn"] #根据自身安全实力,酌情过滤,cmn代表中文,小写字母,[]空数组代表不限制.
allowedLanguages : ["cmn"] #根据自身安全实力,酌情过滤,cmn代表中文,小写字母,[]空数组代表不限制.
langResponseMessages : ["抱歉,我不会**这个语言呢","我不会**这门语言,请使用中文和我对话吧"] #定型文,**会自动替换为检测到的语言
questionMaxLenth : 100 #最大问题字数. 0代表不限制
qmlResponseMessages : ["问题太长了,缩短问题试试吧"] #最大问题长度回复.
blacklistResponseMessages : ["目前正在维护中...请稍候再试吧"] #黑名单回复,将userid丢入blacklist.txt 一行一个
#向量缓存(省钱-酌情调整参数)(进阶!!)需要有一定的调试能力,数据库调优能力,计算和数据测试能力.
#不同种类的向量,维度和模型不同,所以请一开始决定好使用的向量,或者自行将数据库备份\对应,不同种类向量没有互相检索的能力。
Expand Down
Loading
Loading