Ver Fonte

sse+fastapi+agent对话

linzhaoxin319319 há 1 mês atrás
pai
commit
8776eaac0a
1 ficheiros alterados com 897 adições e 0 exclusões
  1. 897 0
      林兆新/2/sse_app.py

+ 897 - 0
林兆新/2/sse_app.py

@@ -0,0 +1,897 @@
+#!/usr/bin/env python3
+"""
+SSE + FastAPI 实时对话窗口
+用户输入消息,后端随机生成回复
+"""
+
+import asyncio
+import json
+import time
+import random
+import os
+from datetime import datetime
+from typing import List, Dict, Any
+from concurrent.futures import ThreadPoolExecutor
+from fastapi import FastAPI, Request
+from fastapi.responses import StreamingResponse, HTMLResponse
+import uvicorn
+import dotenv
+
+# Agent相关导入
+try:
+    from agno.agent import Agent
+    from agno.memory.v2.db.sqlite import SqliteMemoryDb
+    from agno.memory.v2.memory import Memory
+    from agno.models.openai import OpenAILike
+    from agno.storage.sqlite import SqliteStorage
+    AGENT_AVAILABLE = True
+    print("✅ Agent依赖已加载")
+except ImportError as e:
+    print(f"⚠️ Agent依赖未安装: {e}")
+    AGENT_AVAILABLE = False
+
+# 加载环境变量
+dotenv.load_dotenv()
+
+# 全局消息队列
+message_queue: List[Dict[str, Any]] = []
+
+# 全局Agent实例和Memory
+global_agent = None
+global_memory = None
+global_user_id = "user_web_chat"
+# 线程池执行器
+thread_executor = ThreadPoolExecutor(max_workers=2)
+
+# Agent工具函数
+def get_current_time():
+    """获取当前时间"""
+    return f"当前时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
+
+def get_user_info():
+    """获取用户信息"""
+    return "用户信息: 当前用户正在使用web实时对话窗口"
+
+async def call_agent_async(agent, message, user_id):
+    """异步调用Agent,避免阻塞事件循环"""
+    loop = asyncio.get_event_loop()
+    try:
+        print(f"🔄 开始异步调用Agent... (消息: {message[:50]})")
+        
+        # 在线程池中执行同步的Agent调用,设置超时
+        response = await asyncio.wait_for(
+            loop.run_in_executor(
+                thread_executor, 
+                lambda: agent.run(message, user_id=user_id)
+            ),
+            timeout=30.0  # 30秒超时
+        )
+        
+        print(f"✅ Agent异步调用完成")
+        return response
+    except asyncio.TimeoutError:
+        print(f"⏰ Agent调用超时 (30秒)")
+        return None
+    except Exception as e:
+        print(f"❌ Agent异步调用失败: {e}")
+        return None
+
+def create_agent():
+    """创建具有Memory功能的Agent实例"""
+    global global_agent, global_memory
+    
+    if not AGENT_AVAILABLE:
+        print("❌ Agent依赖不可用,将使用随机回复")
+        return None
+    
+    # 检查环境变量
+    api_key = os.getenv("BAILIAN_API_KEY")
+    base_url = os.getenv("BAILIAN_API_BASE_URL")
+    
+    if not api_key or not base_url:
+        print("⚠️ 环境变量未设置,Agent功能将不可用,使用随机回复")
+        return None
+    
+    try:
+        print("🚀 创建具有Memory功能的Agent实例...")
+        
+        # 创建模型
+        model = OpenAILike(
+            id="qwen3-32b",
+            api_key=api_key,
+            base_url=base_url,
+            request_params={"extra_body": {"enable_thinking": False}},
+        )
+        
+        # 数据库文件
+        db_file = "tmp/agent_memory.db"
+        os.makedirs("tmp", exist_ok=True)
+        
+        # 初始化Memory v2
+        memory = Memory(
+            model=model,  # 使用相同的模型进行记忆管理
+            db=SqliteMemoryDb(table_name="user_memories", db_file=db_file),
+        )
+        
+        # 初始化存储
+        storage = SqliteStorage(table_name="agent_sessions", db_file=db_file)
+        
+        # 定义记忆工具函数
+        def remember_info(info: str):
+            """主动记住信息的工具函数"""
+            return f"我已经记住了这个信息: {info}"
+        
+        # 创建Agent with Memory功能
+        agent = Agent(
+            model=model,
+            # Store memories in a database
+            memory=memory,
+            # Give the Agent the ability to update memories
+            enable_agentic_memory=True,
+            # Run the MemoryManager after each response
+            enable_user_memories=True,
+            # Store the chat history in the database
+            storage=storage,
+            # Add the chat history to the messages
+            add_history_to_messages=True,
+            # Number of history runs to include
+            num_history_runs=3,
+            # Tools
+            tools=[get_current_time, get_user_info, remember_info],
+            markdown=False,  # 简单文本回复
+            show_tool_calls=False,  # 关闭工具调用显示,避免影响web显示
+            instructions="""
+你是一个具有记忆功能的友好AI助手,正在通过web实时对话窗口与用户交流。
+
+🧠 **记忆功能**:
+- 你可以记住用户的姓名、偏好和兴趣
+- 保持跨会话的对话连贯性
+- 基于历史对话提供个性化建议
+- 记住之前讨论过的话题
+
+💬 **对话原则**:
+- 使用简洁、自然的中文回答
+- 语气友好、热情
+- 回答要有帮助性
+- 可以调用工具获取信息
+- 主动记住重要信息
+- 基于记忆提供个性化回应
+
+🎯 **个性化服务**:
+- 如果用户告诉你他们的姓名,主动记住
+- 记住用户的偏好和兴趣
+- 在后续对话中引用之前的内容
+- 提供基于历史的个性化建议
+
+请与用户进行愉快的对话!我会记住我们的每次交流。
+            """,
+        )
+        
+        global_agent = agent
+        global_memory = memory
+        print("✅ Memory Agent创建成功!")
+        print(f"📱 模型: qwen3-32b")
+        print(f"🧠 记忆: SQLite数据库 ({db_file})")
+        print(f"💾 存储: 会话历史记录")
+        print(f"👤 用户ID: {global_user_id}")
+        
+        # 简单测试Agent是否正常工作
+        try:
+            test_response = agent.run("你好", user_id=global_user_id)
+            print(f"🧪 Agent测试成功: {str(test_response)[:50]}...")
+        except Exception as e:
+            print(f"⚠️ Agent测试失败: {e}")
+        
+        return agent
+        
+    except Exception as e:
+        print(f"❌ Agent创建失败: {e}")
+        return None
+
+# 随机回复内容(Agent不可用时的备用)
+RANDOM_REPLIES = [
+    "这是一个有趣的观点!",
+    "我完全同意你的看法。",
+    "让我想想这个问题...",
+    "你说得很有道理。",
+    "这让我想到了另一个话题。",
+    "非常好的问题!",
+    "我觉得你可以试试这样做。",
+    "这确实是个挑战。",
+    "你的想法很有创意!",
+    "我需要更多信息来帮助你。",
+    "这个话题很深入呢。",
+    "你考虑得很周全。"
+]
+
+# 创建FastAPI应用
+app = FastAPI(title="SSE实时对话", description="简单的实时聊天系统", version="1.0.0")
+
+# 应用启动时初始化Agent
+@app.on_event("startup")
+async def startup_event():
+    print("🚀 启动SSE实时对话系统...")
+    print("📍 访问地址: http://localhost:8000")
+    
+    # 初始化Agent
+    try:
+        create_agent()
+        
+        if global_agent:
+            print("✅ Memory Agent已就绪,将提供具有记忆功能的智能回复")
+            print("🧠 记忆功能: 可记住用户信息和对话历史")
+            print("💬 特殊命令: 在对话中输入 '记忆' 查看记忆状态")
+        else:
+            print("⚠️ Agent不可用,将使用随机回复")
+            
+    except Exception as e:
+        print(f"❌ Agent创建过程中出错: {e}")
+        print("⚠️ 系统将使用随机回复模式")
+
+@app.get("/")
+async def home():
+    """主页 - 对话界面"""
+    html_content = """
+    <!DOCTYPE html>
+    <html lang="zh-CN">
+    <head>
+        <meta charset="UTF-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        <title>实时对话窗口</title>
+        <style>
+            * {
+                margin: 0;
+                padding: 0;
+                box-sizing: border-box;
+            }
+            
+            body {
+                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+                background: #f0f2f5;
+                height: 100vh;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+            }
+            
+            .chat-container {
+                width: 600px;
+                height: 500px;
+                background: white;
+                border-radius: 10px;
+                box-shadow: 0 4px 20px rgba(0,0,0,0.1);
+                display: flex;
+                flex-direction: column;
+                overflow: hidden;
+            }
+            
+            .chat-header {
+                background: #4a90e2;
+                color: white;
+                padding: 15px 20px;
+                text-align: center;
+                font-size: 18px;
+                font-weight: 600;
+            }
+            
+            .status-bar {
+                padding: 8px 15px;
+                background: #e8f4f8;
+                font-size: 12px;
+                color: #5a5a5a;
+                border-bottom: 1px solid #e0e0e0;
+            }
+            
+            .messages-container {
+                flex: 1;
+                padding: 15px;
+                overflow-y: auto;
+                background: #fafafa;
+            }
+            
+            .message {
+                margin-bottom: 12px;
+                display: flex;
+                animation: slideIn 0.3s ease-out;
+            }
+            
+            @keyframes slideIn {
+                from {
+                    opacity: 0;
+                    transform: translateY(10px);
+                }
+                to {
+                    opacity: 1;
+                    transform: translateY(0);
+                }
+            }
+            
+            .message.user {
+                justify-content: flex-end;
+            }
+            
+            .message-bubble {
+                max-width: 75%;
+                padding: 10px 15px;
+                border-radius: 18px;
+                word-wrap: break-word;
+                position: relative;
+            }
+            
+            .message.user .message-bubble {
+                background: #4a90e2;
+                color: white;
+            }
+            
+            .message.bot .message-bubble {
+                background: white;
+                color: #333;
+                border: 1px solid #e0e0e0;
+                box-shadow: 0 1px 3px rgba(0,0,0,0.1);
+            }
+            
+            .message.system .message-bubble {
+                background: #fff3cd;
+                color: #856404;
+                border: 1px solid #ffeaa7;
+                font-style: italic;
+                text-align: center;
+                max-width: 100%;
+            }
+            
+            .message-time {
+                font-size: 10px;
+                color: #999;
+                margin-top: 3px;
+                text-align: right;
+            }
+            
+            .message.user .message-time {
+                text-align: right;
+            }
+            
+            .message.bot .message-time {
+                text-align: left;
+            }
+            
+            .input-container {
+                padding: 15px;
+                background: white;
+                border-top: 1px solid #e0e0e0;
+                display: flex;
+                gap: 10px;
+            }
+            
+            .message-input {
+                flex: 1;
+                padding: 10px 15px;
+                border: 1px solid #ddd;
+                border-radius: 20px;
+                outline: none;
+                font-size: 14px;
+                transition: border-color 0.3s;
+            }
+            
+            .message-input:focus {
+                border-color: #4a90e2;
+                box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.2);
+            }
+            
+            .send-button {
+                background: #4a90e2;
+                color: white;
+                border: none;
+                border-radius: 20px;
+                padding: 10px 20px;
+                cursor: pointer;
+                font-size: 14px;
+                font-weight: 600;
+                transition: all 0.3s;
+            }
+            
+            .send-button:hover {
+                background: #357abd;
+                transform: translateY(-1px);
+            }
+            
+            .send-button:disabled {
+                background: #ccc;
+                cursor: not-allowed;
+                transform: none;
+            }
+            
+            .typing-indicator {
+                display: none;
+                padding: 10px 15px;
+                color: #666;
+                font-style: italic;
+                font-size: 12px;
+            }
+            
+            .typing-dots {
+                display: inline-block;
+            }
+            
+            .typing-dots::after {
+                content: '';
+                animation: typing 1.5s infinite;
+            }
+            
+            @keyframes typing {
+                0%, 60%, 100% { content: ''; }
+                30% { content: '.'; }
+                40% { content: '..'; }
+                50% { content: '...'; }
+            }
+        </style>
+    </head>
+    <body>
+        <div class="chat-container">
+            <div class="chat-header">
+                💬 实时对话窗口
+            </div>
+            
+            <div class="status-bar" id="statusBar">
+                正在连接...
+            </div>
+            
+            <div class="messages-container" id="messagesContainer">
+                <!-- 消息显示区域 -->
+            </div>
+            
+            <div class="typing-indicator" id="typingIndicator">
+                机器人正在输入<span class="typing-dots"></span>
+            </div>
+            
+                         <div class="input-container">
+                 <input 
+                     type="text" 
+                     id="messageInput" 
+                     class="message-input" 
+                     placeholder="输入您的消息... (输入 '记忆' 查看我的记忆状态)"
+                     maxlength="500"
+                 >
+                 <button id="sendButton" class="send-button">发送</button>
+             </div>
+        </div>
+        
+        <script>
+            let eventSource = null;
+            let isConnected = false;
+            
+            const messagesContainer = document.getElementById('messagesContainer');
+            const messageInput = document.getElementById('messageInput');
+            const sendButton = document.getElementById('sendButton');
+            const statusBar = document.getElementById('statusBar');
+            const typingIndicator = document.getElementById('typingIndicator');
+            
+            // 页面加载完成后初始化
+            window.addEventListener('load', function() {
+                console.log('页面加载完成');
+                
+                // 启用输入功能
+                messageInput.disabled = false;
+                sendButton.disabled = false;
+                messageInput.focus();
+                
+                                 // 显示欢迎消息
+                 addMessage('🎉 欢迎使用AI实时对话窗口!我是您的智能助手,具有记忆功能,可以记住我们的对话历史。请开始聊天吧~', 'system');
+                
+                // 连接SSE
+                connectSSE();
+            });
+            
+            // 连接SSE
+            function connectSSE() {
+                try {
+                    console.log('连接SSE...');
+                    eventSource = new EventSource('/sse/chat');
+                    
+                    eventSource.onopen = function() {
+                        console.log('SSE连接成功');
+                        isConnected = true;
+                        statusBar.textContent = '✅ 已连接 - 消息将实时更新';
+                        statusBar.style.background = '#d4edda';
+                        statusBar.style.color = '#155724';
+                    };
+                    
+                    eventSource.onmessage = function(event) {
+                        try {
+                            const data = JSON.parse(event.data);
+                            handleMessage(data);
+                        } catch (e) {
+                            console.error('消息解析错误:', e);
+                        }
+                    };
+                    
+                    eventSource.onerror = function() {
+                        console.log('SSE连接失败');
+                        isConnected = false;
+                        statusBar.textContent = '⚠️ 连接失败 - 使用离线模式';
+                        statusBar.style.background = '#f8d7da';
+                        statusBar.style.color = '#721c24';
+                    };
+                    
+                } catch (error) {
+                    console.error('SSE初始化错误:', error);
+                    statusBar.textContent = '📱 离线模式';
+                }
+            }
+            
+            // 处理消息
+            function handleMessage(data) {
+                console.log('收到消息:', data);
+                
+                switch(data.type) {
+                    case 'bot_message':
+                        hideTypingIndicator();
+                        addMessage(data.message, 'bot');
+                        break;
+                    case 'system_message':
+                        addMessage(data.message, 'system');
+                        break;
+                }
+            }
+            
+            // 添加消息到界面
+            function addMessage(content, type) {
+                console.log(`添加消息: [${type}] ${content}`);
+                
+                const messageDiv = document.createElement('div');
+                messageDiv.className = `message ${type}`;
+                
+                const bubbleDiv = document.createElement('div');
+                bubbleDiv.className = 'message-bubble';
+                bubbleDiv.textContent = content;
+                
+                const timeDiv = document.createElement('div');
+                timeDiv.className = 'message-time';
+                timeDiv.textContent = new Date().toLocaleTimeString();
+                
+                messageDiv.appendChild(bubbleDiv);
+                messageDiv.appendChild(timeDiv);
+                
+                messagesContainer.appendChild(messageDiv);
+                messagesContainer.scrollTop = messagesContainer.scrollHeight;
+            }
+            
+            // 显示输入指示器
+            function showTypingIndicator() {
+                typingIndicator.style.display = 'block';
+                messagesContainer.scrollTop = messagesContainer.scrollHeight;
+            }
+            
+                         // 隐藏输入指示器
+             function hideTypingIndicator() {
+                 typingIndicator.style.display = 'none';
+             }
+             
+             // 显示记忆状态
+             async function showMemoryStatus() {
+                 try {
+                     showTypingIndicator();
+                     
+                     const response = await fetch('/api/memory');
+                     const result = await response.json();
+                     
+                     hideTypingIndicator();
+                     
+                     if (result.available) {
+                         let memoryInfo = `🧠 **记忆状态信息**\n\n`;
+                         memoryInfo += `👤 用户ID: ${result.user_id}\n`;
+                         memoryInfo += `📊 记忆数量: ${result.memory_count}\n`;
+                         memoryInfo += `💾 数据库: ${result.database}\n\n`;
+                         
+                         if (result.recent_memories && result.recent_memories.length > 0) {
+                             memoryInfo += `📝 **最近的记忆:**\n`;
+                             result.recent_memories.forEach((mem, index) => {
+                                 memoryInfo += `${index + 1}. ${mem.content}...\n`;
+                             });
+                         } else {
+                             memoryInfo += `📭 暂无记忆内容\n`;
+                         }
+                         
+                         memoryInfo += `\n💭 **记忆功能说明:**\n`;
+                         memoryInfo += `- 我可以记住您的姓名、偏好和兴趣\n`;
+                         memoryInfo += `- 保持跨会话的对话连贯性\n`;
+                         memoryInfo += `- 基于历史对话提供个性化建议\n`;
+                         memoryInfo += `- 记住之前讨论过的话题`;
+                         
+                         addMessage(memoryInfo, 'bot');
+                     } else {
+                         addMessage('❌ 记忆功能不可用: ' + result.message, 'system');
+                     }
+                     
+                 } catch (error) {
+                     hideTypingIndicator();
+                     addMessage('❌ 获取记忆状态失败: ' + error.message, 'system');
+                 }
+             }
+            
+                         // 发送消息
+             async function sendMessage() {
+                 const message = messageInput.value.trim();
+                 console.log('准备发送消息:', message);
+                 
+                 if (!message) {
+                     console.log('消息为空');
+                     return;
+                 }
+                 
+                 // 检查特殊命令
+                 if (message === '记忆' || message.toLowerCase() === 'memory') {
+                     console.log('处理记忆查询命令');
+                     addMessage(message, 'user');
+                     messageInput.value = '';
+                     await showMemoryStatus();
+                     return;
+                 }
+                 
+                 // 立即显示用户消息
+                 addMessage(message, 'user');
+                 messageInput.value = '';
+                 
+                 // 禁用输入
+                 messageInput.disabled = true;
+                 sendButton.disabled = true;
+                 
+                 // 显示输入指示器
+                 showTypingIndicator();
+                
+                try {
+                    const response = await fetch('/api/chat', {
+                        method: 'POST',
+                        headers: {
+                            'Content-Type': 'application/json',
+                        },
+                        body: JSON.stringify({
+                            message: message
+                        })
+                    });
+                    
+                    const result = await response.json();
+                    console.log('发送结果:', result);
+                    
+                    if (!result.success) {
+                        hideTypingIndicator();
+                        addMessage('❌ 发送失败: ' + result.error, 'system');
+                    }
+                    
+                } catch (error) {
+                    console.error('发送错误:', error);
+                    hideTypingIndicator();
+                    addMessage('❌ 网络错误: ' + error.message, 'system');
+                } finally {
+                    // 重新启用输入
+                    messageInput.disabled = false;
+                    sendButton.disabled = false;
+                    messageInput.focus();
+                }
+            }
+            
+            // 事件监听器
+            sendButton.addEventListener('click', sendMessage);
+            
+            messageInput.addEventListener('keypress', function(e) {
+                if (e.key === 'Enter' && !e.shiftKey) {
+                    e.preventDefault();
+                    sendMessage();
+                }
+            });
+            
+            // 页面关闭时断开连接
+            window.addEventListener('beforeunload', function() {
+                if (eventSource) {
+                    eventSource.close();
+                }
+            });
+        </script>
+    </body>
+    </html>
+    """
+    return HTMLResponse(content=html_content)
+
+# SSE消息流生成器
+async def generate_chat_stream():
+    """生成聊天消息流"""
+    client_id = f"client_{int(time.time())}"
+    last_message_count = 0
+    
+    try:
+        print(f"新的SSE连接: {client_id}")
+        
+        while True:
+            # 检查新消息
+            if len(message_queue) > last_message_count:
+                for i in range(last_message_count, len(message_queue)):
+                    message = message_queue[i]
+                    yield f"data: {json.dumps(message, ensure_ascii=False)}\n\n"
+                
+                last_message_count = len(message_queue)
+            
+            await asyncio.sleep(0.1)  # 100ms检查间隔
+            
+    except Exception as e:
+        print(f"SSE流错误: {e}")
+    finally:
+        print(f"SSE连接断开: {client_id}")
+
+@app.get("/sse/chat")
+async def sse_chat():
+    """SSE聊天端点"""
+    return StreamingResponse(
+        generate_chat_stream(),
+        media_type="text/event-stream",
+        headers={
+            "Cache-Control": "no-cache",
+            "Connection": "keep-alive",
+            "Access-Control-Allow-Origin": "*",
+        }
+    )
+
+@app.post("/api/chat")
+async def chat_api(request: Request):
+    """处理聊天消息"""
+    global global_agent, global_user_id
+    
+    try:
+        data = await request.json()
+        user_message = data.get("message", "").strip()
+        
+        if not user_message:
+            return {"success": False, "error": "消息不能为空"}
+        
+        print(f"📨 收到用户消息: {user_message}")
+        print(f"🤖 Agent可用性: {global_agent is not None}")
+        
+        # 模拟思考时间
+        await asyncio.sleep(random.uniform(0.5, 1.5))
+        
+        bot_reply = None
+        
+        # 尝试使用Agent生成回复
+        if global_agent:
+            try:
+                print("🤖 调用Memory Agent生成回复...")
+                
+                # 异步调用Agent处理消息,传入user_id以关联记忆
+                response = await call_agent_async(global_agent, user_message, global_user_id)
+                
+                if response:
+                    bot_reply = response.content if hasattr(response, 'content') else str(response)
+                    print(f"✅ Agent回复: {bot_reply}")
+                    print(f"🧠 记忆已更新 (用户ID: {global_user_id})")
+                else:
+                    print("❌ Agent返回空响应")
+                    bot_reply = None
+                
+            except Exception as e:
+                print(f"❌ Agent调用失败: {e}")
+                bot_reply = None
+        
+        # 如果Agent不可用或失败,使用随机回复
+        if not bot_reply:
+            bot_reply = random.choice(RANDOM_REPLIES)
+            print(f"🎲 使用随机回复: {bot_reply}")
+        
+        # 确保回复不为空
+        if not bot_reply:
+            bot_reply = "抱歉,我暂时无法回复。请稍后再试。"
+            print(f"⚠️ 使用默认回复: {bot_reply}")
+        
+        # 添加机器人回复到消息队列
+        bot_message = {
+            "type": "bot_message",
+            "message": bot_reply,
+            "timestamp": datetime.now().isoformat()
+        }
+        message_queue.append(bot_message)
+        
+        print(f"📤 机器人回复已添加到消息队列: {bot_reply[:50]}...")
+        
+        return {
+            "success": True,
+            "message": "消息已处理",
+            "timestamp": datetime.now().isoformat()
+        }
+        
+    except Exception as e:
+        print(f"处理消息错误: {e}")
+        return {"success": False, "error": f"处理错误: {str(e)}"}
+
+@app.get("/api/status")
+async def get_status():
+    """获取系统状态"""
+    return {
+        "status": "running",
+        "messages": len(message_queue),
+        "timestamp": datetime.now().isoformat()
+    }
+
+@app.post("/api/clear")
+async def clear_messages():
+    """清空消息历史"""
+    global message_queue
+    message_queue.clear()
+    
+    # 添加清空提示消息
+    clear_msg = {
+        "type": "system_message",
+        "message": "💬 消息历史已清空",
+        "timestamp": datetime.now().isoformat()
+    }
+    message_queue.append(clear_msg)
+    
+    return {"success": True, "message": "消息历史已清空"}
+
+@app.get("/api/memory")
+async def get_memory_status():
+    """获取Agent记忆状态"""
+    global global_memory, global_user_id, global_agent
+    
+    if not global_agent or not global_memory:
+        return {
+            "available": False,
+            "message": "Memory功能不可用",
+            "user_id": global_user_id
+        }
+    
+    try:
+        # 尝试获取记忆信息
+        memories = global_memory.get_user_memories(user_id=global_user_id)
+        memory_count = len(memories) if memories else 0
+        
+        # 获取最近的3条记忆摘要
+        recent_memories = []
+        if memories:
+            for mem in memories[-3:]:
+                try:
+                    # UserMemory对象的属性访问
+                    content = getattr(mem, 'content', '')[:100] if hasattr(mem, 'content') else str(mem)[:100]
+                    timestamp = getattr(mem, 'created_at', '') if hasattr(mem, 'created_at') else ''
+                    recent_memories.append({
+                        "content": content,
+                        "timestamp": str(timestamp),
+                    })
+                except Exception as e:
+                    # 备用方案:直接转换为字符串
+                    recent_memories.append({
+                        "content": str(mem)[:100],
+                        "timestamp": "",
+                    })
+        
+        return {
+            "available": True,
+            "user_id": global_user_id,
+            "memory_count": memory_count,
+            "recent_memories": recent_memories,
+            "database": "tmp/agent_memory.db",
+            "timestamp": datetime.now().isoformat()
+        }
+        
+    except Exception as e:
+        return {
+            "available": True,
+            "user_id": global_user_id,
+            "memory_count": "unknown",
+            "error": str(e),
+            "message": "记忆系统已启用但获取详情失败",
+            "timestamp": datetime.now().isoformat()
+        }
+
+if __name__ == "__main__":
+    print("🚀 启动SSE实时对话系统...")
+    print("🌐 访问地址: http://localhost:8081")
+    print("🤖 支持Agent智能回复 + SSE实时推送")
+    print("📋 如需Agent功能,请配置环境变量:")
+    print("   BAILIAN_API_KEY=your_api_key")
+    print("   BAILIAN_API_BASE_URL=your_base_url")
+    print("=" * 50)
+    
+    uvicorn.run(
+        "sse_app:app",
+        host="0.0.0.0",
+        port=8081,
+        reload=True,
+        log_level="info"
+    )