Files
xianren_studio/docs/ARCHITECTURE.md
T
xianrenge 10ecf526ec feat: add MCP/skill tool protocol, tasks/tools pages, chat UX overhaul
Tools page: skill & MCP server management with [[skill:]]/[[mcp:]] protocol (up to 3 rounds). New Tasks and Tools pages. Chat: session snapshots, empty-session reuse, per-message model_id, unified JSON prediction suggestions. Settings: upload size limit, prediction options, model enable/disable. Schema additions with ensure_column migrations. Add FEATURES/ARCHITECTURE docs.
2026-08-16 19:50:41 +08:00

247 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Xianren Studio(仙人工作室)代码组织与布局
> 本文档描述代码仓库的组织结构、模块职责、数据流与关键实现。**功能变更后如涉及结构、流程或数据模型,必须同步更新本文档。**
最后更新:2026-08-16
---
## 1. 总览
技术栈:Tauri 2Rust 壳 + WebView2 + React 18 / TypeScript / Vite / Tailwind,推理引擎为 llama.cpp 的 `llama-server` 子进程。
```
xianren_studio/
├── apps/desktop/ Tauri 桌面壳(Rust 命令层、tauri.conf.json、推荐模型默认 JSON
├── crates/core/ 领域核心:SQLite(模型注册表、会话、消息、设置)
├── crates/engine/ llama-server 生命周期 + 流式/非流式聊天(本地与远程 OpenAI 兼容)
├── crates/download/ 分片断点续传下载器
├── crates/api/ OpenAI 兼容本地 API 服务(axum
├── ui/ React 前端
├── scripts/ 构建 / 引擎与测试模型下载脚本
├── docs/ 产品与技术方案、功能记录、本文档
└── AGENTS.md 开发/维护约定(含文档同步规则)
```
---
## 2. 分层与数据流
```
React UIui/src
│ Tauri invokeapi.ts 封装)+ 事件监听(onEvent)
apps/desktop/src/commands.rs ← 所有 Tauri 命令(invoke_handler 注册于 lib.rs
├── crates/coreSQLitemodels / sessions / settings
├── crates/enginellama-server 子进程 / 远程 OpenAI API
├── crates/download(下载任务)
└── crates/api(本地 API 服务)
```
前端通过 `ui/src/api.ts``api.*` 方法调用后端命令;后端通过 Tauri `emit` 向前端推送事件(见 §7 事件通道)。
---
## 3. 前端结构(`ui/`
```
ui/src/
├── main.tsx 入口
├── App.tsx 导航栏、路由(7 个页面)、全局事件订阅(引擎/下载/模型/建议)
├── api.ts Tauri invoke 封装 + 全部请求/事件 TypeScript 类型
├── store.ts zustand 全局状态(见下)
├── styles.css 全局样式
├── components/Icon.tsx SVG 图标库
└── pages/
├── ChatPage.tsx 对话页(最大的页面,含会话快照、消息气泡、模型下拉、建议标签)
├── ModelsPage.tsx 模型管理(本地部署 + 在线 API 启用开关)
├── ModelPlazaPage.tsx 模型广场(HF/ModelScope 搜索与下载)
├── TasksPage.tsx 任务(下载/部署进度)
├── ToolsPage.tsx 工具(Tavily 联网搜索)
├── ServerPage.tsx 服务管理(本地 OpenAI API
└── SettingsPage.tsx 设置
```
### 3.1 全局状态(`store.ts`
主要状态字段:
| 字段 | 说明 |
| --- | --- |
| `models` | 模型列表(含 `enabled``kind``file_name` 等) |
| `engine` | 引擎状态(running / model / port |
| `deployStates` / `deployProgress` | 各模型部署状态(loading/ready/error)与进度 |
| `chatSuggestionsByMessage` | 消息 ID → 预测建议列表(全局接收,跨选项卡不丢) |
| `conversations` | 会话列表 |
| `tasks` | 下载/部署任务 |
| `server` | 本地 API 服务状态 |
### 3.2 会话快照(`ChatPage.tsx`
切换选项卡时 React Router 会卸载页面,因此 `ChatPage.tsx` 顶部维护了模块级 `chatSession` 对象(当前会话、所选模型、消息、输入草稿、请求参数、面板开合、工具、版本、附件),每次渲染后写回;重新挂载时用快照初始化,实现「切走再回来保持原状」。
---
## 4. 后端命令层(`apps/desktop`
### 4.1 `lib.rs`
- `run()`:初始化数据目录(`%APPDATA%\XianrenStudio`)、日志、panic 钩子;构建 Tauri 应用并注册 `invoke_handler`
- 数据目录:`logs/``models/``engines/``recommendations/`
### 4.2 `commands.rs`(命令分组)
| 分组 | 命令 |
| --- | --- |
| 应用/设置 | `app_info``settings_get``settings_set` |
| 模型 | `list_models``import_model``remove_model``set_model_enabled``scan_models``add_remote_model` |
| 模型广场 | `search_models``list_model_files``list_recommended_models``import_recommendations``fetch_model_page` |
| 会话 | `list_conversations``create_conversation``rename_conversation``set_conversation_pinned``set_conversation_favorite``import_conversation``set_conversation_tools``delete_conversation``get_messages` |
| 消息 | `chat_send``chat_stop``regenerate_message``edit_message``list_message_versions``apply_message_version` |
| 引擎 | `engine_start``engine_stop``engine_status``deploy_model` |
| 工具 | `web_search`Tavily)、`list_skills``add_skill``update_skill``remove_skill``set_skill_enabled``test_skill``list_mcp_servers``add_mcp_server``update_mcp_server``remove_mcp_server``set_mcp_server_enabled``mcp_test_server``mcp_list_tools``mcp_call_tool` |
| 下载 | `download_enqueue` |
| 服务 | `server_start``server_stop``server_status` |
| 其他 | `report_error``open_path` |
**聊天相关核心函数(均在 `commands.rs`):**
- `chat_send`:写入用户消息 → 构建历史 → 拉起后台生成任务。
- `run_generation_and_stream`:统一生成入口(本地引擎 / 远程 API),流式转发 token、统计用量、写库、发 `chat://done`,随后触发标题生成与建议生成。
- `maybe_generate_suggestions``call_suggestion_model``parse_suggestions`:回答完成后预测用户接下来可能说的话。统一要求模型输出 JSON 数组;最多重试 3 次;过滤元信息行与回答原文片段;每条 ≤ 30 字。
- `maybe_generate_conversation_title`:首轮对话自动生成标题。
- `create_conversation`:先查找空会话(`find_empty_conversation`)复用,没有才新建。
**工具协议(技能 / MCP):**
- `apps/desktop/src/tools.rs``ToolDef`、标记解析(`[[skill:名]]` / `[[mcp:服务:工具:参数]]`)、`MarkerFilter`(流式输出时过滤标记)、`run_tool_round`(执行工具并回填模型,最多 3 轮)、系统提示词构建。
- `apps/desktop/src/mcp_client.rs`MCP Streamable HTTP 客户端(`initialize` / `tools/list` / `tools/call`,兼容 SSE 响应)。
- 聊天链路:`chat_send` / `regenerate_message` / `edit_message` 解析会话工具并注入系统提示词 → `run_generation_and_stream` 流式输出时过滤标记 → 完成后执行工具循环并保存最终内容。
---
## 5. 核心库(`crates/core`
### 5.1 `app.rs`
- `CoreApp`:持有 SQLite 连接(`Mutex<Connection>`)与数据目录。
- `seed_default_settings`:启动时用 `insert_default` 补齐缺失的设置键(不覆盖用户已保存值)。
- `open_db`:执行 `schema.sql` + **增量迁移** `ensure_column`(为旧库补充新列,幂等)。
### 5.2 `schema.sql`(表结构)
| 表 | 关键字段 | 说明 |
| --- | --- | --- |
| `models` | `kind`local/remote)、`enabled``file_name``file_path``status``base_url``api_key``api_model``meta_json` | 模型注册表;`enabled` 决定在线 API 模型是否出现在聊天页可选列表 |
| `settings` | `key`/`value` | 键值设置 |
| `conversations` | `title``model_id``pinned``favorite``tools_json` | 会话 |
| `messages` | `role``model_id``content``tokens_in/out``elapsed_ms``first_token_ms``images_json` | 消息;`model_id` 记录该回答所用模型(回答下方展示模型名) |
| `message_versions` | `content``tokens_out``seq` | 重新生成前的旧版本 |
| `skills` | `name``description``content``enabled` | 技能工具库 |
| `mcp_servers` | `name``description``url``auth_token``enabled` | MCP 服务配置 |
迁移清单(`ensure_column`):`models.kind/base_url/api_key/api_model/enabled``messages.elapsed_ms/first_token_ms/images_json/model_id``conversations.pinned/favorite/tools_json`
### 5.3 `models.rs`
模型 CRUD、`set_enabled`(启用/停用)、`scan_directory`(扫描 GGUF 目录)、量化猜测 `guess_quant`
### 5.4 `sessions.rs`
会话/消息/版本 CRUD`find_empty_conversation`(新建对话复用空会话);`import_message`(导入对话用,可指定创建时间)。
### 5.5 `settings.rs`
`get/set/insert_default/all`
---
## 6. 引擎与远程调用(`crates/engine`
### 6.1 `manager.rs``EngineManager`
- `start`:以子进程启动 llama-server`CREATE_NO_WINDOW`),轮询 `/health` 等待就绪;最多 180s。
- `stop`:先请求 `/shutdown`,超时再 kill。
- `stream_chat` / `chat`:流式 / 非流式聊天(`/v1/chat/completions`)。
- `status`:返回 running / port / model。
### 6.2 `remote.rs`
- `stream_chat_remote` / `chat_remote`OpenAI 兼容远程 APIBearer 认证)。
- `normalize_base`Base URL 自动补 `/v1`
### 6.3 `types.rs`
- `ChatMessage`role/content/images,多模态时序列化为 content 数组。
- `ChatRequest`model / messages / temperature / top_p / max_tokens / stream。
- `ChatStreamEvent`Text / Reasoning(思考过程)/ Usage。
---
## 7. 事件通道(Tauri emit → 前端 onEvent
| 事件 | 方向 | 说明 |
| --- | --- | --- |
| `chat://token` | 后端→前端 | 流式增量文本 |
| `chat://reasoning` | 后端→前端 | 思考过程增量 |
| `chat://done` | 后端→前端 | 回答完成(含 message_id、model_id、用量) |
| `chat://suggestions` | 后端→前端 | 预测建议列表(全局订阅,存入 store) |
| `chat://tool-status` | 后端→前端 | 工具调用状态(running/done),界面提示 |
| `chat://message-updated` | 后端→前端 | 消息内容更新(恢复版本后) |
| `chat://title-updated` | 后端→前端 | 标题更新 |
| `chat://error` | 后端→前端 | 生成错误 |
| `engine://status` | 后端→前端 | 引擎状态变化 |
| `engine://deploy` | 后端→前端 | 部署状态(loading/ready/error |
| `engine://deploy-progress` | 后端→前端 | 部署进度百分比/阶段 |
| `models://updated` | 后端→前端 | 模型列表变化 |
| `download://started/progress/done/error` | 后端→前端 | 下载任务进度 |
| `server://status` | 后端→前端 | 本地 API 服务状态 |
---
## 8. 设置项(设置键 / 默认值)
定义于 `crates/core/src/app.rs``seed_default_settings`
| 键 | 默认值 | 用途 |
| --- | --- | --- |
| `model_dir` | 数据目录/models | 模型目录 |
| `engine_bin` | engines/cpu/llama-server.exe | llama-server 路径 |
| `backend` | auto | 后端(auto/cpu/cuda/vulkan |
| `hf_endpoint` | https://hf-mirror.com | 模型下载源 |
| `api_port` / `api_key` / `api_enabled` | 1234 / 空 / false | 本地 API 服务 |
| `upload_max_mb` | 10 | 上传大小上限 |
| `auto_title` | true | 自动生成标题 |
| `suggest_enabled` | true | 预测用户接下来说的话开关 |
| `suggest_count` | 3 | 预测条数(15 |
| `tavily_api_key` | (内置演示值) | 联网搜索 API Key |
| `tool_web_search_enabled` | true | 联网搜索工具开关 |
| `recommend_dir` | 数据目录/recommendations | 推荐列表目录 |
---
## 9. 构建与运行
```powershell
# 开发模式(自动拉起 Vite + Tauri
npm --prefix apps/desktop run dev
# 正式版(必须带 custom-protocol 特性,前端资源才会内嵌进 exe)
npm run build --prefix ui
cargo build --release -p xianren-desktop --features custom-protocol
# 或一键打包(tauri build 会自动启用该特性并打 NSIS 安装包)
npm --prefix apps/desktop run build
```
> 注意:不带 `custom-protocol` 编译出的 release exe **不会内嵌前端页面**,直接运行会白屏,因此正式发布必须带该特性。
---
## 10. 文档维护约定
- 功能变化 → 更新 `docs/FEATURES.md` 对应章节,并在「改动记录」追加。
- 结构/流程/数据模型变化 → 更新本文档对应章节。
- 大版本信息(技术栈、目录说明)变化 → 同步更新 `README.md`