@@ -791,6 +791,28 @@ func (s *ConversationService) SendMessageStream(userID, conversationID uint, req
|
|||||||
if streamPreset != nil && streamPreset.SystemPrompt != "" {
|
if streamPreset != nil && streamPreset.SystemPrompt != "" {
|
||||||
systemPrompt = systemPrompt + "\n\n" + 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)
|
apiMessages := s.buildAPIMessages(messages, systemPrompt)
|
||||||
|
|
||||||
// 打印发送给AI的完整内容(流式传输)
|
// 打印发送给AI的完整内容(流式传输)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import ProfilePage from './pages/ProfilePage'
|
|||||||
import CharacterManagePage from './pages/CharacterManagePage'
|
import CharacterManagePage from './pages/CharacterManagePage'
|
||||||
import PresetManagePage from './pages/PresetManagePage'
|
import PresetManagePage from './pages/PresetManagePage'
|
||||||
import WorldbookManagePage from './pages/WorldbookManagePage'
|
import WorldbookManagePage from './pages/WorldbookManagePage'
|
||||||
|
import RegexScriptManagePage from './pages/RegexScriptManagePage'
|
||||||
import AdminPage from './pages/AdminPage'
|
import AdminPage from './pages/AdminPage'
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@@ -29,6 +30,7 @@ function App() {
|
|||||||
<Route path="/characters" element={<CharacterManagePage />} />
|
<Route path="/characters" element={<CharacterManagePage />} />
|
||||||
<Route path="/presets" element={<PresetManagePage />} />
|
<Route path="/presets" element={<PresetManagePage />} />
|
||||||
<Route path="/worldbooks" element={<WorldbookManagePage />} />
|
<Route path="/worldbooks" element={<WorldbookManagePage />} />
|
||||||
|
<Route path="/regex-scripts" element={<RegexScriptManagePage />} />
|
||||||
<Route path="/admin" element={<AdminPage />} />
|
<Route path="/admin" element={<AdminPage />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
|
|||||||
@@ -173,13 +173,10 @@ export default function MessageContent({ content, role, onChoiceSelect }: Messag
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('[MessageContent] 原始内容:', content)
|
console.log('[MessageContent] 原始内容:', content)
|
||||||
|
|
||||||
// 提取 markdown 代码块中的 HTML,并从原始内容中移除代码块标记
|
// 提取 markdown 代码块中的 HTML(仅识别 ```html 标识符的代码块)
|
||||||
// 支持 ```html 和不带标识符的 ``` 包裹(后者在内容含 HTML 标签时识别为 HTML 块)
|
|
||||||
let processedContent = content
|
let processedContent = content
|
||||||
let remainingContent = content
|
let remainingContent = content
|
||||||
let isHtmlCodeBlock = false
|
let isHtmlCodeBlock = false
|
||||||
const htmlTagRegex = /<[a-zA-Z][^>]*>/
|
|
||||||
// 先尝试匹配 ```html 代码块
|
|
||||||
const explicitHtmlRegex = /```html\s*([\s\S]*?)```/gi
|
const explicitHtmlRegex = /```html\s*([\s\S]*?)```/gi
|
||||||
const htmlCodeBlocks: string[] = []
|
const htmlCodeBlocks: string[] = []
|
||||||
let htmlMatch
|
let htmlMatch
|
||||||
@@ -195,24 +192,6 @@ export default function MessageContent({ content, role, onChoiceSelect }: Messag
|
|||||||
isHtmlCodeBlock = true
|
isHtmlCodeBlock = true
|
||||||
console.log('[MessageContent] 提取到 ```html 代码块:', processedContent)
|
console.log('[MessageContent] 提取到 ```html 代码块:', processedContent)
|
||||||
console.log('[MessageContent] 剩余内容:', remainingContent)
|
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析状态面板
|
// 解析状态面板
|
||||||
|
|||||||
Reference in New Issue
Block a user