diff --git a/server/service/app/conversation.go b/server/service/app/conversation.go index 68f8c5f..ab916f1 100644 --- a/server/service/app/conversation.go +++ b/server/service/app/conversation.go @@ -791,6 +791,28 @@ func (s *ConversationService) SendMessageStream(userID, conversationID uint, req if streamPreset != nil && streamPreset.SystemPrompt != "" { systemPrompt = systemPrompt + "\n\n" + streamPreset.SystemPrompt } + + // 集成世界书触发引擎(流式传输) + if conversation.WorldbookEnabled && conversation.WorldbookID != nil { + global.GVA_LOG.Info(fmt.Sprintf("[流式传输] 世界书已启用,ID: %d", *conversation.WorldbookID)) + + var messageContents []string + for _, msg := range messages { + messageContents = append(messageContents, msg.Content) + } + + engine := &WorldbookEngine{} + triggeredEntries, wbErr := engine.ScanAndTrigger(*conversation.WorldbookID, messageContents) + if wbErr != nil { + global.GVA_LOG.Warn(fmt.Sprintf("[流式传输] 世界书触发失败: %v", wbErr)) + } else if len(triggeredEntries) > 0 { + global.GVA_LOG.Info(fmt.Sprintf("[流式传输] 触发了 %d 个世界书条目", len(triggeredEntries))) + systemPrompt = engine.BuildPromptWithWorldbook(systemPrompt, triggeredEntries) + } else { + global.GVA_LOG.Info("[流式传输] 没有触发任何世界书条目") + } + } + apiMessages := s.buildAPIMessages(messages, systemPrompt) // 打印发送给AI的完整内容(流式传输) diff --git a/web-app/src/App.tsx b/web-app/src/App.tsx index b1f84bb..963357a 100644 --- a/web-app/src/App.tsx +++ b/web-app/src/App.tsx @@ -11,6 +11,7 @@ import ProfilePage from './pages/ProfilePage' import CharacterManagePage from './pages/CharacterManagePage' import PresetManagePage from './pages/PresetManagePage' import WorldbookManagePage from './pages/WorldbookManagePage' +import RegexScriptManagePage from './pages/RegexScriptManagePage' import AdminPage from './pages/AdminPage' function App() { @@ -29,6 +30,7 @@ function App() { } /> } /> } /> + } /> } /> diff --git a/web-app/src/components/MessageContent.tsx b/web-app/src/components/MessageContent.tsx index e72ffc9..4532efa 100644 --- a/web-app/src/components/MessageContent.tsx +++ b/web-app/src/components/MessageContent.tsx @@ -173,13 +173,10 @@ export default function MessageContent({ content, role, onChoiceSelect }: Messag useEffect(() => { console.log('[MessageContent] 原始内容:', content) - // 提取 markdown 代码块中的 HTML,并从原始内容中移除代码块标记 - // 支持 ```html 和不带标识符的 ``` 包裹(后者在内容含 HTML 标签时识别为 HTML 块) + // 提取 markdown 代码块中的 HTML(仅识别 ```html 标识符的代码块) let processedContent = content let remainingContent = content let isHtmlCodeBlock = false - const htmlTagRegex = /<[a-zA-Z][^>]*>/ - // 先尝试匹配 ```html 代码块 const explicitHtmlRegex = /```html\s*([\s\S]*?)```/gi const htmlCodeBlocks: string[] = [] let htmlMatch @@ -195,24 +192,6 @@ export default function MessageContent({ content, role, onChoiceSelect }: Messag isHtmlCodeBlock = true console.log('[MessageContent] 提取到 ```html 代码块:', processedContent) console.log('[MessageContent] 剩余内容:', remainingContent) - } else { - // 尝试匹配无语言标识的 ``` 代码块,内容含 HTML 标签时也视为 HTML 块 - const genericCodeRegex = /```\s*\n?([\s\S]*?)```/g - const genericBlocks: string[] = [] - let genericMatch - while ((genericMatch = genericCodeRegex.exec(content)) !== null) { - const blockContent = genericMatch[1].trim() - if (htmlTagRegex.test(blockContent)) { - genericBlocks.push(blockContent) - } - } - if (genericBlocks.length > 0) { - processedContent = genericBlocks.join('\n') - remainingContent = content.replace(/```\s*\n?[\s\S]*?```/g, '').trim() - isHtmlCodeBlock = true - console.log('[MessageContent] 提取到通用 HTML 代码块:', processedContent) - console.log('[MessageContent] 剩余内容:', remainingContent) - } } // 解析状态面板