SaveSessionToSemanticMemory 从指定 Session 中抽取对话内容,并写入语义记忆。 约定: - 将所有 user/assistant 消息拼接为一个大文本,适合用于知识性长记忆; - 调用方通过 scopeMeta 控制命名空间(user_id/project_id/resource_id 等); - 具体要保存哪些 Session 由上层业务决定(教学会话、设置会话等)。
( ctx context.Context, appName string, userID string, sessionID string, scopeMeta map[string]any, cfg *LongTermBridgeConfig, )
| 30 | // - 调用方通过 scopeMeta 控制命名空间(user_id/project_id/resource_id 等); |
| 31 | // - 具体要保存哪些 Session 由上层业务决定(教学会话、设置会话等)。 |
| 32 | func (b *LongTermBridge) SaveSessionToSemanticMemory( |
| 33 | ctx context.Context, |
| 34 | appName string, |
| 35 | userID string, |
| 36 | sessionID string, |
| 37 | scopeMeta map[string]any, |
| 38 | cfg *LongTermBridgeConfig, |
| 39 | ) error { |
| 40 | if b == nil || b.Sessions == nil || b.SemanticMemory == nil || !b.SemanticMemory.Enabled() { |
| 41 | return errors.New("long-term bridge is not properly configured") |
| 42 | } |
| 43 | |
| 44 | // 加载 Session 事件 |
| 45 | sess, err := b.Sessions.Get(ctx, &session.GetRequest{ |
| 46 | AppName: appName, |
| 47 | UserID: userID, |
| 48 | SessionID: sessionID, |
| 49 | }) |
| 50 | if err != nil { |
| 51 | return fmt.Errorf("get session: %w", err) |
| 52 | } |
| 53 | if sess == nil { |
| 54 | return errors.New("session not found") |
| 55 | } |
| 56 | |
| 57 | if sess.Events() == nil || sess.Events().Len() == 0 { |
| 58 | return errors.New("session has no events") |
| 59 | } |
| 60 | |
| 61 | events := sess.Events() |
| 62 | var lines []string |
| 63 | for ev := range events.All() { |
| 64 | if ev == nil { |
| 65 | continue |
| 66 | } |
| 67 | role := string(ev.Content.Role) |
| 68 | text := strings.TrimSpace(ev.Content.Content) |
| 69 | if text == "" { |
| 70 | continue |
| 71 | } |
| 72 | lines = append(lines, fmt.Sprintf("%s: %s", role, text)) |
| 73 | } |
| 74 | |
| 75 | if len(lines) == 0 { |
| 76 | return errors.New("no textual content to save") |
| 77 | } |
| 78 | |
| 79 | joined := strings.Join(lines, "\n") |
| 80 | |
| 81 | if cfg != nil && cfg.MinTokens > 0 { |
| 82 | if tokenCount(joined) < cfg.MinTokens { |
| 83 | return errors.New("session content too short, skip saving") |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | // 构造 docID:app/user/session 的组合,保证全局唯一性 |
| 88 | docID := fmt.Sprintf("%s/%s/%s", appName, userID, sessionID) |
| 89 |