feat: 扩展 Session Manager 接口,新增 ListByUser、UpdateTitle 方法

- Manager.Create 签名新增 userID 参数
- 新增 ConversationSummary 类型和 ListByUser 分页查询
- 新增 UpdateTitle 方法
- MemoryManager 实现:ListByUser 遍历+过滤+排序,UpdateTitle,自动标题生成
- RedisManager 实现:user:{id}:sessions 索引,ListByUser 通过 SMEMBERS 查询
- AppendMessage 自动更新标题(首条 user 消息时,取前 20 字符)
- 更新 ws handler、api/session.go、orchestrator mock 的 Create 调用
This commit is contained in:
hhs
2026-06-14 17:35:20 +08:00
parent 9ff971fd89
commit 6487a8ecab
7 changed files with 293 additions and 38 deletions

View File

@@ -19,7 +19,7 @@ func TestCreateAndGet(t *testing.T) {
ctx := context.Background()
config := models.DefaultConfig()
id, err := m.Create(ctx, config)
id, err := m.Create(ctx, "", config)
if err != nil {
t.Fatalf("Create: %v", err)
}
@@ -56,7 +56,7 @@ func TestExpire(t *testing.T) {
defer m.Stop()
ctx := context.Background()
id, _ := m.Create(ctx, models.DefaultConfig())
id, _ := m.Create(ctx, "", models.DefaultConfig())
// 未过期时应能获取
_, err := m.Get(ctx, id)
@@ -78,7 +78,7 @@ func TestDestroy(t *testing.T) {
defer m.Stop()
ctx := context.Background()
id, _ := m.Create(ctx, models.DefaultConfig())
id, _ := m.Create(ctx, "", models.DefaultConfig())
if err := m.Destroy(ctx, id); err != nil {
t.Fatalf("Destroy: %v", err)
@@ -106,7 +106,7 @@ func TestAppendMessageAndGetHistory(t *testing.T) {
defer m.Stop()
ctx := context.Background()
id, _ := m.Create(ctx, models.DefaultConfig())
id, _ := m.Create(ctx, "", models.DefaultConfig())
msgs := []models.Message{
{Role: "user", Content: "你好"},
@@ -138,7 +138,7 @@ func TestGetHistoryLimit(t *testing.T) {
defer m.Stop()
ctx := context.Background()
id, _ := m.Create(ctx, models.DefaultConfig())
id, _ := m.Create(ctx, "", models.DefaultConfig())
for i := 0; i < 10; i++ {
m.AppendMessage(ctx, id, models.Message{Role: "user", Content: "msg"})
@@ -159,7 +159,7 @@ func TestHistoryLimit(t *testing.T) {
defer m.Stop()
ctx := context.Background()
id, _ := m.Create(ctx, models.DefaultConfig())
id, _ := m.Create(ctx, "", models.DefaultConfig())
// 插入超过上限的消息
for i := 0; i < 10; i++ {
@@ -180,7 +180,7 @@ func TestUpdateConfig(t *testing.T) {
defer m.Stop()
ctx := context.Background()
id, _ := m.Create(ctx, models.DefaultConfig())
id, _ := m.Create(ctx, "", models.DefaultConfig())
ttsEnabled := false
detailLevel := "high"
@@ -211,7 +211,7 @@ func TestActiveRequest(t *testing.T) {
defer m.Stop()
ctx := context.Background()
id, _ := m.Create(ctx, models.DefaultConfig())
id, _ := m.Create(ctx, "", models.DefaultConfig())
// 初始应为空
reqID, err := m.GetActiveRequestID(ctx, id)
@@ -246,7 +246,7 @@ func TestTouchRefreshesTTL(t *testing.T) {
defer m.Stop()
ctx := context.Background()
id, _ := m.Create(ctx, models.DefaultConfig())
id, _ := m.Create(ctx, "", models.DefaultConfig())
// 50ms 后 Touch应重置 TTL
time.Sleep(50 * time.Millisecond)
@@ -278,8 +278,8 @@ func TestActiveCount(t *testing.T) {
t.Errorf("initial ActiveCount = %d, want 0", m.ActiveCount())
}
m.Create(ctx, models.DefaultConfig())
m.Create(ctx, models.DefaultConfig())
m.Create(ctx, "", models.DefaultConfig())
m.Create(ctx, "", models.DefaultConfig())
if m.ActiveCount() != 2 {
t.Errorf("ActiveCount = %d, want 2", m.ActiveCount())
}