@@ -132,7 +132,7 @@ func (a *ConversationApi) UpdateConversationSettings(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = service.ServiceGroupApp.AppServiceGroup.ConversationService.UpdateConversationSettings(userID, uint(conversationID), req.Settings)
|
err = service.ServiceGroupApp.AppServiceGroup.ConversationService.UpdateConversationSettings(userID, uint(conversationID), &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
global.GVA_LOG.Error("更新对话设置失败", zap.Error(err))
|
global.GVA_LOG.Error("更新对话设置失败", zap.Error(err))
|
||||||
commonResponse.FailWithMessage(err.Error(), c)
|
commonResponse.FailWithMessage(err.Error(), c)
|
||||||
|
|||||||
@@ -19,10 +19,12 @@ type Conversation struct {
|
|||||||
Title string `gorm:"type:varchar(200)" json:"title"` // 对话标题
|
Title string `gorm:"type:varchar(200)" json:"title"` // 对话标题
|
||||||
|
|
||||||
// 对话配置
|
// 对话配置
|
||||||
PresetID *uint `gorm:"index" json:"presetId"` // 使用的预设ID
|
PresetID *uint `gorm:"index" json:"presetId"` // 使用的预设ID
|
||||||
AIProvider string `gorm:"type:varchar(50)" json:"aiProvider"` // AI提供商 (openai/anthropic)
|
WorldbookID *uint `gorm:"index" json:"worldbookId"` // 使用的世界书ID
|
||||||
Model string `gorm:"type:varchar(100)" json:"model"` // 使用的模型
|
AIProvider string `gorm:"type:varchar(50)" json:"aiProvider"` // AI提供商 (openai/anthropic)
|
||||||
Settings datatypes.JSON `gorm:"type:jsonb" json:"settings"` // 对话设置 (temperature等)
|
Model string `gorm:"type:varchar(100)" json:"model"` // 使用的模型
|
||||||
|
Settings datatypes.JSON `gorm:"type:jsonb" json:"settings"` // 对话设置 (temperature等)
|
||||||
|
WorldbookEnabled bool `gorm:"default:false" json:"worldbookEnabled"` // 是否启用世界书
|
||||||
|
|
||||||
// 统计信息
|
// 统计信息
|
||||||
MessageCount int `gorm:"default:0" json:"messageCount"` // 消息数量
|
MessageCount int `gorm:"default:0" json:"messageCount"` // 消息数量
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ package request
|
|||||||
|
|
||||||
// CreateConversationRequest 创建对话请求
|
// CreateConversationRequest 创建对话请求
|
||||||
type CreateConversationRequest struct {
|
type CreateConversationRequest struct {
|
||||||
CharacterID uint `json:"characterId" binding:"required"`
|
CharacterID uint `json:"characterId" binding:"required"`
|
||||||
Title string `json:"title" binding:"max=200"`
|
Title string `json:"title" binding:"max=200"`
|
||||||
PresetID *uint `json:"presetId"`
|
PresetID *uint `json:"presetId"`
|
||||||
AIProvider string `json:"aiProvider" binding:"omitempty,oneof=openai anthropic"`
|
WorldbookID *uint `json:"worldbookId"`
|
||||||
Model string `json:"model"`
|
WorldbookEnabled bool `json:"worldbookEnabled"`
|
||||||
|
AIProvider string `json:"aiProvider" binding:"omitempty,oneof=openai anthropic"`
|
||||||
|
Model string `json:"model"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendMessageRequest 发送消息请求
|
// SendMessageRequest 发送消息请求
|
||||||
@@ -28,5 +30,7 @@ type GetMessageListRequest struct {
|
|||||||
|
|
||||||
// UpdateConversationSettingsRequest 更新对话设置请求
|
// UpdateConversationSettingsRequest 更新对话设置请求
|
||||||
type UpdateConversationSettingsRequest struct {
|
type UpdateConversationSettingsRequest struct {
|
||||||
Settings map[string]interface{} `json:"settings" binding:"required"`
|
Settings map[string]interface{} `json:"settings"`
|
||||||
|
WorldbookID *uint `json:"worldbookId"`
|
||||||
|
WorldbookEnabled *bool `json:"worldbookEnabled"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,17 +9,19 @@ import (
|
|||||||
|
|
||||||
// ConversationResponse 对话响应
|
// ConversationResponse 对话响应
|
||||||
type ConversationResponse struct {
|
type ConversationResponse struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
CharacterID uint `json:"characterId"`
|
CharacterID uint `json:"characterId"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
PresetID *uint `json:"presetId"`
|
PresetID *uint `json:"presetId"`
|
||||||
AIProvider string `json:"aiProvider"`
|
WorldbookID *uint `json:"worldbookId"`
|
||||||
Model string `json:"model"`
|
WorldbookEnabled bool `json:"worldbookEnabled"`
|
||||||
Settings map[string]interface{} `json:"settings,omitempty"`
|
AIProvider string `json:"aiProvider"`
|
||||||
MessageCount int `json:"messageCount"`
|
Model string `json:"model"`
|
||||||
TokenCount int `json:"tokenCount"`
|
Settings map[string]interface{} `json:"settings,omitempty"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
MessageCount int `json:"messageCount"`
|
||||||
UpdatedAt time.Time `json:"updatedAt"`
|
TokenCount int `json:"tokenCount"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
|
|
||||||
// 关联数据
|
// 关联数据
|
||||||
Character *CharacterResponse `json:"character,omitempty"`
|
Character *CharacterResponse `json:"character,omitempty"`
|
||||||
@@ -75,17 +77,19 @@ func ToConversationResponse(conv *app.Conversation) ConversationResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ConversationResponse{
|
return ConversationResponse{
|
||||||
ID: conv.ID,
|
ID: conv.ID,
|
||||||
CharacterID: conv.CharacterID,
|
CharacterID: conv.CharacterID,
|
||||||
Title: conv.Title,
|
Title: conv.Title,
|
||||||
PresetID: conv.PresetID,
|
PresetID: conv.PresetID,
|
||||||
AIProvider: conv.AIProvider,
|
WorldbookID: conv.WorldbookID,
|
||||||
Model: conv.Model,
|
WorldbookEnabled: conv.WorldbookEnabled,
|
||||||
Settings: settings,
|
AIProvider: conv.AIProvider,
|
||||||
MessageCount: conv.MessageCount,
|
Model: conv.Model,
|
||||||
TokenCount: conv.TokenCount,
|
Settings: settings,
|
||||||
CreatedAt: conv.CreatedAt,
|
MessageCount: conv.MessageCount,
|
||||||
UpdatedAt: conv.UpdatedAt,
|
TokenCount: conv.TokenCount,
|
||||||
|
CreatedAt: conv.CreatedAt,
|
||||||
|
UpdatedAt: conv.UpdatedAt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,13 +72,15 @@ func (s *ConversationService) CreateConversation(userID uint, req *request.Creat
|
|||||||
|
|
||||||
// 创建对话
|
// 创建对话
|
||||||
conversation := app.Conversation{
|
conversation := app.Conversation{
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
CharacterID: req.CharacterID,
|
CharacterID: req.CharacterID,
|
||||||
Title: title,
|
Title: title,
|
||||||
PresetID: req.PresetID,
|
PresetID: req.PresetID,
|
||||||
AIProvider: aiProvider,
|
WorldbookID: req.WorldbookID,
|
||||||
Model: model,
|
WorldbookEnabled: req.WorldbookEnabled,
|
||||||
Settings: datatypes.JSON("{}"),
|
AIProvider: aiProvider,
|
||||||
|
Model: model,
|
||||||
|
Settings: datatypes.JSON("{}"),
|
||||||
}
|
}
|
||||||
|
|
||||||
err = global.GVA_DB.Create(&conversation).Error
|
err = global.GVA_DB.Create(&conversation).Error
|
||||||
@@ -188,7 +190,7 @@ func (s *ConversationService) GetConversationByID(userID, conversationID uint) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateConversationSettings 更新对话设置
|
// UpdateConversationSettings 更新对话设置
|
||||||
func (s *ConversationService) UpdateConversationSettings(userID, conversationID uint, settings map[string]interface{}) error {
|
func (s *ConversationService) UpdateConversationSettings(userID, conversationID uint, req *request.UpdateConversationSettingsRequest) error {
|
||||||
var conversation app.Conversation
|
var conversation app.Conversation
|
||||||
err := global.GVA_DB.Where("id = ? AND user_id = ?", conversationID, userID).First(&conversation).Error
|
err := global.GVA_DB.Where("id = ? AND user_id = ?", conversationID, userID).First(&conversation).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -198,13 +200,32 @@ func (s *ConversationService) UpdateConversationSettings(userID, conversationID
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 序列化设置
|
updates := make(map[string]interface{})
|
||||||
settingsJSON, err := json.Marshal(settings)
|
|
||||||
if err != nil {
|
// 更新设置
|
||||||
return err
|
if req.Settings != nil {
|
||||||
|
settingsJSON, err := json.Marshal(req.Settings)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
updates["settings"] = datatypes.JSON(settingsJSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
return global.GVA_DB.Model(&conversation).Update("settings", datatypes.JSON(settingsJSON)).Error
|
// 更新世界书ID
|
||||||
|
if req.WorldbookID != nil {
|
||||||
|
updates["worldbook_id"] = req.WorldbookID
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新世界书启用状态
|
||||||
|
if req.WorldbookEnabled != nil {
|
||||||
|
updates["worldbook_enabled"] = *req.WorldbookEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(updates) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return global.GVA_DB.Model(&conversation).Updates(updates).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteConversation 删除对话
|
// DeleteConversation 删除对话
|
||||||
@@ -431,6 +452,30 @@ func (s *ConversationService) callAIService(conversation app.Conversation, chara
|
|||||||
global.GVA_LOG.Info("已追加预设的系统提示词")
|
global.GVA_LOG.Info("已追加预设的系统提示词")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 集成世界书触发引擎
|
||||||
|
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{}
|
||||||
|
triggered, err := engine.ScanAndTrigger(*conversation.WorldbookID, messageContents)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Warn(fmt.Sprintf("世界书触发失败: %v", err))
|
||||||
|
} else if len(triggered) > 0 {
|
||||||
|
global.GVA_LOG.Info(fmt.Sprintf("触发了 %d 个世界书条目", len(triggered)))
|
||||||
|
// 将触发的世界书内容注入到系统提示词
|
||||||
|
systemPrompt = engine.BuildPromptWithWorldbook(systemPrompt, triggered)
|
||||||
|
} else {
|
||||||
|
global.GVA_LOG.Info("没有触发任何世界书条目")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 构建消息列表
|
// 构建消息列表
|
||||||
apiMessages := s.buildAPIMessages(messages, systemPrompt)
|
apiMessages := s.buildAPIMessages(messages, systemPrompt)
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ export interface Conversation {
|
|||||||
characterId: number
|
characterId: number
|
||||||
title: string
|
title: string
|
||||||
presetId?: number
|
presetId?: number
|
||||||
|
worldbookId?: number
|
||||||
|
worldbookEnabled: boolean
|
||||||
aiProvider: string
|
aiProvider: string
|
||||||
model: string
|
model: string
|
||||||
settings?: Record<string, any>
|
settings?: Record<string, any>
|
||||||
@@ -50,6 +52,8 @@ export interface CreateConversationRequest {
|
|||||||
characterId: number
|
characterId: number
|
||||||
title?: string
|
title?: string
|
||||||
presetId?: number
|
presetId?: number
|
||||||
|
worldbookId?: number
|
||||||
|
worldbookEnabled?: boolean
|
||||||
aiProvider?: string
|
aiProvider?: string
|
||||||
model?: string
|
model?: string
|
||||||
settings?: Record<string, any>
|
settings?: Record<string, any>
|
||||||
@@ -103,8 +107,12 @@ export const conversationApi = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// 更新对话设置
|
// 更新对话设置
|
||||||
updateConversationSettings: (conversationId: number, settings: Record<string, any>) => {
|
updateConversationSettings: (conversationId: number, data: {
|
||||||
return apiClient.put(`/app/conversation/${conversationId}/settings`, { settings })
|
settings?: Record<string, any>
|
||||||
|
worldbookId?: number
|
||||||
|
worldbookEnabled?: boolean
|
||||||
|
}) => {
|
||||||
|
return apiClient.put(`/app/conversation/${conversationId}/settings`, data)
|
||||||
},
|
},
|
||||||
|
|
||||||
// 重新生成最后一条 AI 回复(非流式)
|
// 重新生成最后一条 AI 回复(非流式)
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ export default function ChatArea({ conversation, character, onConversationUpdate
|
|||||||
} else {
|
} else {
|
||||||
settings.presetId = presetId
|
settings.presetId = presetId
|
||||||
}
|
}
|
||||||
await conversationApi.updateConversationSettings(conversation.id, settings)
|
await conversationApi.updateConversationSettings(conversation.id, { settings })
|
||||||
setSelectedPresetId(presetId ?? undefined)
|
setSelectedPresetId(presetId ?? undefined)
|
||||||
setShowPresetSelector(false)
|
setShowPresetSelector(false)
|
||||||
const convResp = await conversationApi.getConversationById(conversation.id)
|
const convResp = await conversationApi.getConversationById(conversation.id)
|
||||||
@@ -170,7 +170,7 @@ export default function ChatArea({ conversation, character, onConversationUpdate
|
|||||||
} else {
|
} else {
|
||||||
settings.aiConfigId = configId
|
settings.aiConfigId = configId
|
||||||
}
|
}
|
||||||
await conversationApi.updateConversationSettings(conversation.id, settings)
|
await conversationApi.updateConversationSettings(conversation.id, { settings })
|
||||||
setSelectedConfigId(configId ?? undefined)
|
setSelectedConfigId(configId ?? undefined)
|
||||||
setShowModelSelector(false)
|
setShowModelSelector(false)
|
||||||
const convResp = await conversationApi.getConversationById(conversation.id)
|
const convResp = await conversationApi.getConversationById(conversation.id)
|
||||||
|
|||||||
Reference in New Issue
Block a user