🎨 完善正则脚本功能

Signed-off-by: Echo <1711788888@qq.com>
This commit is contained in:
2026-03-02 00:51:23 +08:00
parent 23396caeeb
commit de6015c77e
3 changed files with 93 additions and 14 deletions

View File

@@ -90,11 +90,20 @@ func (s *ConversationService) CreateConversation(userID uint, req *request.Creat
// 如果角色有开场白,创建开场白消息
if character.FirstMes != "" {
// 应用输出阶段正则脚本处理开场白
processedFirstMes := character.FirstMes
var regexService RegexScriptService
outputScripts, err := regexService.GetScriptsForPlacement(userID, 1, &character.ID, nil)
if err == nil && len(outputScripts) > 0 {
processedFirstMes = regexService.ExecuteScripts(outputScripts, processedFirstMes, "", character.Name)
global.GVA_LOG.Info(fmt.Sprintf("开场白应用正则脚本: 原始长度=%d, 处理后长度=%d", len(character.FirstMes), len(processedFirstMes)))
}
firstMessage := app.Message{
ConversationID: conversation.ID,
Role: "assistant",
Content: character.FirstMes,
TokenCount: len(character.FirstMes) / 4,
Content: processedFirstMes,
TokenCount: len(processedFirstMes) / 4,
}
err = global.GVA_DB.Create(&firstMessage).Error
if err != nil {
@@ -316,12 +325,27 @@ func (s *ConversationService) SendMessage(userID, conversationID uint, req *requ
return nil, errors.New("角色卡不存在")
}
// 应用输入阶段的正则脚本 (Placement 0)
processedContent := req.Content
var regexService RegexScriptService
global.GVA_LOG.Info(fmt.Sprintf("查询输入阶段正则脚本: userID=%d, placement=0, charID=%d", userID, conversation.CharacterID))
inputScripts, err := regexService.GetScriptsForPlacement(userID, 0, &conversation.CharacterID, nil)
if err != nil {
global.GVA_LOG.Error(fmt.Sprintf("查询输入阶段正则脚本失败: %v", err))
} else {
global.GVA_LOG.Info(fmt.Sprintf("找到 %d 个输入阶段正则脚本", len(inputScripts)))
if len(inputScripts) > 0 {
processedContent = regexService.ExecuteScripts(inputScripts, processedContent, "", character.Name)
global.GVA_LOG.Info(fmt.Sprintf("应用了 %d 个输入阶段正则脚本,原文: %s, 处理后: %s", len(inputScripts), req.Content, processedContent))
}
}
// 保存用户消息
userMessage := app.Message{
ConversationID: conversationID,
Role: "user",
Content: req.Content,
TokenCount: len(req.Content) / 4, // 简单估算
Content: processedContent,
TokenCount: len(processedContent) / 4, // 简单估算
}
err = global.GVA_DB.Create(&userMessage).Error
@@ -372,13 +396,23 @@ func (s *ConversationService) SendMessage(userID, conversationID uint, req *requ
return nil, err
}
// 应用显示阶段的正则脚本 (Placement 3)
displayContent := assistantMessage.Content
displayScripts, err := regexService.GetScriptsForPlacement(userID, 3, &conversation.CharacterID, nil)
if err == nil && len(displayScripts) > 0 {
displayContent = regexService.ExecuteScripts(displayScripts, displayContent, "", character.Name)
global.GVA_LOG.Info(fmt.Sprintf("应用了 %d 个显示阶段正则脚本", len(displayScripts)))
}
resp := response.ToMessageResponse(&assistantMessage)
resp.Content = displayContent // 使用处理后的显示内容
return &resp, nil
}
// callAIService 调用 AI 服务
func (s *ConversationService) callAIService(conversation app.Conversation, character app.AICharacter, messages []app.Message) (string, error) {
// 获取 AI 配置
var aiConfig app.AIConfig
var err error
@@ -521,6 +555,21 @@ func (s *ConversationService) callAIService(conversation app.Conversation, chara
}
global.GVA_LOG.Info(fmt.Sprintf("========== AI返回的完整内容 ==========\n%s\n==========================================", aiResponse))
// 应用输出阶段的正则脚本 (Placement 1)
var regexService RegexScriptService
global.GVA_LOG.Info(fmt.Sprintf("查询输出阶段正则脚本: userID=%d, placement=1, charID=%d", conversation.UserID, conversation.CharacterID))
outputScripts, err := regexService.GetScriptsForPlacement(conversation.UserID, 1, &conversation.CharacterID, nil)
if err != nil {
global.GVA_LOG.Error(fmt.Sprintf("查询输出阶段正则脚本失败: %v", err))
} else {
global.GVA_LOG.Info(fmt.Sprintf("找到 %d 个输出阶段正则脚本", len(outputScripts)))
if len(outputScripts) > 0 {
originalResponse := aiResponse
aiResponse = regexService.ExecuteScripts(outputScripts, aiResponse, "", character.Name)
global.GVA_LOG.Info(fmt.Sprintf("应用了 %d 个输出阶段正则脚本,原文: %s, 处理后: %s", len(outputScripts), originalResponse, aiResponse))
}
}
return aiResponse, nil
}
@@ -648,12 +697,27 @@ func (s *ConversationService) SendMessageStream(userID, conversationID uint, req
return errors.New("角色卡不存在")
}
// 应用输入阶段的正则脚本 (Placement 0)
processedContent := req.Content
var regexService RegexScriptService
global.GVA_LOG.Info(fmt.Sprintf("[流式传输] 查询输入阶段正则脚本: userID=%d, placement=0, charID=%d", userID, conversation.CharacterID))
inputScripts, err := regexService.GetScriptsForPlacement(userID, 0, &conversation.CharacterID, nil)
if err != nil {
global.GVA_LOG.Error(fmt.Sprintf("[流式传输] 查询输入阶段正则脚本失败: %v", err))
} else {
global.GVA_LOG.Info(fmt.Sprintf("[流式传输] 找到 %d 个输入阶段正则脚本", len(inputScripts)))
if len(inputScripts) > 0 {
processedContent = regexService.ExecuteScripts(inputScripts, processedContent, "", character.Name)
global.GVA_LOG.Info(fmt.Sprintf("[流式传输] 应用了 %d 个输入阶段正则脚本", len(inputScripts)))
}
}
// 保存用户消息
userMessage := app.Message{
ConversationID: conversationID,
Role: "user",
Content: req.Content,
TokenCount: len(req.Content) / 4,
Content: processedContent,
TokenCount: len(processedContent) / 4,
}
err = global.GVA_DB.Create(&userMessage).Error
@@ -768,6 +832,19 @@ func (s *ConversationService) SendMessageStream(userID, conversationID uint, req
// 打印AI返回的完整内容
global.GVA_LOG.Info(fmt.Sprintf("========== [流式传输] AI返回的完整内容 ==========\n%s\n==========================================", fullContent))
// 应用输出阶段的正则脚本 (Placement 1)
global.GVA_LOG.Info(fmt.Sprintf("[流式传输] 查询输出阶段正则脚本: userID=%d, placement=1, charID=%d", userID, conversation.CharacterID))
outputScripts, err := regexService.GetScriptsForPlacement(userID, 1, &conversation.CharacterID, nil)
if err != nil {
global.GVA_LOG.Error(fmt.Sprintf("[流式传输] 查询输出阶段正则脚本失败: %v", err))
} else {
global.GVA_LOG.Info(fmt.Sprintf("[流式传输] 找到 %d 个输出阶段正则脚本", len(outputScripts)))
if len(outputScripts) > 0 {
fullContent = regexService.ExecuteScripts(outputScripts, fullContent, "", character.Name)
global.GVA_LOG.Info(fmt.Sprintf("[流式传输] 应用了 %d 个输出阶段正则脚本", len(outputScripts)))
}
}
// 保存 AI 回复
assistantMessage := app.Message{
ConversationID: conversationID,

View File

@@ -254,14 +254,16 @@ func (s *RegexScriptService) GetScriptsForPlacement(userID uint, placement int,
db := global.GVA_DB.Where("user_id = ? AND placement = ? AND disabled = ?", userID, placement, false)
// 作用域过滤:全局(0) 或 角色(1) 或 预设(2)
scopeCondition := "scope = 0" // 全局
if charID != nil {
scopeCondition += " OR (scope = 1 AND owner_char_id = " + string(rune(*charID)) + ")"
// 使用参数化查询避免 SQL 注入
if charID != nil && presetID != nil {
db = db.Where("scope = 0 OR (scope = 1 AND owner_char_id = ?) OR (scope = 2 AND owner_preset_id = ?)", *charID, *presetID)
} else if charID != nil {
db = db.Where("scope = 0 OR (scope = 1 AND owner_char_id = ?)", *charID)
} else if presetID != nil {
db = db.Where("scope = 0 OR (scope = 2 AND owner_preset_id = ?)", *presetID)
} else {
db = db.Where("scope = 0")
}
if presetID != nil {
scopeCondition += " OR (scope = 2 AND owner_preset_id = " + string(rune(*presetID)) + ")"
}
db = db.Where(scopeCondition)
if err := db.Order("\"order\" ASC").Find(&scripts).Error; err != nil {
return nil, err