feat: 第四轮大版本更新 — 修复4个严重Bug、2个UI Bug,实现自主思考重构与主-子会话架构
## 🐛 Bug 修复 - 修复前端对话无响应:消除 ChatContainer 中的双重 WebSocket 连接,优化 sendMessage 失败提示 - 修复 Memory-Service 数据库迁移失败:ai-core 和 memory-service 均添加 ALTER TABLE ADD COLUMN IF NOT EXISTS 模式演化 - 修复语音/STT 不可用:添加 MediaRecorder API 降级方案,修复 whisper-cli 输出文件名错误 - 修复仪表盘数据库按钮失效:补充按钮 ID 属性,重写 controlDB() 控制逻辑 ## 🎨 UI 修复 - 修正用户消息头像位置:从 flex-row-reverse 改为 justify-end - 移除空聊天列表的 emoji 占位图标 ## ✨ 新功能 - devtools 新增 STT 处理日志面板(环形缓冲区 + WebSocket 广播 + 可视化表格) - 新增 ADMIN_NICKNAME 环境变量,支持自定义管理员昵称 ## 🔧 改进 - 注册流程增加昵称必填字段(前后端同步) ## 🏗️ 架构重构 - 重构自主思考逻辑:从定时器轮询改为事件驱动(对话后触发 + 静默检测),优化提示词使其更自然人性化 - 实现主-子会话架构:新增 4 种子会话类型(general/memory/iot/knowledge),意图分析 → 并行分发 → 结果合成流程 ## 📄 新增文档 - docs/architecture/main-session-sub-session-design.md — 子会话架构设计文档
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { useChat } from '@/hooks/useChat';
|
||||
import { useChatStore } from '@/store/chatStore';
|
||||
import { MessageList } from './MessageList';
|
||||
import { IoTStatusBar } from './IoTStatusBar';
|
||||
|
||||
export function ChatContainer() {
|
||||
const { messages, isTyping } = useChat();
|
||||
const messages = useChatStore((s) => s.messages);
|
||||
const isTyping = useChatStore((s) => s.isTyping);
|
||||
const continuousMode = useChatStore((s) => s.continuousMode);
|
||||
const backgroundThinkingStatus = useChatStore((s) => s.backgroundThinkingStatus);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ export function ChatInput({ onSend, disabled }: ChatInputProps) {
|
||||
const {
|
||||
isListening,
|
||||
isSupported,
|
||||
isFallbackMode,
|
||||
interimText,
|
||||
finalText,
|
||||
error,
|
||||
@@ -423,14 +424,14 @@ export function ChatInput({ onSend, disabled }: ChatInputProps) {
|
||||
{/* 语音输入状态提示 */}
|
||||
{isListening && (
|
||||
<p className="text-xs text-red-400 text-center animate-pulse">
|
||||
🎤 正在聆听...
|
||||
{isFallbackMode ? '🎤 后端语音识别中...' : '🎤 正在聆听...'}
|
||||
<span className="text-gray-400 ml-2">(Ctrl+Shift+V 停止)</span>
|
||||
</p>
|
||||
)}
|
||||
|
||||
{mode !== 'text' && !isListening && (
|
||||
<p className="text-xs text-gray-400 text-center">
|
||||
{mode === 'voice_msg' ? '语音消息功能即将上线 ♪' : ''}
|
||||
{mode === 'voice_msg' ? '点击麦克风按钮开始语音输入 ♪' : ''}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -154,7 +154,7 @@ export function MessageBubble({ role, content, timestamp, isStreaming, attachmen
|
||||
const imageAttachments = attachments?.filter((a) => a.type === 'image') ?? [];
|
||||
|
||||
return (
|
||||
<div className={`flex px-4 py-2 gap-3 ${isUser ? 'flex-row-reverse' : ''}`}>
|
||||
<div className={`flex px-4 py-2 gap-3 ${isUser ? 'justify-end' : ''}`}>
|
||||
{/* 头像 */}
|
||||
{!isUser && (
|
||||
<CyreneAvatar size="sm" className="flex-shrink-0 mt-1" />
|
||||
|
||||
@@ -19,12 +19,8 @@ export function MessageList({ messages, isTyping }: MessageListProps) {
|
||||
if (messages.length === 0) {
|
||||
return (
|
||||
<div className="flex-1 flex flex-col items-center justify-center text-gray-400 p-8">
|
||||
<div className="text-6xl mb-4">🌸</div>
|
||||
<p className="text-lg font-medium text-pink-300 mb-2">
|
||||
昔涟在这里等你哦 ♪
|
||||
</p>
|
||||
<p className="text-sm">
|
||||
无论是开心的事还是烦恼,都可以和人家说~
|
||||
<p className="text-sm text-gray-400 dark:text-gray-500">
|
||||
开始一段新对话吧
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user