Files
Enterprise-Knowledge-Base/internal/application/service/chat_pipeline/memory.go
T
wizardchen 052be53c42 feat(prompts): update assistant descriptions and add intent-specific templates
- Updated the assistant descriptions in various prompt templates to specify that they are developed by Tencent.
- Added new intent-specific system prompt templates for greeting, chitchat, follow-up, image analysis, summarization, and web search unavailability scenarios.
- Enhanced citation rules in the system prompts to ensure proper inline citation formatting.
- Refactored the rewrite prompt to classify user intent more accurately and output structured JSON responses.
2026-03-25 22:08:29 +08:00

149 lines
3.7 KiB
Go

package chatpipeline
import (
"context"
"fmt"
"github.com/Tencent/WeKnora/internal/event"
"github.com/Tencent/WeKnora/internal/logger"
"github.com/Tencent/WeKnora/internal/types"
"github.com/Tencent/WeKnora/internal/types/interfaces"
)
type MemoryPlugin struct {
memoryService interfaces.MemoryService
}
func NewMemoryPlugin(eventManager *EventManager, memoryService interfaces.MemoryService) *MemoryPlugin {
res := &MemoryPlugin{
memoryService: memoryService,
}
eventManager.Register(res)
return res
}
func (p *MemoryPlugin) ActivationEvents() []types.EventType {
return []types.EventType{
types.MEMORY_RETRIEVAL,
types.MEMORY_STORAGE,
}
}
func (p *MemoryPlugin) OnEvent(
ctx context.Context,
eventType types.EventType,
chatManage *types.ChatManage,
next func() *PluginError,
) *PluginError {
switch eventType {
case types.MEMORY_RETRIEVAL:
return p.handleRetrieval(ctx, chatManage, next)
case types.MEMORY_STORAGE:
return p.handleStorage(ctx, chatManage, next)
default:
return next()
}
}
func (p *MemoryPlugin) handleRetrieval(
ctx context.Context,
chatManage *types.ChatManage,
next func() *PluginError,
) *PluginError {
// Check if memory is enabled
if !chatManage.EnableMemory {
return next()
}
logger.Info(ctx, "Start to retrieve memory")
// Retrieve memory context
query := chatManage.RewriteQuery
if query == "" {
query = chatManage.Query
}
memoryContext, err := p.memoryService.RetrieveMemory(ctx, chatManage.UserID, query)
if err != nil {
logger.Errorf(ctx, "failed to retrieve memory: %v", err)
// Don't block the pipeline if memory retrieval fails
return next()
}
// Add memory context to chatManage
if len(memoryContext.RelatedEpisodes) > 0 {
memoryStr := "\n\nRelevant Memory:\n"
for _, ep := range memoryContext.RelatedEpisodes {
memoryStr += fmt.Sprintf("- %s (Summary: %s)\n", ep.CreatedAt.Format("2006-01-02"), ep.Summary)
}
chatManage.UserContent += memoryStr
logger.Infof(ctx, "Retrieved memory: %s", memoryStr)
}
logger.Info(ctx, "End to retrieve memory")
return next()
}
func (p *MemoryPlugin) handleStorage(
ctx context.Context,
chatManage *types.ChatManage,
next func() *PluginError,
) *PluginError {
if err := next(); err != nil {
return err
}
// Check if memory is enabled
if !chatManage.EnableMemory {
return nil
}
logger.Info(ctx, "Start to store memory")
// If ChatResponse is already available (non-streaming), store it directly
if chatManage.ChatResponse != nil {
messages := []types.Message{
{Role: "user", Content: chatManage.Query},
{Role: "assistant", Content: chatManage.ChatResponse.Content},
}
userID := chatManage.UserID
sessionID := chatManage.SessionID
bgCtx := context.WithoutCancel(ctx)
go func() {
if err := p.memoryService.AddEpisode(bgCtx, userID, sessionID, messages); err != nil {
logger.Errorf(bgCtx, "failed to add episode: %v", err)
}
}()
return nil
}
// If streaming, subscribe to events
if chatManage.EventBus != nil {
var fullResponse string
userID := chatManage.UserID
sessionID := chatManage.SessionID
bgCtx := context.WithoutCancel(ctx)
chatManage.EventBus.On(types.EventType(event.EventAgentFinalAnswer), func(_ context.Context, evt types.Event) error {
data, ok := evt.Data.(event.AgentFinalAnswerData)
if !ok {
return nil
}
fullResponse += data.Content
if data.Done {
messages := []types.Message{
{Role: "user", Content: chatManage.Query},
{Role: "assistant", Content: fullResponse},
}
go func() {
if err := p.memoryService.AddEpisode(bgCtx, userID, sessionID, messages); err != nil {
logger.Errorf(bgCtx, "failed to add episode: %v", err)
}
}()
}
return nil
})
}
logger.Info(ctx, "End to store memory")
return nil
}