# 智队中枢 > PIT 网关路由应用 - Personal Intelligent Team Gateway Router Service **中文名**:智队中枢 **英文名**:PIT Router **当前版本**:v0.9.8 --- ## 更新日志 ### v0.9.8 (2026-03-15) 🎨 Markdown 渲染和代码高亮 - ✅ 新增 MarkdownMessage.vue 组件 - ✅ 集成 markdown-it 解析器 - ✅ 集成 highlight.js 代码高亮 - ✅ 支持 GitHub Dark 主题 - ✅ 自定义标题、列表、代码块样式 ### v0.9.7 (2026-03-15) 🔗 绑定/解绑 Agent - ✅ 新增 BotSettingsModal.vue 组件 - ✅ 新增 GET /api/agents/available 接口 - ✅ 支持机器人绑定 Agent - ✅ 支持机器人解绑 Agent - ✅ 状态自动同步 ### v0.9.6 (2026-03-15) ➕ 新建机器人 - ✅ 新增 CreateBotModal.vue 组件 - ✅ 头像选择器(12 个预设) - ✅ 表单验证 - ✅ 创建成功自动刷新列表 ### v0.9.1 (2026-03-15) 📝 技术方案完善 - ✅ 完善新建智队机器人技术方案 - ✅ 完善机器人绑定 Agent 流程 - ✅ 添加创建聊天会话流程说明 - ✅ 添加完整使用流程说明 - ✅ 添加前端新建机器人功能 ### v0.9.0 (2026-03-15) 🎉 智队机器人功能完成 - ✅ Bot 数据模型实现 (app/models/bot.py) - ✅ 机器人管理 API 实现 (app/routes/bots.py) - ✅ 聊天会话 API 实现 (app/routes/chat.py) - ✅ 聊天 WebSocket 事件处理 (app/socketio/chat_handlers.py) - ✅ 机器人服务层实现 (app/services/bot_service.py) - ✅ 数据库迁移脚本 (migrations/versions/add_bot_model.py) - ✅ 前端聊天界面 (Vue.js 3 SPA) - ChatWindow.vue - 聊天窗口组件 - BotSelector.vue - 机器人选择器 - ChatSidebar.vue - 会话侧边栏 - ChatView.vue - 聊天视图 - ✅ 前端状态管理 (stores/chat.ts) ### 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) - ✅ 修复暗黑主题切换不生效的问题 - ✅ 修复暗黑主题切换时的页面闪烁问题 - ✅ 完善 Web UI 细节(会话详情页、频道编辑页、错误页面) - ✅ 优化自动部署脚本(备份策略、健康检查) ### v0.7.1 (2026-03-15) - ✅ 登录页面,支持外网访问 Web UI - ✅ 添加自动部署脚本 - ✅ 添加 Webhook 服务 - ✅ 清理 venv 目录 --- ## 项目概述 **智队中枢**(原 PIT Router)是 PIT(Personal Intelligent Team)系统的核心组件,负责连接用户交互层和 Agent 层,实现消息路由、会话管理、Agent 调度等功能。 ### 核心目标 - 提供统一的 WebSocket 接入点 - 实现多 Agent 智能路由 - 管理会话生命周期 - 支持 Agent 负载均衡 - 保证消息可靠传输 - **🆕 提供内置聊天界面和机器人功能** --- ## 🆕 智队机器人功能 ### 功能概述 智队机器人是智队中枢内置的聊天机器人功能,用户可以通过智队中枢的聊天界面与绑定的 OpenClaw Agent 进行对话。 **类比 QQ Bot**: ``` QQ 用户 → QQ 客户端 → QQ Bot(Channel 插件)→ OpenClaw Agent 智队用户 → 智队中枢聊天界面 → 智队机器人 → 智队频道插件 → OpenClaw Agent ``` ### 架构设计 ``` ┌─────────────────────────────────────────────────────────────────────┐ │ 智队中枢 (Flask) │ │ ┌───────────────────────────────────────────────────────────────┐ │ │ │ 聊天界面 (Chat UI) │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ 会话列表 │ │ 聊天窗口 │ │ 机器人列表 │ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ └───────────────────────────────────────────────────────────────┘ │ │ ┌───────────────────────────────────────────────────────────────┐ │ │ │ 智队机器人管理 (Bot Manager) │ │ │ │ - 机器人注册 │ │ │ │ - 机器人绑定 Agent │ │ │ │ - 机器人状态监控 │ │ │ └───────────────────────────────────────────────────────────────┘ │ │ ┌───────────────────────────────────────────────────────────────┐ │ │ │ 现有核心功能 │ │ │ │ - WebSocket Server │ │ │ │ - Session Manager │ │ │ │ - Agent Scheduler │ │ │ │ - Message Router │ │ │ └───────────────────────────────────────────────────────────────┘ │ └──────────────────────────────┬──────────────────────────────────────┘ │ WebSocket + PIT Protocol ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ 智队频道插件 (PIT Channel) │ │ 连接到绑定的 OpenClaw Agent │ └──────────────────────────────┬──────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ OpenClaw Agent (小白等) │ └─────────────────────────────────────────────────────────────────────┘ ``` ### 消息流 ``` ┌──────────┐ 登录 ┌──────────────┐ │ 用户 │ ──────────→ │ 智队中枢 │ └──────────┘ └──────────────┘ │ │ │ 选择机器人 │ ↓ ↓ ┌──────────┐ 创建会话 ┌──────────────┐ │ 机器人列表│ ──────────→ │ Session │ │ (小白等) │ │ (bot_id) │ └──────────┘ └──────────────┘ │ │ │ 发送消息 │ ↓ ↓ ┌──────────┐ 路由消息 ┌──────────────┐ │ 聊天窗口 │ ──────────→ │ Message │ │ │ │ Router │ └──────────┘ └──────────────┘ │ │ WebSocket ↓ ┌──────────────┐ │ 智队频道插件 │ └──────────────┘ │ ↓ ┌──────────────┐ │ OpenClaw │ │ Agent (小白) │ └──────────────┘ ``` ### 新建智队机器人技术方案 #### 功能入口 **前端位置**:首页右上角「➕ 新建机器人」按钮 **触发条件**:用户已登录 #### 新建机器人流程 ``` ┌──────────────┐ │ 用户点击 │ │ "新建机器人" │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ 弹出创建表单 │ │ - 名称(必填)│ │ - 显示名称 │ │ - 头像选择 │ │ - 描述 │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ 前端验证 │ │ 名称不为空 │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ POST /api/bots│ │ 创建机器人 │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ 后端处理 │ │ - 生成 Token │ │ - 创建 Bot │ │ - 返回结果 │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ 前端更新列表 │ │ 显示新机器人 │ └──────────────┘ ``` #### 创建机器人 API **请求**: ```http POST /api/bots/ Authorization: Bearer Content-Type: application/json { "name": "xiaobai", "display_name": "小白", "avatar": "🐶", "description": "忠诚的AI助手小狗" } ``` **响应**: ```json { "bot": { "id": "uuid", "name": "xiaobai", "display_name": "小白", "avatar": "🐶", "description": "忠诚的AI助手小狗", "status": "offline", "agent_id": null, "capabilities": ["chat"], "config": { ... }, "created_at": "2026-03-15T03:00:00Z" }, "token": "bot_xxx..." // 只返回一次,用于 API 调用 } ``` #### 前端实现 **组件**:`frontend/src/views/HomeView.vue` **功能**: - 模态框表单 - 头像选择器(12 个预设头像) - 表单验证 - 创建成功后自动刷新列表 **Store 方法**: ```typescript // stores/chat.ts async function createBot(data: { name: string; display_name?: string; avatar?: string; description?: string; }) { const response = await botApi.create(data); const bot = response.data.bot; bots.value.push(bot); return bot; } ``` --- ### 机器人绑定 Agent 流程 #### 绑定流程图 ``` ┌──────────────────────────────────────────────────────────────────┐ │ 机器人绑定 Agent 流程 │ └──────────────────────────────────────────────────────────────────┘ ┌──────────────┐ │ 1. 创建机器人 │ │ (无 Agent) │ │ status: │ │ offline │ └──────┬───────┘ │ │ 用户选择 Agent ▼ ┌──────────────┐ │ 2. 绑定 Agent │ │ POST /api/bots/:id/bind │ { agent_id } │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ 3. 后端验证 │ │ - Agent 存在 │ │ - Agent 在线 │ │ - 权限检查 │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ 4. 更新 Bot │ │ agent_id = x │ │ status = │ │ agent.status│ └──────┬───────┘ │ ▼ ┌──────────────┐ │ 5. Bot 可用 │ │ 用户可以开始 │ │ 聊天会话 │ └──────────────┘ ``` #### 绑定 Agent API **请求**: ```http POST /api/bots/{bot_id}/bind Authorization: Bearer Content-Type: application/json { "agent_id": "agent-001" } ``` **响应**: ```json { "bot": { "id": "bot-uuid", "name": "xiaobai", "agent_id": "agent-001", "status": "online" }, "message": "Bot bound to agent xiaobai-agent" } ``` #### 解绑 Agent API **请求**: ```http POST /api/bots/{bot_id}/unbind Authorization: Bearer ``` **响应**: ```json { "bot": { "id": "bot-uuid", "agent_id": null, "status": "offline" }, "message": "Bot unbound from agent" } ``` #### 状态同步机制 **Agent 状态变化时**: ``` Agent 状态变化 → Gateway 心跳 → 更新 Agent.status ↓ 同步到绑定该 Agent 的所有 Bot ↓ 更新 Bot.status ``` **代码实现**: ```python # app/services/bot_service.py @staticmethod def sync_agent_status(bot: Bot) -> Bot: """同步 Agent 状态到 Bot""" if bot.agent_id: agent = Agent.query.get(bot.agent_id) if agent: bot.status = agent.status else: bot.status = 'offline' else: bot.status = 'offline' bot.last_active_at = datetime.utcnow() db.session.commit() return bot ``` --- ### 创建聊天会话流程 #### 前置条件检查 ``` 用户选择机器人 → 检查 Bot.agent_id │ ├── 有 Agent → 创建会话成功 │ └── 无 Agent → 提示"机器人未绑定 Agent" ``` #### 创建会话 API **请求**: ```http POST /api/chat/sessions Authorization: Bearer Content-Type: application/json { "bot_id": "bot-uuid", "title": "与小白的对话" } ``` **后端处理**: ```python # 1. 验证 Bot 存在 bot = BotService.get_bot_by_id(bot_id) # 2. 检查权限 if not BotService.check_permission(user, bot, 'use'): return error('Permission denied') # 3. 检查 Agent 绑定 if not bot.agent_id: return error('Bot has no agent bound') # 4. 获取 Agent agent = Agent.query.get(bot.agent_id) # 5. 创建会话 session = Session( user_id=user_id, bot_id=bot.id, primary_agent_id=agent.id, title=title, channel_type='pit-bot', status='active' ) ``` --- ### 完整使用流程 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 用户使用流程 │ └─────────────────────────────────────────────────────────────────┘ 1. 登录智队中枢 └── POST /api/auth/login → 获取 JWT Token 2. 查看机器人列表 └── GET /api/bots/ → 返回可用机器人 3. 【可选】新建机器人 └── POST /api/bots/ → 创建机器人(status: offline) 4. 【可选】绑定 Agent └── POST /api/bots/:id/bind → 绑定后 status 变为 online 5. 选择机器人开始聊天 └── POST /api/chat/sessions → 创建会话 6. 发送消息 └── POST /api/chat/sessions/:id/messages └── 或 WebSocket: chat.send.message 7. 接收 Agent 响应 └── WebSocket: chat.message 事件 8. 继续对话或关闭会话 └── DELETE /api/chat/sessions/:id → 关闭会话 ``` --- ### 与 QQ Bot 的对比 | 特性 | QQ Bot | 智队机器人 | |------|--------|-----------| | **用户入口** | QQ 客户端 | 智队中枢 Web/App | | **消息通道** | QQ 协议 | WebSocket | | **认证方式** | QQ 账号 | JWT Token | | **会话管理** | QQ 群/私聊 | Session 模型 | | **消息格式** | QQ 消息 | PIT 协议 | | **Agent 绑定** | Channel 插件配置 | Bot → Gateway → Agent | | **多机器人** | 多个 QQ Bot | 多个智队机器人 | | **优势** | 用户基数大、无需安装 | 完全自主、功能可控 | ### 优势分析 | 优势 | 说明 | |------|------| | 🎯 **完全自主** | 不依赖第三方平台,完全可控 | | 🔧 **功能可控** | 可以自定义所有功能,无平台限制 | | 🔗 **统一入口** | 用户、机器人、Agent 统一管理 | | 📊 **数据私有** | 所有数据存储在本地,隐私安全 | | 🚀 **易于扩展** | 可以轻松添加新功能、新机器人 | | 💰 **零成本** | 无需支付平台费用 | --- ## 技术栈 | 层级 | 技术 | 版本 | 说明 | |------|------|------|------| | 语言 | Python | 3.12 | 高性能异步支持 | | Web框架 | Flask | 3.0+ | 轻量级、灵活 | | WebSocket | Flask-SocketIO | 5.3+ | 实时双向通信 | | ORM | SQLAlchemy | 3.1+ | 数据库抽象层 | | 认证 | Flask-Login + JWT | - | 用户身份验证 | | 缓存 | Redis | 7+ | 会话缓存、消息队列 | | 数据库 | PostgreSQL | 15+ | 生产环境持久化 | | 部署 | Gunicorn + Nginx | - | 生产环境部署 | | **前端** | **Vue.js 3 + Vite** | **-** | **🆕 聊天界面(SPA 单页应用)** | --- ## 系统架构 ``` 用户交互层 (Clients) ↓ WebSocket / HTTP 智队中枢 (PIT Router) ├── 接入层 (Access Layer) │ ├── HTTP Server (Flask) │ ├── WebSocket (SocketIO) │ ├── Auth Middleware (JWT) │ └── Rate Limiter ├── 业务层 (Business Layer) │ ├── Session Manager │ ├── Message Router │ ├── Agent Scheduler (加权轮询) │ ├── Message Queue (ACK机制) │ └── 🆕 Bot Manager (机器人管理) └── 数据层 (Data Layer) ├── PostgreSQL (持久化) ├── Redis (缓存/消息队列) └── Config Store ↓ WebSocket + PIT Channel 协议 Agent 层 (OpenClaw Gateways) ``` --- ## 项目结构 ``` pit-router/ ├── app/ │ ├── __init__.py # Flask 应用工厂 │ ├── config.py # 配置管理 │ ├── extensions.py # Flask 扩展初始化 │ ├── models/ # 数据模型层 │ │ ├── __init__.py │ │ ├── user.py # 用户模型 │ │ ├── session.py # 会话模型 │ │ ├── agent.py # Agent 模型 │ │ ├── gateway.py # Gateway 模型 │ │ ├── message.py # 消息模型 │ │ ├── connection.py # 连接模型 │ │ └── 🆕 bot.py # 机器人模型 │ ├── routes/ # HTTP 路由层 │ │ ├── __init__.py │ │ ├── auth.py # 认证路由 │ │ ├── sessions.py # 会话路由 │ │ ├── agents.py # Agent 路由 │ │ ├── gateways.py # Gateway 路由 │ │ ├── messages.py # 消息路由 │ │ ├── stats.py # 统计接口 │ │ ├── 🆕 bots.py # 机器人管理 API │ │ └── 🆕 chat.py # 聊天 API │ ├── socketio/ # WebSocket 处理层 │ │ ├── __init__.py │ │ ├── handlers.py # Socket.IO 事件处理 │ │ ├── events.py # 事件定义 │ │ ├── auth.py # WebSocket 认证 │ │ └── 🆕 chat_handlers.py # 聊天事件处理 │ ├── services/ # 业务逻辑层 │ │ ├── __init__.py │ │ ├── session_service.py # 会话服务 │ │ ├── agent_service.py # Agent 服务 │ │ ├── message_service.py # 消息服务 │ │ ├── scheduler.py # Agent 调度器 │ │ ├── message_queue.py # 消息队列管理 │ │ └── 🆕 bot_service.py # 机器人服务 │ ├── utils/ # 工具函数 │ │ ├── __init__.py │ │ ├── validators.py # 输入验证 │ │ ├── security.py # 安全工具 │ │ └── helpers.py # 辅助函数 │ ├── templates/ # 🆕 前端模板 │ │ ├── base.html │ │ ├── auth/ │ │ │ └── login.html │ │ ├── components/ │ │ │ ├── navbar.html │ │ │ ├── sidebar.html │ │ │ └── toast.html │ │ ├── 🆕 chat/ # 聊天界面 │ │ │ ├── index.html # 聊天主页 │ │ │ ├── session.html # 会话详情 │ │ │ └── bots.html # 机器人列表 │ │ └── 🆕 components/ │ │ ├── chat_window.html │ │ └── message_bubble.html │ └── extensions.py # Flask 扩展初始化 ├── migrations/ # 数据库迁移 ├── tests/ # 测试 │ ├── __init__.py │ ├── test_auth.py │ ├── test_sessions.py │ ├── test_messages.py │ ├── test_websocket.py │ └── 🆕 test_bots.py # 机器人测试 ├── requirements.txt # Python 依赖 ├── requirements-dev.txt # 开发依赖 ├── config.yaml # 配置文件模板 ├── config.example.yaml # 配置示例 ├── docker-compose.yaml # Docker 编排 ├── Dockerfile # Docker 镜像 └── run.py # 启动入口 ``` --- ## 数据模型 ### 用户模型 (User) | 字段 | 类型 | 说明 | |------|------|------| | id | String(36) | 主键 UUID | | username | String(80) | 用户名,唯一索引 | | password_hash | String(256) | 密码哈希 (bcrypt) | | email | String(120) | 邮箱,唯一 | | nickname | String(80) | 昵称 | | role | String(20) | 角色:admin/user | | status | String(20) | 状态:active/disabled | | created_at | DateTime | 创建时间 | | last_login_at | DateTime | 最后登录时间 | ### 🆕 机器人模型 (Bot) > **设计理念**:Bot 是 Agent 的用户侧展示配置,一对一直接绑定 | 字段 | 类型 | 说明 | |------|------|------| | id | String(36) | 主键 UUID | | name | String(80) | 机器人名称(如"小白"),唯一索引 | | display_name | String(80) | 显示名称 | | avatar | String(256) | 头像 URL | | description | Text | 机器人描述 | | ~~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 | | **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) | 字段 | 类型 | 说明 | |------|------|------| | id | String(36) | 主键 UUID | | user_id | String(36) | 用户 ID,外键 | | **🆕 bot_id** | **String(36)** | **机器人 ID,外键** | | primary_agent_id | String(36) | 主 Agent ID | | participating_agent_ids | JSON | 参与 Agent ID 列表 | | user_socket_id | String(100) | 用户 WebSocket Socket ID | | title | String(200) | 会话标题 | | channel_type | String(20) | 渠道类型:web/desktop/mobile/pit-bot | | status | String(20) | 状态:active/paused/closed | | message_count | Integer | 消息计数 | | unread_count | Integer | 未读消息数 | | created_at | DateTime | 创建时间 | | updated_at | DateTime | 更新时间 | | last_active_at | DateTime | 最后活跃时间 | ### Agent 模型 | 字段 | 类型 | 说明 | |------|------|------| | id | String(36) | 主键 UUID | | name | String(80) | Agent 名称 | | display_name | String(80) | 显示名称 | | gateway_id | String(36) | Gateway ID,外键 | | socket_id | String(100) | WebSocket Socket ID | | model | String(80) | 使用的模型 | | capabilities | JSON | 能力列表 | | status | String(20) | 状态:online/offline/busy | | priority | Integer | 优先级 (1-10) | | weight | Integer | 权重 (用于调度) | | connection_limit | Integer | 最大连接数 | | current_sessions | Integer | 当前会话数 | | last_heartbeat | DateTime | 最后心跳时间 | | created_at | DateTime | 创建时间 | ### Gateway 模型 | 字段 | 类型 | 说明 | |------|------|------| | id | String(36) | 主键 UUID | | name | String(80) | Gateway 名称,唯一 | | url | String(256) | Gateway 回调地址 | | token_hash | String(256) | 认证 Token 哈希 | | status | String(20) | 状态:online/offline | | agent_count | Integer | Agent 数量 | | connection_limit | Integer | 最大连接数 | | heartbeat_interval | Integer | 心跳间隔 (秒) | | allowed_ips | JSON | 允许连接的 IP 白名单 | | last_heartbeat | DateTime | 最后心跳时间 | | created_at | DateTime | 创建时间 | ### 消息模型 (Message) | 字段 | 类型 | 说明 | |------|------|------| | id | String(36) | 主键 UUID | | session_id | String(36) | 会话 ID,外键 | | 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 | | reply_to | String(36) | 回复的消息 ID | | status | String(20) | 状态:sent/delivered/read/failed | | ack_status | String(20) | 确认状态:pending/acknowledged | | retry_count | Integer | 重试次数 | | 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 | | entity_id | String(36) | 关联实体 ID | | entity_type | String(20) | 实体类型:user/agent | | ip_address | String(45) | IP 地址 (支持 IPv6) | | user_agent | String(500) | 客户端信息 | | status | String(20) | 状态:connected/disconnected | | auth_token | String(500) | 认证 Token | | connected_at | DateTime | 连接时间 | | last_activity | DateTime | 最后活动时间 | | disconnected_at | DateTime | 断开时间 | > **说明**:Bot 不直接建立 WebSocket 连接,通过 Agent 连接。Connection 只追踪 user/agent/gateway 三种类型。 --- ## HTTP API 设计 ### 认证 API ``` POST /api/auth/register - 注册新用户 POST /api/auth/login - 用户登录,返回 JWT Token POST /api/auth/logout - 用户登出 POST /api/auth/refresh - 刷新 Token GET /api/auth/me - 获取当前用户信息 POST /api/auth/verify - 验证 Token 有效性 ``` ### 🆕 机器人管理 API ``` GET /api/bots - 获取机器人列表 POST /api/bots - 创建机器人 GET /api/bots/:id - 获取机器人详情 PUT /api/bots/:id - 更新机器人配置 DELETE /api/bots/:id - 删除机器人 POST /api/bots/:id/bind - 绑定 Agent POST /api/bots/:id/unbind - 解绑 Agent GET /api/bots/:id/status - 获取机器人状态 POST /api/bots/:id/heartbeat - 机器人心跳上报 ``` ### 🆕 聊天 API ``` GET /api/chat/sessions - 获取聊天会话列表 POST /api/chat/sessions - 创建聊天会话 GET /api/chat/sessions/:id - 获取会话详情 GET /api/chat/sessions/:id/messages - 获取消息历史 POST /api/chat/sessions/:id/messages - 发送消息 PUT /api/chat/sessions/:id/read - 标记消息已读 DELETE /api/chat/sessions/:id - 关闭会话 ``` ### 会话 API > **说明**:`/api/sessions` 为通用会话 API(兼容旧版本),聊天会话请使用 `/api/chat/sessions` ``` GET /api/sessions - 获取所有会话列表(含所有渠道类型) POST /api/sessions - 创建通用会话 GET /api/sessions/:id - 获取会话详情 PUT /api/sessions/:id/close - 关闭会话 (替代 DELETE) GET /api/sessions/:id/messages - 获取会话消息 GET /api/sessions/:id/participants - 获取会话参与者 POST /api/sessions/:id/transfer - 会话转接 ``` ### Agent API ``` GET /api/agents - 获取 Agent 列表 GET /api/agents/:id - 获取 Agent 详情 GET /api/agents/:id/status - 获取 Agent 实时状态 PUT /api/agents/:id/config - 更新 Agent 配置 POST /api/agents/:id/heartbeat - Agent 心跳上报 GET /api/agents/available - 获取可用 Agent 列表 ``` ### Gateway API ``` GET /api/gateways - 获取 Gateway 列表 POST /api/gateways - 注册 Gateway DELETE /api/gateways/:id - 注销 Gateway GET /api/gateways/:id/status - 获取 Gateway 状态 POST /api/gateways/:id/heartbeat - Gateway 心跳上报 PUT /api/gateways/:id/agents - 更新 Gateway 的 Agent 列表 ``` ### 消息 API ``` POST /api/messages - 发送消息 (HTTP 方式) GET /api/messages/:id - 获取单条消息 PUT /api/messages/:id/ack - 确认消息已送达 PUT /api/messages/:id/read - 标记消息已读 ``` ### 统计 API ``` GET /api/stats - 系统统计信息 GET /api/stats/sessions - 会话统计 GET /api/stats/messages - 消息统计 GET /api/stats/agents - Agent 统计 GET /api/stats/bots - 🆕 机器人统计 ``` --- ## WebSocket 协议 ### 连接流程 ``` 1. 客户端连接 WebSocket 2. 服务端发送 connect 事件要求认证 3. 客户端发送 auth 事件携带 JWT Token 4. 服务端验证 Token,发送 authenticated 或 error 5. 认证成功后,可以进行其他操作 ``` ### 认证事件 | 事件 | 方向 | 说明 | 参数 | |------|------|------|------| | `connect` | C→S | 连接请求 | - | | `auth` | C→S | 认证请求 | `{ token: string }` | | `authenticated` | S→C | 认证成功 | `{ user_id: string, socket_id: string }` | | `auth_error` | S→C | 认证失败 | `{ code: string, message: string }` | ### 心跳事件 | 事件 | 方向 | 说明 | 参数 | |------|------|------|------| | `ping` | C→S | 心跳请求 | `{ timestamp: number }` | | `pong` | S→C | 心跳响应 | `{ timestamp: number }` | | `heartbeat_timeout` | S→C | 心跳超时 | `{ socket_id: string }` | ### 🆕 聊天事件 > **事件命名规范**:C→S 发送用 `chat.send.*`,S→C 接收用 `chat.*` | 事件 | 方向 | 说明 | 参数 | |------|------|------|------| | `chat.send.create` | C→S | 创建聊天会话 | `{ bot_id, title? }` | | `chat.created` | S→C | 会话已创建 | `{ session_id, bot }` | | `chat.send.join` | C→S | 加入会话 | `{ session_id }` | | `chat.joined` | S→C | 已加入会话 | `{ session_id, bot, messages }` | | `chat.send.leave` | C→S | 离开会话 | `{ session_id }` | | `chat.left` | S→C | 已离开会话 | `{ session_id }` | | `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.send.read` | C→S | 消息已读 | `{ session_id, message_ids }` | | `chat.read` | S→C | 消息已读确认 | `{ session_id, message_ids }` | | `chat.closed` | S→C | 会话被关闭 | `{ session_id, reason }` | ### 会话事件 | 事件 | 方向 | 说明 | 参数 | |------|------|------|------| | `session.create` | C→S | 创建会话 | `{ title, user_id, agent_id?, priority? }` | | `session.created` | S→C | 会话已创建 | `{ session_id, agent_id }` | | `session.join` | C→S | 加入会话 | `{ session_id }` | | `session.joined` | S→C | 已加入会话 | `{ session_id, participants: [] }` | | `session.leave` | C→S | 离开会话 | `{ session_id }` | | `session.left` | S→C | 已离开会话 | `{ session_id, user_id }` | | `session.closed` | S→C | 会话被关闭 | `{ session_id, reason }` | | `session.assigned` | S→C | Agent 分配通知 | `{ session_id, agent_id }` | ### 消息事件 | 事件 | 方向 | 说明 | 参数 | |------|------|------|------| | `message.send` | C→S | 发送消息 | `{ session_id, content, type, reply_to? }` | | `message` | S→C | 收到消息 | `{ message_id, session_id, sender, content, timestamp }` | | `message.ack` | C→S | 消息确认 | `{ message_id, status: delivered/read }` | | `message.acked` | S→C | 确认已收到 | `{ message_id, status }` | | `message.stream` | S→C | 流式消息 | `{ session_id, chunk, is_end }` | | `message.read` | C→S | 消息已读 | `{ session_id, message_ids: [] }` | | `typing` | C→S | 正在输入 | `{ session_id, is_typing: boolean }` | ### 错误事件 | 事件 | 方向 | 说明 | 参数 | |------|------|------|------| | `error` | S→C | 通用错误 | `{ code, message, details? }` | | `session_error` | S→C | 会话错误 | `{ session_id, code, message }` | | `message_error` | S→C | 消息错误 | `{ message_id, code, message }` | | `🆕 chat_error` | S→C | 聊天错误 | `{ session_id?, code, message }` | ### 消息格式 (与 PIT Channel 兼容) ```json { "type": "request" | "response" | "event" | "ack", "id": "uuid-string", "method": "send.message" | "send.media" | "ping" | "auth", "params": { "to": "user-id", "content": "message content", "timestamp": 1234567890, "replyTo": "message-id" }, "replyTo": "original-message-id", "error": { "code": "ERROR_CODE", "message": "Error description" } } ``` --- ## Agent 调度策略 ### 调度算法 ```python class AgentScheduler: STRATEGIES = { "round_robin": RoundRobinStrategy, # 轮询 "weighted_round_robin": WeightedRoundRobinStrategy, # 加权轮询 "least_connections": LeastConnectionsStrategy, # 最少连接 "least_response_time": LeastResponseTimeStrategy, # 最快响应 "capability_match": CapabilityMatchStrategy, # 能力匹配 } ``` ### 调度配置 ```yaml scheduler: strategy: "weighted_round_robin" # 调度策略 retry_attempts: 3 # 分配失败重试次数 timeout: 30 # 分配超时 (秒) # 权重配置 weights: priority: 0.4 # 优先级权重 (40%) load: 0.3 # 负载权重 (30%) capability: 0.3 # 能力匹配权重 (30%) ``` --- ## 消息可靠性机制 ### ACK 确认流程 ``` 1. 客户端发送 message.send 2. 服务端存储消息,状态=pending 3. 服务端转发消息给 Agent 4. Agent 收到后发送 message.ack 5. 服务端更新消息状态=delivered 6. 用户阅读后发送 message.read 7. 服务端更新消息状态=read ``` ### 消息重试机制 | 场景 | 策略 | 最大重试 | |------|------|----------| | Agent 离线 | 存入队列,Agent 上线后推送 | 无限 | | 发送超时 | 指数退避重试 | 3 次 | | ACK 超时 | 重新发送 | 3 次 | ### 消息持久化 ```python # 消息存储策略 MESSAGE_RETENTION = { "active_sessions": "30_days", # 活跃会话保留 30 天 "closed_sessions": "7_days", # 关闭会话保留 7 天 "failed_messages": "3_days", # 失败消息保留 3 天 } ``` --- ## 安全设计 ### 认证机制 | 层级 | 机制 | 说明 | |------|------|------| | HTTP API | JWT Bearer Token | Authorization: Bearer | | WebSocket | JWT Query Param | ws://host/ws?token= | | Gateway | Token + IP 白名单 | 双重验证 | | 🆕 Chat UI | Session + JWT | 登录后访问 | | 🆕 Bot API | Bot Token | X-Bot-Token: | ### Token 策略 | Token 类型 | 有效期 | 用途 | |------------|--------|------| | 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 ``` ### 安全措施 | 措施 | 实现 | 说明 | |------|------|------| | HTTPS/WSS | Nginx 反向代理 | 强制 TLS 1.2+ | | CORS | Flask-CORS | 白名单配置 | | Rate Limit | Flask-Limiter | 100 req/min per IP | | Input Validation | Marshmallow/Pydantic | 严格参数校验 | | SQL Injection | SQLAlchemy ORM | 参数化查询 | | XSS | Jinja2 转义 | 自动转义输出 | | IP 白名单 | Middleware | Gateway 连接限制 | | 连接数限制 | Socket.IO | 单用户最大连接数 | | 🆕 Bot Token 验证 | Middleware | 验证 Bot API 请求 | --- ## 部署架构 ### Docker Compose ```yaml version: '3.8' services: pit-router: build: . ports: - "9000:9000" environment: - FLASK_ENV=production - SECRET_KEY=${SECRET_KEY} - JWT_SECRET_KEY=${JWT_SECRET_KEY} - DATABASE_URL=postgresql://user:pass@postgres:5432/pit - REDIS_URL=redis://redis:6379/0 volumes: - pit-data:/app/data - pit-logs:/app/logs depends_on: - postgres - redis restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s deploy: resources: limits: cpus: '2.0' memory: 2G reservations: cpus: '0.5' memory: 512M postgres: image: postgres:15-alpine environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_DB=pit_router volumes: - postgres-data:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d pit_router"] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine volumes: - redis-data:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./ssl:/etc/nginx/ssl:ro depends_on: - pit-router restart: unless-stopped volumes: pit-data: pit-logs: postgres-data: redis-data: ``` --- ## 开发进度 ### ✅ 已完成功能 #### 核心功能 (Phase 1-3) | 模块 | 功能 | 完成度 | 完成日期 | |------|------|--------|----------| | **数据模型** | User, Session, Agent, Gateway, Message, Connection | 100% | 2026-03-14 | | **HTTP API** | 认证、会话、Agent、Gateway、消息、统计 | 100% | 2026-03-14 | | **WebSocket** | 认证、心跳、会话、消息事件 | 100% | 2026-03-14 | | **调度器** | 5 种调度策略 | 100% | 2026-03-14 | | **消息队列** | ACK 机制、重试 | 100% | 2026-03-14 | | **业务服务** | 会话、消息、Agent 服务 | 100% | 2026-03-14 | | **工具函数** | 验证、安全、辅助 | 100% | 2026-03-14 | | **Docker** | Dockerfile + docker-compose | 100% | 2026-03-14 | | **Web UI** | 登录页、频道配置、会话管理 | 100% | 2026-03-15 | | **自动部署** | Webhook + 脚本 | 100% | 2026-03-15 | #### 智队机器人功能 (Phase 6) ✅ 完成 | 模块 | 功能 | 完成度 | 完成日期 | |------|------|--------|----------| | **Bot 模型** | 数据模型实现 (bot.py) | 100% | 2026-03-15 | | **机器人 API** | REST API 实现 (bots.py) | 100% | 2026-03-15 | | **聊天 API** | REST API 实现 (chat.py) | 100% | 2026-03-15 | | **聊天事件** | WebSocket 处理 (chat_handlers.py) | 100% | 2026-03-15 | | **机器人服务** | 业务逻辑 (bot_service.py) | 100% | 2026-03-15 | | **数据库迁移** | 表结构迁移 (add_bot_model.py) | 100% | 2026-03-15 | | **聊天界面** | Vue.js 3 前端组件 | 100% | 2026-03-15 | | **状态管理** | Pinia Store (chat.ts) | 100% | 2026-03-15 | ### ⏳ 待完成功能 #### 测试与运维 (Phase 4-5) | 模块 | 功能 | 预计时间 | 优先级 | |------|------|----------|--------| | **单元测试** | 补充测试用例 | 1 天 | 🟡 中 | | **集成测试** | 端到端测试 | 1 天 | 🟡 中 | | **性能测试** | 压力测试 | 0.5 天 | 🟢 低 | | **Nginx + SSL** | HTTPS 配置 | 0.5 天 | 🟢 低 | | **日志系统** | 结构化日志 | 0.5 天 | 🟢 低 | | **监控告警** | Prometheus + Grafana | 1 天 | 🟢 低 | **预计总工期**:4.5 天 ### 总体进度 | 阶段 | 状态 | 内容 | 完成度 | |------|------|------|--------| | **Phase 1** | ✅ 完成 | 核心功能(数据模型、HTTP API、WebSocket) | 100% | | **Phase 2** | ✅ 完成 | 服务层(调度器、消息队列、会话/消息/Agent 服务) | 100% | | **Phase 3** | ✅ 完成 | 工具层(验证器、安全工具、辅助函数) | 100% | | **Phase 4** | ⚠️ 部分 | 测试部署(单元测试 80%,集成/性能/部署未完成) | 80% | | **Phase 5** | ⏳ 待开始 | 运维工具(Nginx + SSL、日志、监控) | 0% | | **Phase 6** | ✅ 完成 | 智队机器人(Bot 模型、API、聊天界面) | 100% | **总进度**: 约 90% --- ## 与 PIT Channel 的对接 ### 协议兼容性 | PIT Channel 发送 | 智队中枢处理 | |------------------|----------------| | `type: "request"` | 路由到对应处理器 | | `method: "send.message"` | 转发给目标 Agent | | `method: "ping"` | 返回 `pong` | | `type: "ack"` | 更新消息状态 | ### 配置示例 ```json // openclaw.json { "plugins": { "entries": { "pit-bot": { "enabled": true, "config": { "routerUrl": "wss://智队中枢.example.com/ws", "authToken": "${PIT_ROUTER_TOKEN}", "heartbeatInterval": 30000, "heartbeatTimeout": 10000, "ackTimeout": 30000 } } } } } ``` --- ## 自动部署 > Gitea 仓库提交后自动更新 Docker 容器 ### 架构流程 ``` 开发者推送代码 → Gitea 触发 Webhook → 更新脚本执行 → 拉取代码 → 构建镜像 → 重启容器 → 健康检查 ``` ### 实施清单 - [x] 创建 `auto-update.sh` 脚本 - [x] 创建 `webhook-server.py` 服务 - [x] 配置 systemd 服务 - [x] 配置 Gitea Webhook - [x] 测试自动更新 --- ## 相关项目 - [PIT Channel 插件](http://localhost:3000/yunxiafei/PIT_Channel) - OpenClaw Channel 插件(智队中枢客户端) - [PIT Client](http://localhost:3000/yunxiafei/pit-client) - 用户交互层应用 --- ## 许可证 MIT License --- *创建时间: 2026-03-14 | 更新: 2026-03-15 | 作者: 小白 🐶*