830 lines
27 KiB
Markdown
830 lines
27 KiB
Markdown
|
||
# MCP Client Vue - 版本发布记录
|
||
|
||
## v1.0.0
|
||
重构时间: 2025-10-12
|
||
|
||
### 🎯 初始发布
|
||
|
||
#### 核心特性
|
||
- **MCP客户端基础功能** - 支持Model Context Protocol
|
||
- **双传输协议** - HTTP和SSE(Server-Sent Events)传输
|
||
- **Vue 3 + TypeScript** - 现代化前端技术栈
|
||
- **Naive UI组件库** - 美观的用户界面
|
||
- **Pinia状态管理** - 响应式数据流
|
||
|
||
#### 基础功能
|
||
- 服务器连接管理
|
||
- 工具调用执行
|
||
- 资源获取支持
|
||
- 提示词管理
|
||
- 基本的错误处理
|
||
|
||
#### 技术实现
|
||
- 前后端分离架构
|
||
- RESTful API设计
|
||
- 实时双向通信
|
||
- 模块化组件设计
|
||
- TypeScript类型安全
|
||
|
||
### 📋 项目结构
|
||
```
|
||
mcp-client-vue/
|
||
├── src/ # 后端服务
|
||
│ ├── server/ # Express服务器
|
||
│ └── types/ # TypeScript类型
|
||
├── web/ # Vue前端应用
|
||
│ ├── src/ # Vue组件和服务
|
||
│ ├── public/ # 静态资源
|
||
│ └── dist/ # 构建输出
|
||
└── docs/ # 项目文档
|
||
```
|
||
|
||
### 🎯 设计理念
|
||
- **用户友好** - 直观的操作界面
|
||
- **开发者友好** - 清晰的代码结构
|
||
- **可扩展性** - 模块化架构设计
|
||
- **跨平台** - 基于Web技术实现
|
||
|
||
---
|
||
|
||
## 下载和安装
|
||
|
||
### 系统要求
|
||
- Node.js 18.0+
|
||
- 现代浏览器(Chrome 90+, Firefox 88+, Safari 14+)
|
||
|
||
### 快速开始
|
||
```bash
|
||
# 克隆项目
|
||
git clone [repository-url]
|
||
cd mcp-client-vue
|
||
|
||
# 安装依赖
|
||
cd web && npm install
|
||
|
||
# 启动开发服务器
|
||
npm run dev
|
||
|
||
# 访问应用
|
||
open http://localhost:5173
|
||
```
|
||
|
||
### 生产构建
|
||
```bash
|
||
# 构建项目
|
||
npm run build
|
||
|
||
# 预览构建
|
||
npm run preview
|
||
```
|
||
|
||
---
|
||
|
||
## 支持和反馈
|
||
|
||
- 📖 [完整文档](./README.md)
|
||
- 📋 [更新日志](./CHANGELOG.md)
|
||
- 🐛 [问题报告](./CURRENT_STATUS.md)
|
||
- 📚 [开发指南](./DEVELOPMENT_GUIDE.md)
|
||
|
||
**MCP Client Vue - 让MCP集成变得简单高效** 🚀
|
||
|
||
## v1.0.1
|
||
|
||
重构时间: 2025-10-14
|
||
|
||
### 🎉 重大改进
|
||
|
||
基于v1.0.0的深度优化版本,全面提升了用户体验和系统稳定性。
|
||
|
||
#### 🚀 核心功能
|
||
- **完善的服务器管理系统**
|
||
- 支持HTTP和SSE双传输协议
|
||
- 可视化连接状态管理
|
||
- 自动重连机制(页面刷新恢复连接)
|
||
- 智能URL地址转换(0.0.0.0 → localhost)
|
||
|
||
#### 🛠️ 主要修复
|
||
- ✅ **编辑按钮响应** - 修复点击无响应问题
|
||
- ✅ **连接协议** - 修复HTTP 406和SSE 404错误
|
||
- ✅ **界面显示** - 修复模态框空白页问题
|
||
- ✅ **表单数据** - 修复字段不填充问题
|
||
- ✅ **状态持久化** - 修复页面刷新断连问题
|
||
|
||
#### 🎨 用户体验
|
||
- 优化模态框尺寸(90vw宽度,最大1200px)
|
||
- 改进表单验证和错误提示
|
||
- 实时连接状态指示
|
||
- 详细的操作日志和调试信息
|
||
|
||
#### 🏗️ 技术栈升级
|
||
- Vue 3.4.15
|
||
- TypeScript 5.3.3
|
||
- Naive UI 2.43.1
|
||
- vue-tsc 2.0.6(从1.8.25升级)
|
||
|
||
### 📦 发布内容
|
||
|
||
```bash
|
||
# 安装和启动
|
||
cd web && npm install
|
||
npm run dev
|
||
```
|
||
|
||
### 🔧 配置要求
|
||
|
||
#### HTTP服务器
|
||
```json
|
||
{
|
||
"name": "HTTP服务器",
|
||
"url": "http://localhost:3100",
|
||
"type": "http"
|
||
}
|
||
```
|
||
|
||
#### SSE服务器
|
||
```json
|
||
{
|
||
"name": "SSE服务器",
|
||
"url": "http://localhost:3200/sse",
|
||
"type": "sse"
|
||
}
|
||
```
|
||
|
||
### ⚠️ 已知问题
|
||
- TypeScript类型错误47个(不影响功能)
|
||
- 使用 `npm run build:skip-check` 跳过类型检查
|
||
|
||
---
|
||
|
||
## v1.0.2
|
||
|
||
发布时间: 2025-10-14
|
||
|
||
### 🎯 重大功能:MCP 工具调用集成
|
||
|
||
本版本实现了完整的 MCP 工具调用功能,AI 可以智能调用 MCP 服务器提供的工具并整合结果。
|
||
|
||
#### ✨ 核心功能
|
||
|
||
**🔧 智能工具调用**
|
||
- AI 自动识别何时需要调用工具
|
||
- 支持 OpenAI Function Calling 协议
|
||
- 兼容多个 AI 服务商(OpenAI、火山引擎、阿里云等)
|
||
- 完整的多轮对话支持(AI → Tool → AI)
|
||
|
||
**🔄 流式工具执行**
|
||
- 实时显示工具调用进度
|
||
- 流式体验不中断
|
||
- 友好的状态提示:
|
||
- 🔧 正在调用工具: [工具名]...
|
||
- ✅ 工具执行完成
|
||
- ❌ 工具执行失败: [错误信息]
|
||
- 🤖 正在生成回复...
|
||
|
||
**📋 工具格式转换**
|
||
- MCP 工具 → OpenAI Function 格式
|
||
- 自动提取 inputSchema 作为 parameters
|
||
- 支持完整的 JSON Schema 定义
|
||
|
||
#### 🛠️ 技术实现
|
||
|
||
**服务层改进**
|
||
- `MCPClientService.getTools()` - 获取工具列表
|
||
- `chatService.convertToolsToOpenAIFormat()` - 格式转换
|
||
- `chatService.executeToolCalls()` - 工具执行逻辑
|
||
- `modelServiceManager.sendChatRequestStream()` - 增强工具参数支持
|
||
|
||
**流式解析增强**
|
||
- SSE 流中检测 `tool_calls`
|
||
- 累积多个流片段中的工具调用数据
|
||
- 正确拼接 `function.arguments` JSON 字符串
|
||
- 返回完整的工具调用数组
|
||
|
||
**消息格式支持**
|
||
```typescript
|
||
// 工具调用消息
|
||
{
|
||
role: 'assistant',
|
||
content: '',
|
||
tool_calls: [{
|
||
id: '...',
|
||
type: 'function',
|
||
function: { name: '...', arguments: '{}' }
|
||
}]
|
||
}
|
||
|
||
// 工具结果消息
|
||
{
|
||
tool_call_id: '...',
|
||
role: 'tool',
|
||
name: 'tool_name',
|
||
content: '{...}'
|
||
}
|
||
```
|
||
|
||
#### 📦 使用方式
|
||
|
||
1. **配置 AI 服务** - 在"模型服务"中添加支持函数调用的 AI
|
||
2. **连接 MCP 服务器** - 在"MCP 设置"中添加工具服务器
|
||
3. **选择模型和 MCP** - 在对话界面选择
|
||
4. **开始对话** - AI 会自动调用相关工具
|
||
|
||
#### 💡 使用示例
|
||
|
||
```
|
||
用户: "查询今天北京的天气"
|
||
|
||
系统: 🔧 正在调用工具: get_weather...
|
||
✅ 工具执行完成
|
||
🤖 正在生成回复...
|
||
|
||
AI: "根据天气数据,今天北京晴天,温度 15-25°C,
|
||
空气质量良好,适合户外活动。"
|
||
```
|
||
|
||
#### 🐛 Bug 修复
|
||
|
||
- ✅ 修复 MCPClientService 类型导入问题
|
||
- ✅ 修复 types.ts 和 types/index.ts 路径冲突
|
||
- ✅ 修复 modelServiceManager 返回类型
|
||
- ✅ 修复未使用变量警告
|
||
|
||
#### 🔧 技术细节
|
||
|
||
**修改的文件**
|
||
- `/web/src/services/chatService.ts` - 工具调用主逻辑
|
||
- `/web/src/services/modelServiceManager.ts` - 工具参数支持
|
||
- `/web/src/services/MCPClientService.ts` - 工具列表获取
|
||
|
||
**新增方法**
|
||
- `MCPClientService.getTools(serverId)` - 获取服务器工具
|
||
- `chatService.convertToolsToOpenAIFormat()` - 格式转换
|
||
- `chatService.executeToolCalls()` - 执行工具调用
|
||
|
||
**改进方法**
|
||
- `modelServiceManager.sendChatRequestStream()` - 支持 tools 参数
|
||
- `modelServiceManager.makeChatRequestStream()` - 检测和收集 tool_calls
|
||
|
||
#### 🎯 设计亮点
|
||
|
||
1. **无缝集成** - 不改变现有对话流程
|
||
2. **错误恢复** - 工具调用失败不影响对话继续
|
||
3. **类型安全** - 完整的 TypeScript 类型定义
|
||
4. **性能优化** - 流式处理保持响应速度
|
||
5. **用户友好** - 清晰的进度提示
|
||
|
||
#### ⚙️ 配置要求
|
||
|
||
**AI 服务要求**
|
||
- 支持 OpenAI Function Calling 格式
|
||
- 推荐:OpenAI GPT-3.5+, GPT-4+
|
||
- 兼容:火山引擎、阿里云等 OpenAI 兼容服务
|
||
|
||
**MCP 服务器要求**
|
||
- 实现 `tools/list` 接口
|
||
- 实现 `tools/call` 接口
|
||
- 提供标准的 inputSchema (JSON Schema)
|
||
|
||
### 📚 相关文档
|
||
|
||
- [完整文档](./README.md)
|
||
- [更新日志](./CHANGELOG.md)
|
||
- [故障排除](./CURRENT_STATUS.md)
|
||
|
||
### 🚀 升级指南
|
||
|
||
```bash
|
||
# 拉取最新代码
|
||
git pull origin main
|
||
|
||
# 安装依赖(如有更新)
|
||
cd web && npm install
|
||
|
||
# 启动开发服务器
|
||
npm run dev
|
||
```
|
||
|
||
### 🔜 下一步计划
|
||
|
||
- 工具调用历史记录
|
||
- 工具执行超时控制
|
||
- 批量工具调用优化
|
||
- 工具调用权限管理
|
||
- 工具调用性能监控
|
||
|
||
**v1.0.2 - AI + MCP 工具调用,让对话更智能!** 🚀🔧
|
||
|
||
## v1.0.3
|
||
|
||
发布时间: 2025-10-15
|
||
|
||
### 重大功能:停止生成 & UI 优化
|
||
|
||
本版本实现了完整的停止生成功能,参考 Cherry Studio 的 PAUSED 状态设计,提供更好的用户体验。
|
||
|
||
#### 核心功能
|
||
|
||
**智能停止生成**
|
||
- 点击停止按钮立即中断 AI 回复(响应时间 < 100ms)
|
||
- 保留已生成的内容,标记为"已停止"状态
|
||
- 区分用户主动停止和系统错误
|
||
- 停止后可立即继续对话
|
||
|
||
**UI 体验优化**
|
||
- 按钮文字从"确认"改为"发送"
|
||
- 停止后显示黄色"已停止"标签(而非红色"发送失败")
|
||
- 停止的消息可以复制、重新生成、删除
|
||
- 实时状态反馈(发送中 → 已停止 → 可操作)
|
||
|
||
**状态管理增强**
|
||
- 新增 `paused` 消息状态
|
||
- 新增 `paused` 流式事件类型
|
||
- 完整的 AbortController 信号传递链
|
||
- 流读取循环实时检查中止信号
|
||
|
||
#### 技术实现
|
||
|
||
**按钮事件修复**
|
||
- 修复点击事件绑定问题(从三元表达式改为函数调用)
|
||
- 运行时动态判断状态,而非编译时
|
||
```typescript
|
||
// Before: @click="store.state.isSending ? handleStopGeneration : handleSendMessage"
|
||
// After: @click="handleButtonClick"
|
||
const handleButtonClick = () => {
|
||
if (store.state.isSending) {
|
||
handleStopGeneration()
|
||
} else {
|
||
handleSendMessage()
|
||
}
|
||
}
|
||
```
|
||
|
||
**中止信号传递链**
|
||
```
|
||
UI (点击停止)
|
||
↓ handleStopGeneration()
|
||
↓ store.stopGeneration()
|
||
↓ abortController.abort()
|
||
↓ chatService.sendMessageStream(signal)
|
||
↓ modelServiceManager.makeChatRequestStream(signal)
|
||
↓ while循环检查 signal.aborted
|
||
↓ reader.cancel() + 抛出 AbortError
|
||
↓ 状态设置为 'paused'
|
||
↓ UI 更新显示"已停止"
|
||
```
|
||
|
||
**流读取中止检查**
|
||
```typescript
|
||
while (true) {
|
||
// 关键:每次读取前检查中止信号
|
||
if (signal?.aborted) {
|
||
console.log('检测到中止信号,停止读取流')
|
||
reader.cancel()
|
||
throw new DOMException('用户中止操作', 'AbortError')
|
||
}
|
||
|
||
const { done, value } = await reader.read()
|
||
if (done) break
|
||
|
||
// 处理数据...
|
||
}
|
||
```
|
||
|
||
**错误处理优化**
|
||
```typescript
|
||
catch (error) {
|
||
const isAborted = error instanceof Error && error.name === 'AbortError'
|
||
|
||
if (isAborted) {
|
||
// 用户主动停止 - 标记为 paused,保留内容
|
||
assistantMessage.status = 'paused'
|
||
assistantMessage.error = undefined
|
||
onChunk({ type: 'paused', messageId: assistantMessage.id })
|
||
|
||
// 关键:更新消息列表,触发 UI 刷新
|
||
state.messages = [...chatService.getMessages(currentTopicId)]
|
||
} else {
|
||
// 真实错误 - 标记为 error
|
||
assistantMessage.status = 'error'
|
||
assistantMessage.error = error.message
|
||
}
|
||
}
|
||
```
|
||
|
||
#### Bug 修复
|
||
|
||
### Emoji 测试
|
||
|
||
为验证发布脚本对 emoji 的处理(例如某些 emoji 属于 4 字节 unicode,可能触发服务器端 collation 问题),在此插入若干 emoji 供测试:
|
||
|
||
- 表情类:😄 😂 😭 🥳
|
||
- 物品/动作:🚀 🧪 🔧 📝
|
||
- 动物/自然:🐛 🐶 🌳
|
||
- 标志/符号:🏷️ ✅ ❌ 🔣
|
||
|
||
示例行(包含中文和 emoji):
|
||
|
||
> 测试:本行包含中文与 emoji,目的是验证脚本对 emoji 的过滤与回退逻辑。示例 emoji:😄 🚀 🐛 🧪 🏷️
|
||
|
||
- 修复按钮点击无响应问题(事件绑定错误)
|
||
- 修复停止后仍显示"发送中..."状态
|
||
- 修复停止后消息列表不更新
|
||
- 修复 AbortError 被错误标记为失败
|
||
- 修复按钮文字显示"确认"而非"发送"
|
||
|
||
#### 修改的文件
|
||
|
||
**类型定义**
|
||
- `/web/src/types/chat.ts`
|
||
- MessageStatus 添加 `'paused'` 类型
|
||
- StreamEvent 添加 `'paused'` 事件类型
|
||
|
||
**UI 组件**
|
||
- `/web/src/components/Chat/ChatLayout.vue`
|
||
- 修复按钮点击事件绑定
|
||
- 按钮文字改为"发送"
|
||
- 添加"已停止"状态标签显示
|
||
- paused 状态消息显示操作按钮
|
||
|
||
**服务层**
|
||
- `/web/src/services/chatService.ts`
|
||
- 区分 AbortError 和其他错误
|
||
- 设置 paused 状态和事件
|
||
|
||
- `/web/src/services/modelServiceManager.ts`
|
||
- 流读取循环中检查 signal.aborted
|
||
- 调用 reader.cancel() 中止读取
|
||
- 正确处理 AbortError
|
||
|
||
**状态管理**
|
||
- `/web/src/stores/chatStore.ts`
|
||
- 在 catch 块中更新消息列表
|
||
- 确保 UI 显示最新状态
|
||
|
||
#### 使用示例
|
||
|
||
```
|
||
1. 用户发送:"请详细介绍 Vue 3 的新特性"
|
||
2. AI 开始回复,显示"发送中..."
|
||
3. 用户点击"停止"按钮
|
||
4. 立即响应:
|
||
- 输出停止
|
||
- 标签变为"已停止"(黄色)
|
||
- 显示已生成的内容
|
||
- 显示操作按钮
|
||
5. 用户可以:
|
||
- 复制已生成的内容
|
||
- 重新生成完整回复
|
||
- 删除该消息
|
||
- 继续发送新消息
|
||
```
|
||
|
||
#### 设计亮点
|
||
|
||
1. **参考 Cherry Studio** - 借鉴成熟产品的设计理念
|
||
2. **立即响应** - 停止操作 < 100ms 响应
|
||
3. **内容保留** - 部分生成的内容依然有价值
|
||
4. **状态区分** - paused vs error,语义更清晰
|
||
5. **完整操作** - 停止的消息仍可进行各种操作
|
||
6. **信号传递** - 完整的中止信号链,确保可靠性
|
||
|
||
#### 用户体验对比
|
||
|
||
**修复前**
|
||
- 点击停止无反应
|
||
- 继续显示"发送中..."
|
||
- 显示 loading 动画
|
||
- 按钮文字为"确认"
|
||
|
||
**修复后**
|
||
- 点击立即停止
|
||
- 显示"已停止"(黄色)
|
||
- 隐藏 loading 动画
|
||
- 按钮文字为"发送"
|
||
- 可以操作停止的消息
|
||
- 立即可继续对话
|
||
|
||
#### 相关文档
|
||
|
||
- `STOP_GENERATION_SUMMARY.md` - 修复总结
|
||
- `STOP_GENERATION_FIX.md` - 详细技术文档
|
||
- `STOP_GENERATION_PATCH.md` - 补充修复说明
|
||
- `STOP_GENERATION_TEST.md` - 测试指南
|
||
- `STOP_GENERATION_VERIFY.md` - 快速验证清单
|
||
|
||
#### 升级指南
|
||
|
||
```bash
|
||
# 拉取最新代码
|
||
git pull origin main
|
||
|
||
# 安装依赖
|
||
cd web && npm install
|
||
|
||
# 启动开发服务器
|
||
npm run dev
|
||
|
||
# 测试停止功能
|
||
# 1. 发送消息
|
||
# 2. 在 AI 回复时点击"停止"
|
||
# 3. 验证显示"已停止"标签
|
||
# 4. 验证可以继续对话
|
||
```
|
||
|
||
#### 验收标准
|
||
|
||
- [x] 按钮点击有明显反应
|
||
- [x] 流输出在 100ms 内停止
|
||
- [x] 显示"已停止"而非"失败"
|
||
- [x] 保留已生成内容
|
||
- [x] 停止后可立即继续对话
|
||
- [x] 可对停止的消息进行操作
|
||
- [x] 无意外错误日志
|
||
|
||
#### 下一步计划
|
||
|
||
- 停止后自动保存草稿
|
||
- 停止历史记录统计
|
||
- 批量停止多个会话
|
||
- 停止原因记录(用户主动/超时/错误)
|
||
- 性能监控和优化
|
||
|
||
**v1.0.3 - 完美的停止体验,让对话更可控!**
|
||
|
||
## v2.0.0
|
||
重构时间: 2025-10-16
|
||
|
||
### Phase 1: 核心服务拆分 (Day 1-2) ✅ 已完成
|
||
- ✅ Step 1: 创建服务目录结构 `/web/src/services/chat/`
|
||
- ✅ Step 2: 提取 MessageService - 消息 CRUD 操作(20+ 方法)
|
||
- ✅ Step 3: 提取 ConversationService - 对话管理(10+ 方法)
|
||
- ✅ Step 4: 创建统一日志系统 Logger (支持日志级别、命名空间、格式化)
|
||
- ✅ Step 5: 创建错误处理体系 AppError (ValidationError, NetworkError, APIError, ServiceError, StorageError + ErrorHandler)
|
||
- ✅ Step 6: 提取 StreamProcessor - 流式响应处理(性能监控、批量输出、工具集成)
|
||
- ✅ Step 7: 提取 ToolExecutor - 工具调用执行(递归调用链、错误处理)
|
||
- ✅ Step 8: 创建 ChatOrchestrator - 协调所有服务(话题管理、消息管理、流式发送、持久化 + togglePin/Favorite/Archive)
|
||
- ✅ Step 9: 更新 chatStore 使用新服务(已完成:chatService → chatOrchestrator)
|
||
- ⏸️ Step 10: 测试验证,确保无功能回归
|
||
|
||
**✅ Phase 1 重构完成!旧的 chatService.ts (1147行) 已完全被新架构替代。**
|
||
|
||
**服务架构总结:**
|
||
```
|
||
ChatOrchestrator (协调器)
|
||
├── MessageService (消息 CRUD)
|
||
├── ConversationService (对话管理)
|
||
├── StreamProcessor (流式处理)
|
||
└── ToolExecutor (工具执行)
|
||
|
||
工具层:
|
||
├── Logger (统一日志)
|
||
└── AppError + ErrorHandler (错误处理)
|
||
```
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ 用户界面层 (UI) │
|
||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||
│ │ 聊天视图 │ │ 设置视图 │ │ 模型管理 │ │ MCP管理 │ │
|
||
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
||
└─────────────────────────────────────────────────────────┘
|
||
↓ ↑
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ 状态管理层 (Pinia Stores) │
|
||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||
│ │chatStore │ │modelStore│ │ mcpStore │ │
|
||
│ └──────────┘ └──────────┘ └──────────┘ │
|
||
└─────────────────────────────────────────────────────────┘
|
||
↓ ↑
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ 业务服务层 (Services) │
|
||
│ ┌─────────────────────────────────────────────────────┐│
|
||
│ │ ChatOrchestrator (协调器) ││
|
||
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ││
|
||
│ │ │ Message │ │Conversation│ │ Stream │ ││
|
||
│ │ │ Service │ │ Service │ │ Processor │ ││
|
||
│ │ └────────────┘ └────────────┘ └────────────┘ ││
|
||
│ │ ┌────────────┐ ││
|
||
│ │ │ Tool │ ││
|
||
│ │ │ Executor │ ││
|
||
│ │ └────────────┘ ││
|
||
│ └─────────────────────────────────────────────────────┘│
|
||
│ ┌──────────────┐ ┌──────────────┐ │
|
||
│ │ModelService │ │MCPClientSvc │ │
|
||
│ │ Manager │ │ │ │
|
||
│ └──────────────┘ └──────────────┘ │
|
||
└─────────────────────────────────────────────────────────┘
|
||
↓ ↑
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ 工具层 (Utils) │
|
||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||
│ │ Logger │ │ Error │ │Validation│ │
|
||
│ │ │ │ Handler │ │ │ │
|
||
│ └──────────┘ └──────────┘ └──────────┘ │
|
||
└─────────────────────────────────────────────────────────┘
|
||
↓ ↑
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ 数据持久化层 (Storage) │
|
||
│ ┌──────────┐ ┌──────────┐ │
|
||
│ │localStorage│ │IndexedDB │ (未来) │
|
||
│ └──────────┘ └──────────┘ │
|
||
└─────────────────────────────────────────────────────────┘
|
||
↓ ↑
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ 后端服务 (Node.js) │
|
||
│ ┌──────────┐ ┌──────────┐ │
|
||
│ │LLMService│ │MCPManager│ │
|
||
│ └──────────┘ └──────────┘ │
|
||
└─────────────────────────────────────────────────────────┘
|
||
↓ ↑
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ 外部服务 (External APIs) │
|
||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||
│ │阿里通义 │ │ 火山方舟 │ │MCP Servers│ │
|
||
│ └──────────┘ └──────────┘ └──────────┘ │
|
||
└─────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 发送消息流程
|
||
|
||
```
|
||
用户输入消息
|
||
↓
|
||
ChatLayout 组件触发事件
|
||
↓
|
||
chatStore.sendMessage()
|
||
↓
|
||
ChatOrchestrator.sendMessageStream()
|
||
↓
|
||
1. MessageService 创建用户消息
|
||
2. 更新话题信息
|
||
3. 持久化到 localStorage
|
||
↓
|
||
4. MessageService 创建助手消息占位符
|
||
↓
|
||
5. StreamProcessor.processStream()
|
||
├─ 准备工具列表(如有 MCP)
|
||
├─ 准备上下文消息(限制 20 条)
|
||
├─ 选择服务和模型
|
||
└─ 执行流式请求
|
||
↓
|
||
6. 流式响应 onChunk 回调
|
||
└─ MessageService.appendMessageContent()
|
||
└─ 触发 UI 更新
|
||
↓
|
||
7. 检查是否有工具调用
|
||
└─ 是: ToolExecutor.executeToolCalls()
|
||
├─ 执行每个工具
|
||
├─ 收集工具结果
|
||
└─ 发送结果给 AI(递归)
|
||
└─ 否: 完成
|
||
↓
|
||
8. 更新消息状态为 'success'
|
||
9. 更新话题最后消息
|
||
10. 持久化
|
||
↓
|
||
UI 展示最终消息
|
||
```
|
||
|
||
### 核心服务
|
||
|
||
#### 1. ChatOrchestrator(聊天协调器)
|
||
|
||
**职责**:
|
||
- 统一对外接口
|
||
- 协调各服务完成业务流程
|
||
- 管理话题和对话
|
||
- 处理持久化
|
||
|
||
**核心方法**:
|
||
```typescript
|
||
class ChatOrchestrator {
|
||
// 话题管理
|
||
createTopic(name: string, options?: CreateTopicOptions): Topic
|
||
getTopics(filter?: TopicFilter): Topic[]
|
||
updateTopic(topicId: string, updates: Partial<Topic>): boolean
|
||
deleteTopic(topicId: string): boolean
|
||
|
||
// 消息管理
|
||
getMessages(topicId: string): Message[]
|
||
deleteMessage(topicId: string, messageId: string): boolean
|
||
|
||
// 发送消息
|
||
sendMessageStream(
|
||
options: SendMessageOptions,
|
||
onChunk: (event: StreamEvent) => void,
|
||
mcpServerId?: string,
|
||
signal?: AbortSignal
|
||
): Promise<void>
|
||
|
||
// 重新生成
|
||
regenerateMessage(topicId: string, messageId: string): Promise<Message>
|
||
|
||
// 持久化
|
||
private saveTopics(): void
|
||
private loadTopics(): void
|
||
private saveConversations(): void
|
||
private loadConversations(): void
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### 2. MessageService(消息服务)
|
||
|
||
**职责**:
|
||
- 消息 CRUD
|
||
- 消息状态管理
|
||
- 消息查询和过滤
|
||
|
||
**核心方法**:
|
||
```typescript
|
||
class MessageService {
|
||
createMessage(conversationId: string, options: CreateMessageOptions): Message
|
||
getMessages(conversationId: string): Message[]
|
||
getMessagesByTopicId(topicId: string): Message[]
|
||
updateMessage(conversationId: string, messageId: string, options: UpdateMessageOptions): boolean
|
||
updateMessageStatus(conversationId: string, messageId: string, status: MessageStatus): boolean
|
||
appendMessageContent(conversationId: string, messageId: string, content: string): boolean
|
||
deleteMessage(conversationId: string, messageId: string): boolean
|
||
deleteMessagesAfter(conversationId: string, messageId: string): boolean
|
||
getSuccessMessages(conversationId: string): Message[]
|
||
getRecentSuccessMessages(conversationId: string, limit: number): Message[]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### 3. ConversationService(对话服务)
|
||
|
||
**职责**:
|
||
- 对话创建、读取、删除
|
||
- 对话元数据管理
|
||
- 对话与话题的关联
|
||
|
||
**核心方法**:
|
||
```typescript
|
||
class ConversationService {
|
||
createConversation(options: CreateConversationOptions): Conversation
|
||
getConversation(conversationId: string): Conversation | undefined
|
||
getConversationByTopicId(topicId: string): Conversation | undefined
|
||
deleteConversation(conversationId: string): boolean
|
||
deleteConversationByTopicId(topicId: string): boolean
|
||
updateMetadata(conversationId: string, metadata: Partial<Conversation['metadata']>): boolean
|
||
clearMessages(conversationId: string): boolean
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### 4. StreamProcessor(流式处理器)
|
||
|
||
**职责**:
|
||
- 处理流式响应
|
||
- 性能监控
|
||
- 批量输出
|
||
- 工具集成
|
||
|
||
**核心方法**:
|
||
```typescript
|
||
class StreamProcessor {
|
||
async processStream(options: StreamOptions): Promise<StreamResult>
|
||
|
||
private prepareTools(mcpServerId?: string): Promise<{ tools: any[], mcpServerName: string }>
|
||
private prepareMessages(conversation: Conversation, tools: any[], mcpServerName: string): any[]
|
||
private selectServiceAndModel(requestedModel?: string): { service: any, selectedModel: string }
|
||
private executeStream(...): Promise<StreamResult>
|
||
}
|
||
```
|
||
|
||
**特性**:
|
||
- 上下文限制:最近 20 条消息
|
||
- 批量输出:每 3 个字符一次(增强流式效果)
|
||
- 性能监控:首字延迟、总耗时、chunk 数
|
||
- 工具集成:自动注入系统提示词
|
||
|
||
---
|
||
|
||
#### 5. ToolExecutor(工具执行器)
|
||
|
||
**职责**:
|
||
- 解析工具调用请求
|
||
- 执行 MCP 工具
|
||
- 处理工具结果
|
||
- 支持递归工具链
|
||
|
||
**核心方法**:
|
||
```typescript
|
||
class ToolExecutor {
|
||
async executeToolCalls(options: ToolCallOptions): Promise<void>
|
||
|
||
private executeTools(toolCalls: any[], mcpServerId: string, onChunk: Function): Promise<ToolCallResult[]>
|
||
private executeSingleTool(toolCall: any, mcpServerId: string, onChunk: Function): Promise<ToolCallResult>
|
||
private sendToolResultsToAI(...): Promise<void>
|
||
private buildMessagesWithToolResults(...): any[]
|
||
}
|
||
```
|
||
|