Files
map-client-vue/CHAT_V2.1_UPDATE.md
2025-10-14 21:52:11 +08:00

13 KiB
Raw Blame History

聊天模块 V2.1 优化更新

📅 更新日期

2025年10月14日

🎯 本次优化内容

1. 右侧对话列表可折叠

功能描述:右侧的对话列表现在支持折叠/展开,节省屏幕空间。

实现细节

  • 在对话头部添加折叠按钮
  • 按钮图标根据状态变化ChevronLeft / ChevronRight
  • 按钮文字显示"显示列表" / "隐藏列表"
  • 使用 CSS transition 实现平滑动画

代码实现

<!-- 头部按钮 -->
<n-button text @click="showSidebar = !showSidebar">
  <n-icon :component="showSidebar ? ChevronRightIcon : ChevronLeftIcon" />
  <span>{{ showSidebar ? '隐藏列表' : '显示列表' }}</span>
</n-button>

<!-- CSS 动画 -->
<style>
.topics-sidebar {
  width: 320px;
  transition: all 0.3s ease;
  overflow: hidden;
}

.topics-sidebar:not(.visible) {
  width: 0;
  border-left: none;
  opacity: 0;
}
</style>

使用方法

  • 点击对话头部右上角的折叠按钮
  • 对话列表会平滑地隐藏/显示
  • 响应式设计:小屏幕时自动变为浮动面板

2. AI 模型选择列表动态加载

功能描述:模型选择器现在会动态读取"模型服务"中已配置的所有可用模型。

实现细节

// 从 modelStore 动态读取模型列表
const modelOptions = computed(() => {
  const services = modelStore.providers
  const options: any[] = []
  
  services.forEach((service: any) => {
    if (service.enabled && service.models) {
      service.models.forEach((model: any) => {
        options.push({
          label: `${service.name} | ${model.name}`,
          key: `${service.id}:${model.id}`,
          icon: () => h(NIcon, { component: BrainIcon })
        })
      })
    }
  })
  
  return options
})

// 显示选中的模型名称
const selectedModelName = computed(() => {
  if (!selectedModel.value) return undefined
  const [serviceId, modelId] = selectedModel.value.split(':')
  const service = modelStore.providers.find((s: any) => s.id === serviceId)
  const model = service?.models?.find((m: any) => m.id === modelId)
  return model ? `${service?.name} | ${model.name}` : undefined
})

工作流程

  1. 用户在"模型服务"页面添加服务如火山引擎、OpenAI
  2. 服务连接成功后,其模型会自动出现在聊天页面的模型选择器中
  3. 选择模型后,该模型会被用于当前对话
  4. 模型信息格式:服务名 | 模型名(如"火山引擎 | doubao-1.5-pro-32k"

特性

  • 实时同步:添加新服务后立即可用
  • 多服务支持:同时显示所有服务的模型
  • 清晰标识:服务名和模型名分开显示
  • 图标辅助:每个选项都有模型图标

3. MCP 服务支持(基础架构)

功能描述:聊天对话中现在支持选择和使用 MCP 服务器。

实现细节

3.1 MCP 服务器列表动态加载

// 从 mcpStore 读取已连接的服务器
const mcpOptions = computed(() => {
  const options: any[] = [
    {
      label: '不启用 MCP 服务',
      key: 'none'
    }
  ]
  
  // 添加已连接的服务器
  mcpStore.connectedServers.forEach((server) => {
    const toolCount = server.capabilities?.tools?.length || 0
    options.push({
      label: `${server.name} (${toolCount} 个工具)`,
      key: server.id,
      icon: () => h(NIcon, { component: PlugIcon })
    })
  })
  
  return options
})

// 显示选中的 MCP 服务器名称
const selectedMCPName = computed(() => {
  if (!selectedMCP.value || selectedMCP.value === 'none') return '不启用 MCP 服务'
  const server = mcpStore.servers.find(s => s.id === selectedMCP.value)
  return server?.name || '未知服务'
})

3.2 MCP 服务器传递到聊天服务

// ChatLayout.vue - 发送消息时传递 MCP 服务器 ID
const handleSendMessage = async () => {
  const mcpId = selectedMCP.value === 'none' ? undefined : selectedMCP.value
  await store.sendMessageStream(
    content,
    selectedModel.value,
    mcpId,  // 传递 MCP 服务器 ID
    () => { scrollToBottom() }
  )
}

// chatStore.ts - 转发到 chatService
const sendMessageStream = async (
  content: string,
  model?: string,
  mcpServerId?: string,  // 新增参数
  onChunk?: (chunk: string) => void
) => {
  await chatService.sendMessageStream(
    { topicId, content, model, stream: true },
    onChunk,
    mcpServerId  // 传递给 service
  )
}

// chatService.ts - 接收并准备使用
async sendMessageStream(
  options: SendMessageOptions,
  onChunk: (event: StreamEvent) => void,
  mcpServerId?: string  // 接收 MCP 服务器 ID
): Promise<void> {
  // TODO: 在这里实现 MCP 工具调用逻辑
  await this.callModelStream(conversation, model, onChunk, mcpServerId)
}

3.3 自动加载和重连

// 初始化时加载 MCP 服务器
onMounted(async () => {
  store.initialize()
  scrollToBottom()
  
  // 加载 MCP 服务器配置
  mcpStore.loadServers()
  
  // 尝试自动重连之前已连接的服务器
  try {
    await mcpStore.autoReconnect()
  } catch (error) {
    console.warn('自动重连 MCP 服务器失败:', error)
  }
})

工作流程

  1. 用户在"MCP 设置"页面添加并连接服务器
  2. 服务器连接成功后,自动出现在聊天页面的 MCP 选择器中
  3. 选择服务器后,该服务器 ID 会被传递到聊天服务
  4. 聊天服务可以使用该服务器的工具(待实现)

当前状态

  • 基础架构完成MCP 服务器 ID 可以从 UI 传递到服务层
  • 服务器列表动态加载:实时显示已连接的服务器和工具数量
  • 自动重连:页面刷新后自动重连之前的服务器
  • 工具调用逻辑:已预留接口,等待实现

下一步实现

// 在 callModelStream 中检测 AI 的工具调用请求
private async callModelStream(
  conversation: Conversation,
  model: string | undefined,
  onChunk: (chunk: string) => void,
  mcpServerId?: string
): Promise<void> {
  if (mcpServerId) {
    // 1. 获取 MCP 服务器的可用工具列表
    const server = mcpStore.servers.find(s => s.id === mcpServerId)
    const tools = server?.capabilities?.tools || []
    
    // 2. 将工具列表传递给 AI 模型
    // 让 AI 知道可以调用哪些工具
    
    // 3. 如果 AI 返回工具调用请求,执行工具
    // const toolResult = await mcpStore.callTool(mcpServerId, toolName, params)
    
    // 4. 将工具结果返回给 AI让它生成最终回复
  }
  
  // 正常的流式响应
  // ...
}

📊 完整功能清单

已完成功能

  1. 左侧导航可折叠V2.0
  2. 右侧对话列表V2.0
  3. 右侧对话列表可折叠V2.1 新增)
  4. 工具栏 - MCP 服务选择
  5. 工具栏 - 模型动态加载V2.1 优化)
  6. MCP 服务集成基础架构V2.1 新增)
  7. 快捷操作按钮
  8. 消息实时更新
  9. 消息条数正确显示

待实现功能

  1. MCP 工具调用实际逻辑
  2. Markdown 渲染
  3. 代码语法高亮
  4. 真正的流式响应SSE
  5. 图片和文件消息

🎬 使用示例

场景1使用特定模型对话

  1. 添加模型服务

    侧边栏 → 模型服务 → 添加服务
    例如:添加"火山引擎"服务
    
  2. 在聊天中选择模型

    聊天页面 → 工具栏 → 点击"选择模型▼"
    选择:火山引擎 | doubao-1.5-pro-32k-character
    
  3. 发送消息

    输入框 → 输入"你好" → Enter
    AI 使用选中的模型回复
    

场景2使用 MCP 服务器扩展能力

  1. 添加 MCP 服务器

    侧边栏 → MCP 设置 → 添加服务器
    例如:添加"xhs-sse"服务器
    URL: http://localhost:3200
    
  2. 连接服务器

    点击"连接"按钮
    等待连接成功,显示可用工具数量
    
  3. 在聊天中选择 MCP

    聊天页面 → 工具栏 → 点击"不启用 MCP 服务▼"
    选择xhs-sse (5 个工具)
    
  4. 发送消息(准备使用工具)

    输入框 → 输入"搜索最新的 Vue 3 教程"
    AI 可以调用 MCP 工具进行搜索(功能待实现)
    

场景3折叠对话列表获得更大空间

  1. 隐藏对话列表

    点击右上角"隐藏列表"按钮
    对话列表平滑隐藏
    主对话区域扩大
    
  2. 再次显示

    点击"显示列表"按钮
    对话列表平滑显示
    

🔧 技术细节

数据流:模型选择

用户添加服务
    ↓
ModelService 连接
    ↓
modelStore.providers 更新
    ↓
modelOptions 计算属性更新
    ↓
下拉列表自动刷新
    ↓
用户选择模型
    ↓
selectedModel = "serviceId:modelId"
    ↓
发送消息时使用该模型
    ↓
modelServiceManager.sendChatRequest(serviceId, messages, modelId)

数据流MCP 集成

用户添加 MCP 服务器
    ↓
MCPClientService 连接
    ↓
mcpStore.servers 更新
    ↓
mcpOptions 计算属性更新
    ↓
下拉列表自动刷新
    ↓
用户选择 MCP 服务器
    ↓
selectedMCP = serverId
    ↓
发送消息时传递 serverId
    ↓
chatService.sendMessageStream(..., mcpServerId)
    ↓
callModelStream(..., mcpServerId)
    ↓
[待实现] mcpStore.callTool(mcpServerId, toolName, params)

关键组件关系

ChatLayout.vue
    ├─ uses chatStore (聊天状态管理)
    ├─ uses modelStore (模型列表)
    ├─ uses mcpStore (MCP 服务器列表)
    └─ calls sendMessageStream(content, model, mcpServerId)

chatStore.ts
    └─ calls chatService.sendMessageStream(options, onChunk, mcpServerId)

chatService.ts
    └─ calls callModelStream(conversation, model, onChunk, mcpServerId)
        └─ [TODO] 实现 MCP 工具调用逻辑

📝 配置示例

模型服务配置示例

{
  "id": "volcengine-001",
  "name": "火山引擎",
  "type": "volcengine",
  "url": "https://ark.cn-beijing.volces.com/api/v3",
  "apiKey": "your-api-key",
  "enabled": true,
  "models": [
    {
      "id": "doubao-1.5-pro-32k",
      "name": "豆包-1.5-pro-32k",
      "type": "chat"
    },
    {
      "id": "doubao-1.5-pro-32k-character",
      "name": "豆包-1.5-pro-32k-角色扮演",
      "type": "chat"
    }
  ]
}

MCP 服务器配置示例

{
  "id": "mcp-xhs-001",
  "name": "xhs-sse",
  "url": "http://localhost:3200",
  "transport": "sse",
  "status": "connected",
  "capabilities": {
    "tools": [
      {
        "name": "search",
        "description": "搜索互联网内容"
      },
      {
        "name": "read_file",
        "description": "读取本地文件"
      }
    ]
  }
}

🎯 下一步开发计划

优先级1MCP 工具调用实现

// 实现 AI 工具调用流程
1.  MCP 工具列表格式化为 OpenAI Function Calling 格式
2. 在调用模型时传递工具定义
3. 解析 AI 返回的工具调用请求
4. 执行 MCP 工具
5. 将结果返回给 AI
6. 显示完整的对话过程

优先级2模型切换优化

// 记住每个对话的模型选择
1.  Topic 中保存 modelId
2. 切换对话时自动选择对应模型
3. 支持为不同对话设置默认模型

优先级3UI 优化

// 更好的用户体验
1. 工具调用进度显示
2. MCP 工具调用结果可视化
3. 模型和 MCP 状态指示器
4. 更多的快捷键支持

⚠️ 注意事项

MCP 服务器要求

  1. 必须先配置:在"MCP 设置"中添加并连接服务器
  2. 连接状态:只有已连接的服务器才会出现在选择器中
  3. 自动重连:页面刷新后会自动尝试重连
  4. 工具数量:选择器显示每个服务器的工具数量

模型服务要求

  1. 必须先配置:在"模型服务"中添加服务
  2. 启用状态:只有启用的服务的模型才会出现
  3. 连接状态:建议先测试连接再使用
  4. API Key:确保 API Key 有效且有足够配额

性能建议

  1. 服务器数量:建议不超过 5 个 MCP 服务器同时连接
  2. 模型选择:根据对话复杂度选择合适的模型
  3. 工具调用:复杂工具可能需要更长时间

📖 更新记录

V2.12025/10/14

  • 右侧对话列表支持折叠
  • 模型选择器动态加载已配置的模型
  • MCP 服务集成基础架构完成
  • 自动重连 MCP 服务器
  • 完善的数据流和状态管理

V2.02025/10/14

  • 左侧导航可折叠
  • 右侧对话列表布局
  • 完整工具栏
  • 消息实时更新
  • 消息条数修复

优化完成! 🎉

现在您可以:

  1. 折叠对话列表获得更大空间
  2. 使用已配置的任意模型对话
  3. 选择 MCP 服务器(基础架构就绪)

继续完善 MCP 工具调用功能,敬请期待 V2.2