Files
pit-router/README.md
小白 cb2bb5ec35 docs: 完善智队机器人技术方案 (v0.9.1)
- 完善新建智队机器人技术方案
- 完善机器人绑定 Agent 流程
- 添加创建聊天会话流程说明
- 添加完整使用流程说明
- 添加前端新建机器人功能说明
2026-03-15 11:44:12 +08:00

1371 lines
46 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.
# 智队中枢
> PIT 网关路由应用 - Personal Intelligent Team Gateway Router Service
**中文名**:智队中枢
**英文名**PIT Router
**当前版本**v0.9.1
---
## 更新日志
### 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是 PITPersonal Intelligent Team系统的核心组件负责连接用户交互层和 Agent 层实现消息路由、会话管理、Agent 调度等功能。
### 核心目标
- 提供统一的 WebSocket 接入点
- 实现多 Agent 智能路由
- 管理会话生命周期
- 支持 Agent 负载均衡
- 保证消息可靠传输
- **🆕 提供内置聊天界面和机器人功能**
---
## 🆕 智队机器人功能
### 功能概述
智队机器人是智队中枢内置的聊天机器人功能,用户可以通过智队中枢的聊天界面与绑定的 OpenClaw Agent 进行对话。
**类比 QQ Bot**
```
QQ 用户 → QQ 客户端 → QQ BotChannel 插件)→ 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 <jwt_token>
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 <jwt_token>
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 <jwt_token>
```
**响应**
```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 <jwt_token>
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 <token> |
| WebSocket | JWT Query Param | ws://host/ws?token=<jwt> |
| Gateway | Token + IP 白名单 | 双重验证 |
| 🆕 Chat UI | Session + JWT | 登录后访问 |
| 🆕 Bot API | Bot Token | X-Bot-Token: <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 | 作者: 小白 🐶*