Skip to content

Commit

Permalink
Beta120 (#118)
Browse files Browse the repository at this point in the history
* beta1

* beta2

* beta3

* beta4

* beta5

* beta6

* beta7

* beta8

* beta9

* beta10

* beta11

* beta12

* beta13

* beta14

* beta15

* beta16

* beta16

* beta19

* beta20

* beta21

* beta22

* beta23

* beta24

* beta25

* beta27

* beta28

* beta29

* beta30

* beta31

* beta33

* beta34

* beta35

* beta36

* beta37

* beta38

* beta39

* beta40

* beta41

* beta42

* beta43

* beta44

* beta45

* beta45

* beta46

* beat48

* beta49

* beta50

* beta51

* beta52

* beta53

* beta54

* beta55

* beta57

* beta58

* beta59

* beta61

* beta62

* beta63

* beta63

* beta64

* beta65

* beta66

* beta67

* beta70

* beta71

* beta72

* beta72

* beta74

* beta75

* beta76

* beta77

* beta78

* beta79

* beta80

* beta81

* beta82

* beta83

* beta85

* beta86

* beta87

* beta88

* beta89

* beta90

* beta91

* beta92

* beta93

* beta94

* beta94

* beta96

* beta97

* beta98

* beta99

* beta100

* beta101

* beta102

* beta104

* beta105

* beta106

* beta107

* beta108

* beta109

* beta110

* beta111

* beta112

* beta113

* beta115

* beta116

* beta117

* beta118

* beta119

* beta120
  • Loading branch information
Hoshinonyaruko authored May 19, 2024
1 parent 4a09fba commit d1053df
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 32 deletions.
12 changes: 4 additions & 8 deletions applogic/gensokyo.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,18 +206,14 @@ func (app *App) GensokyoHandler(w http.ResponseWriter, r *http.Request) {
}
}

// 读取URL参数 "selfid"
selfid := r.URL.Query().Get("selfid")
if selfid != "" {
// 使用 prompt 变量进行后续处理
fmt.Printf("收到selfid参数: %s\n", selfid)
}
// 直接从ob11事件获取selfid
selfid := strconv.FormatInt(message.SelfID, 10)

// 读取URL参数 "api"
api := r.URL.Query().Get("api")
if selfid != "" {
if api != "" {
// 使用 prompt 变量进行后续处理
fmt.Printf("收到api参数: %s\n", selfid)
fmt.Printf("收到api参数: %s\n", api)
}

// 打印日志信息,包括prompt参数
Expand Down
10 changes: 10 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,16 @@ func IPWhiteList() []string {
return nil
}

// 获取HttpPaths
func GetHttpPaths() []string {
mu.Lock()
defer mu.Unlock()
if instance != nil {
return instance.Settings.HttpPaths
}
return nil
}

// 获取最大上下文
func GetMaxTokensHunyuan(options ...string) int {
mu.Lock()
Expand Down
5 changes: 5 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,11 @@ func main() {
log.Fatalf("Failed to load blacklist: %v", err)
}

// 判断是否设置多个http地址,获取对应关系
if len(config.GetHttpPaths()) > 0 {
utils.FetchAndStoreUserIDs()
}

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

Expand Down
28 changes: 18 additions & 10 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,6 @@ _✨ 适用于Gensokyo以及Onebotv11的大模型一键端 ✨_

并发环境下的sse内存安全,支持维持多用户同时双向sse传输

---

## 效果

![效果图](/pic/3.png)

![效果图](/pic/4.png)

---

## 支持llm平台

腾讯混元
Expand Down Expand Up @@ -117,6 +107,14 @@ AhoCorasick算法实现的超高效文本IN-Out替换规则,可大量替换n

支持中间件开发,在gensokyo框架层到gensokyo-llm的http请求之间,可开发中间件实现向量拓展,数据库拓展,动态修改用户问题.

支持反向ws连接,支持同时连接多个onebotv11的http-api

---

## 使用教程

施工中...(部署非常简单,有一定onebotv11机器人部署经验者可参考config.yml注释直接部署出来.)

---

# API接口调用说明
Expand Down Expand Up @@ -285,6 +283,16 @@ exitOnQ需要enhancedPromptChoices=true,其实enhancedPromptChoices最好就是t

promptMarks和switchOnQ、switchOnA在功能上是相同的,都是根据关键字跳转分支,promptMarks先执行,不分轮次不分QA,switchOnQ和switchOnA更具体,区分Q和A,区分轮次,实现细节跳转。

---

## 故事模式效果(QQ开放平台)

![效果图](/pic/3.png)

![效果图](/pic/4.png)

---

## 已知问题

如果有固定且不需要切换的分支,请设置该yml的promptMarksLength为99999
Expand Down
45 changes: 41 additions & 4 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,49 @@ var upgrader = websocket.Upgrader{
},
}

// 全局变量和互斥锁
var (
selfIDs []string
selfIDsMu sync.Mutex
)

// AddSelfID 添加一个 ID 到全局切片中
func AddSelfID(id string) {
selfIDsMu.Lock()
defer selfIDsMu.Unlock()
selfIDs = append(selfIDs, id)
}

// GetSelfIDs 返回当前保存的所有 ID
func GetSelfIDs() []string {
selfIDsMu.Lock()
defer selfIDsMu.Unlock()
// 返回切片的副本以防止外部修改
copiedIDs := make([]string, len(selfIDs))
copy(copiedIDs, selfIDs)
return copiedIDs
}

// IsSelfIDExists 检查一个 ID 是否存在于全局切片中
func IsSelfIDExists(id string) bool {
selfIDsMu.Lock()
defer selfIDsMu.Unlock()
for _, sid := range selfIDs {
if sid == id {
return true
}
}
return false
}

// 用于处理WebSocket连接
func WsHandler(w http.ResponseWriter, r *http.Request, config *config.Config) {
// 从请求头或URL查询参数中提取token
tokenFromHeader := r.Header.Get("Authorization")
selfID := r.Header.Get("X-Self-ID")
fmtf.Printf("接入机器人X-Self-ID[%v]", selfID)
// 加入到数组里
AddSelfID(selfID)
var token string
if strings.HasPrefix(tokenFromHeader, "Token ") {
token = strings.TrimPrefix(tokenFromHeader, "Token ")
Expand Down Expand Up @@ -86,13 +123,13 @@ func WsHandler(w http.ResponseWriter, r *http.Request, config *config.Config) {
}

if messageType == websocket.TextMessage {
processWSMessage(p, selfID)
processWSMessage(p)
}
}
}

// 处理收到的信息
func processWSMessage(msg []byte, selfid string) {
func processWSMessage(msg []byte) {
var genericMap map[string]interface{}
if err := json.Unmarshal(msg, &genericMap); err != nil {
log.Printf("Error unmarshalling message to map: %v, Original message: %s\n", err, string(msg))
Expand Down Expand Up @@ -131,9 +168,9 @@ func processWSMessage(msg []byte, selfid string) {
// 构造请求URL
var url string
if config.GetLotus() == "" {
url = "http://127.0.0.1:" + fmt.Sprint(port) + "/gensokyo?selfid=" + selfid
url = "http://127.0.0.1:" + fmt.Sprint(port) + "/gensokyo"
} else {
url = config.GetLotus() + "/gensokyo?selfid=" + selfid
url = config.GetLotus() + "/gensokyo"
}

// 创建POST请求
Expand Down
1 change: 1 addition & 0 deletions structs/struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ type Settings struct {
Port int `yaml:"port"`
SelfPath string `yaml:"selfPath"`
HttpPath string `yaml:"path"`
HttpPaths []string `yaml:"paths"`
Lotus string `yaml:"lotus"`
PathToken string `yaml:"pathToken"`
SystemPrompt []string `yaml:"systemPrompt"`
Expand Down
1 change: 1 addition & 0 deletions template/config_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ settings:
port : 46233 #本程序监听端口,支持gensokyo http上报, 请在gensokyo的反向http配置加入 post_url: ["http://127.0.0.1:port/gensokyo"]
selfPath : "" #本程序监听地址,不包含http头,请放通port到公网,仅发图场景需要填写,可以是域名,暂不支持https.
path : "http://123.123.123.123:11111" #调用gensokyo api的地址,填入 gensokyo 的 正向http地址 http_address: "0.0.0.0:46231" 对应填入 "http://127.0.0.1:46231"
paths : [] #当要连接多个onebotv11的http正向地址时,多个地址填入这里.
lotus : "" #当填写另一个gensokyo-llm的http地址时,将请求另一个的conversation端点,实现多个llm不需要多次配置,简化配置,单独使用请忽略留空.例:http://192.168.0.1:12345(包含http头和端口)
pathToken : "" #gensokyo正向http-api的access_token(是onebotv11标准的)
apiType : 0 #0=混元 1=文心(文心平台包含了N种模型...) 2=gpt 3=rwkv 4=通义千问 5=智谱AI
Expand Down
86 changes: 76 additions & 10 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,57 @@ type MessageIDInfo struct {
var UserIDMessageIDs = make(map[int64][]MessageIDInfo)
var muUserIDMessageIDs sync.RWMutex // 用于UserIDMessageIDs的读写锁

var (
baseURLMap = make(map[string]string)
baseURLMapMu sync.Mutex
)

// 结构体用于解析 JSON 响应
type loginInfoResponse struct {
Status string `json:"status"`
Retcode int `json:"retcode"`
Data struct {
UserID int64 `json:"user_id"`
Nickname string `json:"nickname"`
} `json:"data"`
}

// 构造 URL 并请求数据
func FetchAndStoreUserIDs() {
httpPaths := config.GetHttpPaths()
for _, baseURL := range httpPaths {
url := baseURL + "/get_login_info"
resp, err := http.Get(url)
if err != nil {
fmtf.Printf("Error fetching login info from %s: %v", url, err)
continue
}
defer resp.Body.Close()

var result loginInfoResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
fmtf.Printf("Error decoding response from %s: %v", url, err)
continue
}

if result.Retcode == 0 && result.Status == "ok" {
fmtf.Printf("成功绑定机器人selfid[%v]onebot api baseURL[%v]", result.Data.UserID, baseURL)
baseURLMapMu.Lock()
useridstr := strconv.FormatInt(result.Data.UserID, 10)
baseURLMap[useridstr] = baseURL
baseURLMapMu.Unlock()
}
}
}

// GetBaseURLByUserID 通过 user_id 获取 baseURL
func GetBaseURLByUserID(userID string) (string, bool) {
baseURLMapMu.Lock()
defer baseURLMapMu.Unlock()
url, exists := baseURLMap[userID]
return url, exists
}

func GenerateUUID() string {
return uuid.New().String()
}
Expand Down Expand Up @@ -158,7 +209,7 @@ func ExtractEventDetails(eventData map[string]interface{}) (string, structs.Usag

func SendGroupMessage(groupID int64, userID int64, message string, selfid string) error {
//TODO: 用userid作为了echo,在ws收到回调信息的时候,加入到全局撤回数组,AddMessageID,实现撤回
if selfid != "" {
if server.IsSelfIDExists(selfid) {
// 创建消息结构体
msg := map[string]interface{}{
"action": "send_group_msg",
Expand All @@ -173,8 +224,13 @@ func SendGroupMessage(groupID int64, userID int64, message string, selfid string
// 发送消息
return server.SendMessageBySelfID(selfid, msg)
}
// 获取基础URL
baseURL := config.GetHttpPath() // 假设config.getHttpPath()返回基础URL
var baseURL string
if len(config.GetHttpPaths()) > 0 {
baseURL, _ = GetBaseURLByUserID(selfid)
} else {
// 获取基础URL
baseURL = config.GetHttpPath() // 假设config.getHttpPath()返回基础URL
}

// 构建完整的URL
baseURL = baseURL + "/send_group_msg"
Expand Down Expand Up @@ -255,7 +311,7 @@ func SendGroupMessage(groupID int64, userID int64, message string, selfid string

func SendGroupMessageMdPromptKeyboard(groupID int64, userID int64, message string, selfid string, newmsg string, response string, promptstr string) error {
//TODO: 用userid作为了echo,在ws收到回调信息的时候,加入到全局撤回数组,AddMessageID,实现反向ws连接时候的撤回
if selfid != "" {
if server.IsSelfIDExists(selfid) {
// 创建消息结构体
msg := map[string]interface{}{
"action": "send_group_msg",
Expand Down Expand Up @@ -493,7 +549,7 @@ func SendGroupMessageMdPromptKeyboard(groupID int64, userID int64, message strin
}

func SendPrivateMessage(UserID int64, message string, selfid string) error {
if selfid != "" {
if server.IsSelfIDExists(selfid) {
// 创建消息结构体
msg := map[string]interface{}{
"action": "send_private_msg",
Expand All @@ -507,8 +563,13 @@ func SendPrivateMessage(UserID int64, message string, selfid string) error {
// 发送消息
return server.SendMessageBySelfID(selfid, msg)
}
// 获取基础URL
baseURL := config.GetHttpPath() // 假设config.getHttpPath()返回基础URL
var baseURL string
if len(config.GetHttpPaths()) > 0 {
baseURL, _ = GetBaseURLByUserID(selfid)
} else {
// 获取基础URL
baseURL = config.GetHttpPath() // 假设config.getHttpPath()返回基础URL
}

// 构建完整的URL
baseURL = baseURL + "/send_private_msg"
Expand Down Expand Up @@ -587,7 +648,7 @@ func SendPrivateMessage(UserID int64, message string, selfid string) error {
}

func SendPrivateMessageRaw(UserID int64, message string, selfid string) error {
if selfid != "" {
if server.IsSelfIDExists(selfid) {
// 创建消息结构体
msg := map[string]interface{}{
"action": "send_private_msg",
Expand All @@ -601,8 +662,13 @@ func SendPrivateMessageRaw(UserID int64, message string, selfid string) error {
// 发送消息
return server.SendMessageBySelfID(selfid, msg)
}
// 获取基础URL
baseURL := config.GetHttpPath() // 假设config.getHttpPath()返回基础URL
var baseURL string
if len(config.GetHttpPaths()) > 0 {
baseURL, _ = GetBaseURLByUserID(selfid)
} else {
// 获取基础URL
baseURL = config.GetHttpPath() // 假设config.getHttpPath()返回基础URL
}

// 构建完整的URL
baseURL = baseURL + "/send_private_msg"
Expand Down

0 comments on commit d1053df

Please sign in to comment.