diff --git a/README.md b/README.md index e8922d5..f82f64a 100644 --- a/README.md +++ b/README.md @@ -5,18 +5,35 @@ **中文名**:智队中枢 **英文名**:PIT Router -**当前版本**:v0.8.0 +**当前版本**:v0.8.1 --- ## 更新日志 +### v0.8.1 (2026-03-15) 🔧 技术方案修复 +- ✅ 修复 Bot 模型字段缺失(添加 owner_id, token_hash, is_system, capabilities) +- ✅ 修复消息路由逻辑(删除 gateway_id,只保留 agent_id 一对一绑定) +- ✅ 修复 WebSocket 事件命名冲突(区分 chat.send.* 和 chat.*) +- ✅ 修复 Connection 模型(移除 bot 类型,Bot 不直接连接) +- ✅ 修复 Message 模型(分离 sender_type 和 sender_name) +- ✅ 添加 Bot Config 详细配置结构 +- ✅ 添加 Bot 权限控制机制 +- ✅ 添加 Bot Token 认证机制 +- ✅ 明确前端架构为 Vue.js 3 SPA + ### v0.8.0 (2026-03-15) 🚀 新功能 - ✅ 新增智队机器人功能模块设计 - ✅ 新增 Bot 数据模型设计 - ✅ 新增机器人管理 API 设计 - ✅ 新增聊天界面设计 - ✅ 新增聊天 WebSocket 事件设计 +- ✅ **修复 Bot 模型字段缺失(添加 owner_id, token_hash, is_system)** +- ✅ **修复消息路由逻辑(删除 gateway_id,只保留 agent_id 绑定)** +- ✅ **修复 WebSocket 事件命名冲突(区分 chat.send.* 和 chat.*)** +- ✅ **修复 Connection/Message 模型语义问题** +- ✅ **添加 Bot 权限控制和安全机制** +- ✅ **明确前端架构为 Vue.js 3 SPA** - ⏳ 智队机器人功能开发中 ### v0.7.2 (2026-03-15) @@ -170,7 +187,7 @@ QQ 用户 → QQ 客户端 → QQ Bot(Channel 插件)→ OpenClaw Agent | 缓存 | Redis | 7+ | 会话缓存、消息队列 | | 数据库 | PostgreSQL | 15+ | 生产环境持久化 | | 部署 | Gunicorn + Nginx | - | 生产环境部署 | -| **前端** | **Jinja2 + Vue.js 3** | **-** | **🆕 聊天界面** | +| **前端** | **Vue.js 3 + Vite** | **-** | **🆕 聊天界面(SPA 单页应用)** | --- @@ -300,6 +317,8 @@ pit-router/ ### 🆕 机器人模型 (Bot) +> **设计理念**:Bot 是 Agent 的用户侧展示配置,一对一直接绑定 + | 字段 | 类型 | 说明 | |------|------|------| | id | String(36) | 主键 UUID | @@ -307,13 +326,42 @@ pit-router/ | display_name | String(80) | 显示名称 | | avatar | String(256) | 头像 URL | | description | Text | 机器人描述 | -| gateway_id | String(36) | 绑定的 Gateway ID,外键 | -| agent_id | String(36) | 绑定的 Agent ID,外键 | +| ~~gateway_id~~ | ~~String(36)~~ | ~~[已删除]~~ ~~绑定的 Gateway ID~~ | +| **owner_id** | **String(36)** | **所属用户 ID,外键,admin 可创建系统 Bot** | +| **agent_id** | **String(36)** | **绑定的 Agent ID,外键,一对一绑定** | +| **token_hash** | **String(256)** | **API 认证 Token 哈希(用于 Bot 独立认证)** | +| **is_system** | **Boolean** | **是否为系统级 Bot(所有用户可见)** | | status | String(20) | 状态:online/offline/busy | -| config | JSON | 配置(模型、温度等) | +| **capabilities** | **JSON** | **能力标签(如 ["chat", "code", "search"])** | +| config | JSON | 详细配置(见下方 Config 结构) | | created_at | DateTime | 创建时间 | | last_active_at | DateTime | 最后活跃时间 | +#### Bot Config 配置结构 + +```json +{ + "model": "gpt-4o", + "temperature": 0.7, + "max_tokens": 4096, + "system_prompt": "你是小白,一只专业硬核的程序狗...", + "rate_limit": { + "requests_per_minute": 60, + "tokens_per_day": 100000 + }, + "features": { + "streaming": true, + "markdown": true, + "code_highlight": true, + "file_upload": false + }, + "context": { + "max_history": 20, + "summary_threshold": 10 + } +} +``` + ### 会话模型 (Session) | 字段 | 类型 | 说明 | @@ -374,8 +422,10 @@ pit-router/ |------|------|------| | id | String(36) | 主键 UUID | | session_id | String(36) | 会话 ID,外键 | -| sender_type | String(20) | 发送者类型:user/agent/bot/system | +| sender_type | String(20) | 发送者类型:user/agent/system | | sender_id | String(36) | 发送者 ID | +| **sender_name** | **String(80)** | **发送者显示名称(可以是 Bot 名)** | +| **bot_id** | **String(36)** | **关联的 Bot ID(可选,用于展示)** | | message_type | String(20) | 消息类型:text/media/system | | content | Text | 消息内容 | | content_type | String(20) | 内容类型:markdown/plain/html | @@ -386,15 +436,20 @@ pit-router/ | created_at | DateTime | 创建时间 | | delivered_at | DateTime | 送达时间 | +> **设计说明**: +> - `sender_type` 只有 user/agent/system 三种,因为实际发送消息的是用户或 Agent +> - `sender_name` 用于显示,可以是 Bot 的名称(如"小白") +> - `bot_id` 关联到 Bot 模型,用于在 UI 中展示机器人信息 + ### 连接模型 (Connection) | 字段 | 类型 | 说明 | |------|------|------| | id | String(36) | 主键 UUID | | socket_id | String(100) | Socket.IO Socket ID | -| connection_type | String(20) | 连接类型:user/agent/gateway/bot | +| connection_type | String(20) | 连接类型:user/agent/gateway | | entity_id | String(36) | 关联实体 ID | -| entity_type | String(20) | 实体类型:user/agent/bot | +| entity_type | String(20) | 实体类型:user/agent | | ip_address | String(45) | IP 地址 (支持 IPv6) | | user_agent | String(500) | 客户端信息 | | status | String(20) | 状态:connected/disconnected | @@ -403,6 +458,8 @@ pit-router/ | last_activity | DateTime | 最后活动时间 | | disconnected_at | DateTime | 断开时间 | +> **说明**:Bot 不直接建立 WebSocket 连接,通过 Agent 连接。Connection 只追踪 user/agent/gateway 三种类型。 + --- ## HTTP API 设计 @@ -446,9 +503,11 @@ DELETE /api/chat/sessions/:id - 关闭会话 ### 会话 API +> **说明**:`/api/sessions` 为通用会话 API(兼容旧版本),聊天会话请使用 `/api/chat/sessions` + ``` -GET /api/sessions - 获取会话列表 -POST /api/sessions - 创建会话 +GET /api/sessions - 获取所有会话列表(含所有渠道类型) +POST /api/sessions - 创建通用会话 GET /api/sessions/:id - 获取会话详情 PUT /api/sessions/:id/close - 关闭会话 (替代 DELETE) GET /api/sessions/:id/messages - 获取会话消息 @@ -530,19 +589,22 @@ GET /api/stats/bots - 🆕 机器人统计 ### 🆕 聊天事件 +> **事件命名规范**:C→S 发送用 `chat.send.*`,S→C 接收用 `chat.*` + | 事件 | 方向 | 说明 | 参数 | |------|------|------|------| -| `chat.create` | C→S | 创建聊天会话 | `{ bot_id, title? }` | +| `chat.send.create` | C→S | 创建聊天会话 | `{ bot_id, title? }` | | `chat.created` | S→C | 会话已创建 | `{ session_id, bot }` | -| `chat.join` | C→S | 加入会话 | `{ session_id }` | +| `chat.send.join` | C→S | 加入会话 | `{ session_id }` | | `chat.joined` | S→C | 已加入会话 | `{ session_id, bot, messages }` | -| `chat.leave` | C→S | 离开会话 | `{ session_id }` | +| `chat.send.leave` | C→S | 离开会话 | `{ session_id }` | | `chat.left` | S→C | 已离开会话 | `{ session_id }` | -| `chat.message` | C→S | 发送消息 | `{ session_id, content, reply_to? }` | -| `chat.message` | S→C | 收到消息 | `{ message_id, session_id, sender_type, content, timestamp }` | -| `chat.typing` | C→S | 正在输入 | `{ session_id, is_typing }` | +| `chat.send.message` | C→S | 发送消息 | `{ session_id, content, reply_to? }` | +| `chat.message` | S→C | 收到消息 | `{ message_id, session_id, sender_type, sender_name, content, timestamp }` | +| `chat.send.typing` | C→S | 正在输入 | `{ session_id, is_typing }` | | `chat.typing` | S→C | 对方正在输入 | `{ session_id, is_typing }` | -| `chat.read` | C→S | 消息已读 | `{ session_id, message_ids }` | +| `chat.send.read` | C→S | 消息已读 | `{ session_id, message_ids }` | +| `chat.read` | S→C | 消息已读确认 | `{ session_id, message_ids }` | | `chat.closed` | S→C | 会话被关闭 | `{ session_id, reason }` | ### 会话事件 @@ -679,6 +741,7 @@ MESSAGE_RETENTION = { | WebSocket | JWT Query Param | ws://host/ws?token= | | Gateway | Token + IP 白名单 | 双重验证 | | 🆕 Chat UI | Session + JWT | 登录后访问 | +| 🆕 Bot API | Bot Token | X-Bot-Token: | ### Token 策略 @@ -687,6 +750,35 @@ MESSAGE_RETENTION = { | Access Token | 24 小时 | API 访问 | | Refresh Token | 7 天 | 刷新 Access Token | | Gateway Token | 永不过期 (可撤销) | Gateway 认证 | +| 🆕 Bot Token | 永不过期 (可撤销) | Bot API 认证 | + +### 🆕 Bot 权限控制 + +| 角色 | 权限 | +|------|------| +| **admin** | 创建/管理所有 Bot,绑定任意 Agent | +| **user** | 创建/管理自己的 Bot,绑定可访问的 Agent | +| **Bot Token** | 只能访问绑定 Agent 的会话 | + +```python +# Bot 权限检查逻辑 +def check_bot_permission(user, bot, action): + if user.role == 'admin': + return True # 管理员拥有所有权限 + + if action in ['view', 'use']: + # 系统级 Bot 所有用户可用 + if bot.is_system: + return True + # 自己的 Bot + return bot.owner_id == user.id + + if action in ['edit', 'delete', 'bind']: + # 只有所有者可以编辑/删除/绑定 + return bot.owner_id == user.id + + return False +``` ### 安全措施 @@ -700,6 +792,7 @@ MESSAGE_RETENTION = { | XSS | Jinja2 转义 | 自动转义输出 | | IP 白名单 | Middleware | Gateway 连接限制 | | 连接数限制 | Socket.IO | 单用户最大连接数 | +| 🆕 Bot Token 验证 | Middleware | 验证 Bot API 请求 | ---