feat: 添加会话标题自动生成功能

- 后端:首次 AI 回复后自动从用户消息提取标题
- 后端:通过 WebSocket 推送 session_updated 事件
- 前端:useChat hook 处理标题更新事件
- 前端:Sidebar 组件实时更新会话标题显示
This commit is contained in:
2025-12-12 17:45:17 +08:00
parent f561687307
commit 65a23f1e71
9 changed files with 141 additions and 3 deletions
+11 -1
View File
@@ -11,6 +11,7 @@ interface UseChatOptions {
sessionId: string;
onError?: (error: Error) => void;
onSessionNotFound?: () => void;
onSessionUpdated?: (sessionId: string, name: string) => void;
}
interface ChatState {
@@ -20,7 +21,7 @@ interface ChatState {
streamingContent: string;
}
export function useChat({ sessionId, onError, onSessionNotFound }: UseChatOptions) {
export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdated }: UseChatOptions) {
const [state, setState] = useState<ChatState>({
messages: [],
isConnected: false,
@@ -38,8 +39,10 @@ export function useChat({ sessionId, onError, onSessionNotFound }: UseChatOption
// 用 ref 存储回调,避免依赖变化导致无限循环
const onErrorRef = useRef(onError);
const onSessionNotFoundRef = useRef(onSessionNotFound);
const onSessionUpdatedRef = useRef(onSessionUpdated);
onErrorRef.current = onError;
onSessionNotFoundRef.current = onSessionNotFound;
onSessionUpdatedRef.current = onSessionUpdated;
// 加载历史消息
const loadMessages = useCallback(async () => {
@@ -134,6 +137,13 @@ export function useChat({ sessionId, onError, onSessionNotFound }: UseChatOption
onErrorRef.current?.(new Error(message.payload?.message || 'Unknown error'));
setState((prev) => ({ ...prev, isLoading: false, streamingContent: '' }));
break;
case 'session_updated':
// 会话信息更新(如标题)
if (message.payload?.id && message.payload?.name) {
onSessionUpdatedRef.current?.(message.payload.id, message.payload.name);
}
break;
}
} catch {
// 忽略解析错误