From 6b8bd3c554434ac6e7fafa11e2688d1ebd4b4998 Mon Sep 17 00:00:00 2001 From: hhs <386998068@qq.com> Date: Sat, 13 Jun 2026 15:24:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=9A=E4=B9=89=20SessionManager=20?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=20+=20SessionConfigPatch=20=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/models/models.go | 20 ++++++++++++ backend/internal/session/manager.go | 49 +++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 backend/internal/session/manager.go diff --git a/backend/internal/models/models.go b/backend/internal/models/models.go index 2508195..73d017a 100644 --- a/backend/internal/models/models.go +++ b/backend/internal/models/models.go @@ -21,6 +21,26 @@ func DefaultConfig() SessionConfig { return SessionConfig{TTSEnabled: true, DetailLevel: "low", Language: "zh-CN"} } +// SessionConfigPatch 会话配置增量更新(指针字段表示"未传则不更新")。 +type SessionConfigPatch struct { + TTSEnabled *bool `json:"tts_enabled,omitempty"` + DetailLevel *string `json:"detail_level,omitempty"` + Language *string `json:"language,omitempty"` +} + +// Apply 将 patch 中的非 nil 字段覆盖到 cfg。 +func (p SessionConfigPatch) Apply(cfg *SessionConfig) { + if p.TTSEnabled != nil { + cfg.TTSEnabled = *p.TTSEnabled + } + if p.DetailLevel != nil { + cfg.DetailLevel = *p.DetailLevel + } + if p.Language != nil { + cfg.Language = *p.Language + } +} + // Message 对话消息。 type Message struct { Role string `json:"role"` // "user" | "assistant" diff --git a/backend/internal/session/manager.go b/backend/internal/session/manager.go new file mode 100644 index 0000000..6e7f0eb --- /dev/null +++ b/backend/internal/session/manager.go @@ -0,0 +1,49 @@ +// Package session 提供会话生命周期管理能力。 +package session + +import ( + "context" + "errors" + + "github.com/hhs/camtalk/internal/models" +) + +// ErrSessionNotFound 会话不存在或已过期。 +var ErrSessionNotFound = errors.New("session not found") + +// Manager 会话管理器接口。 +// WebSocket Handler 通过此接口操作会话,不直接接触存储层。 +type Manager interface { + // Create 创建新会话,返回 session ID。 + Create(ctx context.Context, config models.SessionConfig) (string, error) + + // Get 获取会话(含 config)。不存在返回 ErrSessionNotFound。 + Get(ctx context.Context, sessionID string) (*models.Session, error) + + // UpdateConfig 更新会话配置(config 消息触发)。 + UpdateConfig(ctx context.Context, sessionID string, patch models.SessionConfigPatch) error + + // GetHistory 获取最近 N 轮对话历史(供 Orchestrator 构建 LLM 上下文)。 + GetHistory(ctx context.Context, sessionID string, limit int) ([]models.Message, error) + + // AppendMessage 追加一条对话消息,同时刷新 TTL。 + AppendMessage(ctx context.Context, sessionID string, msg models.Message) error + + // SetActiveRequest 标记当前正在处理的请求 ID(interrupt 用)。 + SetActiveRequest(ctx context.Context, sessionID string, requestID string) error + + // GetActiveRequestID 获取当前活跃请求 ID。 + GetActiveRequestID(ctx context.Context, sessionID string) (string, error) + + // ClearActiveRequest 清除活跃请求标记(请求完成或中断后)。 + ClearActiveRequest(ctx context.Context, sessionID string) error + + // Touch 刷新 TTL(心跳时调用)。 + Touch(ctx context.Context, sessionID string) error + + // Destroy 显式销毁会话(REST API DELETE 或连接断开清理)。 + Destroy(ctx context.Context, sessionID string) error + + // ActiveCount 返回当前活跃会话数(健康检查用)。 + ActiveCount() int +}