Cross-session Memory Sharing 提供了一个强大的会话间记忆共享系统,支持私有、共享和全局三种作用域,以及细粒度的访问控制。
package main
import (
"context"
"github.com/astercloud/aster/pkg/memory"
)
func main() {
// 创建会话记忆管理器
config := memory.DefaultSessionManagerConfig()
manager := memory.NewSessionMemoryManager(config)
// 添加私有记忆
memID, err := manager.AddMemory(
context.Background(),
"session-1",
"User prefers dark mode",
map[string]interface{}{"category": "preference"},
memory.ScopePrivate,
)
if err != nil {
panic(err)
}
}
// session-1 共享记忆给 session-2
err := manager.ShareMemory(
ctx,
memID,
"session-1", // from (所有者)
"session-2", // to (目标会话)
memory.AccessRead, // 访问级别
)
if err != nil {
panic(err)
}
// session-2 现在可以读取这个记忆
mem, err := manager.GetMemory(ctx, memID, "session-2")
if err == nil {
fmt.Printf("Shared memory: %s\n", mem.Content)
}
// 创建全局记忆(所有会话可见)
globalMemID, _ := manager.AddMemory(
ctx,
"session-1",
"System maintenance scheduled for tonight",
nil,
memory.ScopeGlobal,
)
// 任何会话都可以读取全局记忆
mem, _ := manager.GetMemory(ctx, globalMemID, "session-100")
fmt.Printf("Global announcement: %s\n", mem.Content)
// 只有创建者会话可以访问
memID, _ := manager.AddMemory(
ctx,
"session-1",
"My secret note",
nil,
memory.ScopePrivate,
)
// session-1 可以访问
mem, _ := manager.GetMemory(ctx, memID, "session-1") // ✅
// session-2 无法访问
_, err := manager.GetMemory(ctx, memID, "session-2") // ❌ Access denied
// 创建私有记忆
memID, _ := manager.AddMemory(
ctx,
"session-1",
"Project plan",
nil,
memory.ScopePrivate,
)
// 共享给特定会话
manager.ShareMemory(ctx, memID, "session-1", "session-2", memory.AccessRead)
manager.ShareMemory(ctx, memID, "session-1", "session-3", memory.AccessWrite)
// session-2 可以读
mem, _ := manager.GetMemory(ctx, memID, "session-2") // ✅
// session-3 可以读写
manager.UpdateMemory(ctx, memID, "session-3", "Updated plan", nil) // ✅
// session-4 无法访问
_, err := manager.GetMemory(ctx, memID, "session-4") // ❌ Access denied
// 所有会话可以读取全局记忆
globalMemID, _ := manager.AddMemory(
ctx,
"admin-session",
"Company-wide announcement",
nil,
memory.ScopeGlobal,
)
// 任何会话都可以读
mem, _ := manager.GetMemory(ctx, globalMemID, "random-session-123") // ✅
// 但只有所有者可以修改
manager.UpdateMemory(ctx, globalMemID, "random-session", "Try to modify", nil) // ❌
manager.UpdateMemory(ctx, globalMemID, "admin-session", "Modified", nil) // ✅
默认状态,无法访问记忆。
manager.ShareMemory(ctx, memID, "session-1", "session-2", memory.AccessRead)
// session-2 可以读
mem, _ := manager.GetMemory(ctx, memID, "session-2") // ✅
// 但不能写
err := manager.UpdateMemory(ctx, memID, "session-2", "Try to update", nil) // ❌
manager.ShareMemory(ctx, memID, "session-1", "session-2", memory.AccessWrite)
// session-2 可以读写
mem, _ := manager.GetMemory(ctx, memID, "session-2") // ✅
manager.UpdateMemory(ctx, memID, "session-2", "Updated", nil) // ✅
// 但不能删除(只有所有者可以)
err := manager.DeleteMemory(ctx, memID, "session-2") // ❌
manager.ShareMemory(ctx, memID, "session-1", "session-2", memory.AccessFullControl)
// session-2 可以读写
mem, _ := manager.GetMemory(ctx, memID, "session-2") // ✅
manager.UpdateMemory(ctx, memID, "session-2", "Updated", nil) // ✅
// 但仍然不能删除(删除是所有者专属权限)
err := manager.DeleteMemory(ctx, memID, "session-2") // ❌ Only owner can delete
memID, err := manager.AddMemory(
ctx,
"session-id",
"Memory content",
map[string]interface{}{
"tag": "important",
"priority": 5,
},
memory.ScopePrivate,
)
// 所有者共享记忆给其他会话
err := manager.ShareMemory(
ctx,
memID,
"owner-session",
"target-session",
memory.AccessRead,
)
// 检查共享数量限制(默认 100)
config := memory.DefaultSessionManagerConfig()
config.MaxSharedSessions = 10 // 最多共享给 10 个会话
// 所有者撤销共享
err := manager.RevokeAccess(
ctx,
memID,
"owner-session",
"target-session",
)
// 需要 Write 或 FullControl 权限
err := manager.UpdateMemory(
ctx,
memID,
"session-id",
"Updated content",
map[string]interface{}{"updated": true},
)
// 只有所有者可以删除
err := manager.DeleteMemory(ctx, memID, "owner-session") // ✅
err := manager.DeleteMemory(ctx, memID, "other-session") // ❌
// 列出会话可访问的所有记忆
memories, err := manager.ListSessionMemories(ctx, "session-1", "")
// 按作用域过滤
privateMemories, _ := manager.ListSessionMemories(ctx, "session-1", memory.ScopePrivate)
globalMemories, _ := manager.ListSessionMemories(ctx, "session-1", memory.ScopeGlobal)
config := memory.SessionManagerConfig{
// 默认作用域
DefaultScope: memory.ScopePrivate,
// 是否允许跨会话共享
EnableSharing: true,
// 是否允许全局记忆
EnableGlobal: true,
// 记忆过期时间
MemoryTTL: 7 * 24 * time.Hour, // 7 天
// 最大共享数量
MaxSharedSessions: 100,
}
manager := memory.NewSessionMemoryManager(config)
// 添加记忆时自动创建溯源信息
memID, _ := manager.AddMemory(
ctx,
"session-1",
"User feedback: UI is confusing",
map[string]interface{}{"source": "feedback"},
memory.ScopePrivate,
)
// 获取记忆时查看溯源
mem, _ := manager.GetMemory(ctx, memID, "session-1")
fmt.Printf("Source: %s\n", mem.Provenance.Source)
fmt.Printf("Confidence: %.2f\n", mem.Provenance.Confidence)
stats := manager.GetStats()
fmt.Printf("总记忆数: %d\n", stats.TotalMemories)
fmt.Printf("总会话数: %d\n", stats.TotalSessions)
fmt.Printf("全局记忆数: %d\n", stats.GlobalMemories)
fmt.Printf("私有记忆: %d\n", stats.ScopeDistribution[memory.ScopePrivate])
fmt.Printf("全局记忆: %d\n", stats.ScopeDistribution[memory.ScopeGlobal])
// 手动触发清理
removed := manager.CleanupExpired(ctx)
fmt.Printf("清理了 %d 个过期记忆\n", removed)
// 定期自动清理
ticker := time.NewTicker(24 * time.Hour)
go func() {
for range ticker.C {
removed := manager.CleanupExpired(ctx)
log.Printf("清理了 %d 个过期记忆", removed)
}
}()
// 批量添加记忆
memories := []struct {
content string
scope memory.MemoryScope
}{
{"Memory 1", memory.ScopePrivate},
{"Memory 2", memory.ScopeGlobal},
{"Memory 3", memory.ScopePrivate},
}
memIDs := []string{}
for _, mem := range memories {
id, _ := manager.AddMemory(ctx, "session-1", mem.content, nil, mem.scope)
memIDs = append(memIDs, id)
}
// 批量共享
for _, memID := range memIDs {
manager.ShareMemory(ctx, memID, "session-1", "session-2", memory.AccessRead)
}
// ✅ 用户特定数据 → Private
manager.AddMemory(ctx, sessionID, "User's API key", nil, memory.ScopePrivate)
// ✅ 团队协作数据 → Shared(通过 ShareMemory 控制)
memID, _ := manager.AddMemory(ctx, sessionID, "Team notes", nil, memory.ScopePrivate)
manager.ShareMemory(ctx, memID, sessionID, "team-member-1", memory.AccessWrite)
// ✅ 系统公告 → Global
manager.AddMemory(ctx, "admin", "System maintenance tonight", nil, memory.ScopeGlobal)
// ✅ 只需要读 → AccessRead
manager.ShareMemory(ctx, memID, owner, viewer, memory.AccessRead)
// ✅ 需要协作编辑 → AccessWrite
manager.ShareMemory(ctx, memID, owner, collaborator, memory.AccessWrite)
// ❌ 避免滥用 FullControl
// manager.ShareMemory(ctx, memID, owner, user, memory.AccessFullControl)
// 设置合理的 TTL
config := memory.DefaultSessionManagerConfig()
config.MemoryTTL = 30 * 24 * time.Hour // 30 天
// 定期清理
ticker := time.NewTicker(24 * time.Hour)
go func() {
for range ticker.C {
manager.CleanupExpired(ctx)
}
}()
// 在共享前验证所有者
mem, err := manager.GetMemory(ctx, memID, sessionID)
if err != nil {
return err
}
if mem.OwnerID != sessionID {
return fmt.Errorf("only owner can share")
}
// 然后执行共享
manager.ShareMemory(ctx, memID, sessionID, targetSession, memory.AccessRead)
// 每个用户有自己的会话
userSession := "user-123"
// 存储用户偏好(私有)
manager.AddMemory(ctx, userSession, "Prefers dark mode", nil, memory.ScopePrivate)
manager.AddMemory(ctx, userSession, "Timezone: UTC+8", nil, memory.ScopePrivate)
// 团队长创建共享记忆
teamLeadSession := "team-lead-1"
memID, _ := manager.AddMemory(
ctx,
teamLeadSession,
"Project requirements document",
nil,
memory.ScopePrivate,
)
// 共享给团队成员
members := []string{"member-1", "member-2", "member-3"}
for _, member := range members {
manager.ShareMemory(ctx, memID, teamLeadSession, member, memory.AccessRead)
}
// 给协作者写权限
manager.ShareMemory(ctx, memID, teamLeadSession, "co-lead", memory.AccessWrite)
// 管理员创建全局公告
adminSession := "admin"
manager.AddMemory(
ctx,
adminSession,
"New feature released: Dark mode support",
map[string]interface{}{
"type": "announcement",
"date": time.Now(),
},
memory.ScopeGlobal,
)
// 所有用户自动可见
运行跨会话共享测试:
go test ./pkg/memory/... -run TestSession -v