diff --git a/data/.config.example.toml b/data/config.example.toml
similarity index 67%
rename from data/.config.example.toml
rename to data/config.example.toml
index 2af0066e95f9517fd2ee1dbde4edad2b48a18bd1..a17ccd411bbd7fb0e7dfdedb0e48113f36c216ba 100644
--- a/data/.config.example.toml
+++ b/data/config.example.toml
@@ -3,19 +3,6 @@ mode = 'local'
cookie = 'domain'
data_dir = '/var/lib/euler_copilot'
-[login]
-provider = 'authhub'
-admin_user = [
- "admin"
-]
-
-[login.settings]
-host = 'http://127.0.0.1:8000'
-host_inner = 'http://127.0.0.1:11120'
-login_api = 'http://127.0.0.1:8080/api/auth/login'
-app_id = ''
-app_secret = ''
-
[rag]
rag_service = 'http://127.0.0.1:9988'
diff --git a/design/services/activity.md b/design/services/activity.md
index 431881995946a757b6c7449e8ec1fed144a6875a..ab26e0298f7a76d9ce1aa00d24d57163c0d8c44c 100644
--- a/design/services/activity.md
+++ b/design/services/activity.md
@@ -38,12 +38,27 @@ Activity 模块是 openEuler Intelligence 框架中的用户活动控制系统
#### 静态方法
-- `is_active(user_id)`: 先按用户滑动窗口统计,再按全局并发统计,达到任一阈值即返回 `True`
-- `set_active(user_id)`: 在未超过全局并发上限时登记一个活动任务,内部使用 SQLAlchemy `merge` 以 userId 为键写入最新时间戳
-- `remove_active(user_id)`: 移除用户活动状态
+- `can_active(user_id)`: 判断系统是否可以接受新任务
+ - 先检查用户滑动窗口限流:统计该用户在 `SLIDE_WINDOW_TIME` 秒内的请求数,若 >= `SLIDE_WINDOW_QUESTION_COUNT` 则返回 `False`
+ - 再检查全局并发限制:统计当前所有活跃任务数,若 >= `MAX_CONCURRENT_TASKS` 则返回 `False`
+ - 两项检查都通过则返回 `True`
+
+- `set_active(user_id)`: 登记一个活动任务
+ - 先检查当前活跃任务数,若 >= `MAX_CONCURRENT_TASKS` 则抛出 `ActivityError`
+ - 使用 `session.add()` 添加新的 `SessionActivity` 记录,包含 userId 和当前时间戳
+ - 每次调用都会新增一条记录(不是更新已有记录)
+
+- `is_active(user_id)`: 判断用户是否有活动记录
+ - 统计该用户的活动记录数量,返回 count > 0
+
+- `remove_active(user_id)`: 移除用户的所有活动记录
+ - 删除该用户的所有 SessionActivity 记录
> **注意**
-> 当前实现仅在 `is_active` 阶段执行滑动窗口校验;`set_active` 只进行一次全局并发计数后写入数据库。
+>
+> - `can_active` 负责限流检查(用户级 + 系统级)
+> - `set_active` 每次调用都新增记录,可能导致同一用户有多条活动记录
+> - `remove_active` 会删除用户的所有活动记录
## 时序图
@@ -56,40 +71,40 @@ sequenceDiagram
Note over Client, DB: 用户请求处理流程
Client->>Router: 发起请求
- Router->>Activity: is_active(user_id)
+ Router->>Activity: can_active(user_id)
Note over Activity, DB: 滑动窗口限流检查
- Activity->>DB: SELECT COUNT(*) FROM framework_session_activity
WHERE userId=? AND timestamp >= ?
+ Activity->>DB: SELECT COUNT(*) FROM framework_session_activity
WHERE userId=? AND timestamp BETWEEN (now-15s) AND now
DB-->>Activity: 返回用户窗口内请求数
- Activity->>Activity: 检查是否超过SLIDE_WINDOW_QUESTION_COUNT
-
+ Activity->>Activity: 检查是否 >= SLIDE_WINDOW_QUESTION_COUNT
+
alt 用户请求数超限
- Activity-->>Router: 返回True (限流)
+ Activity-->>Router: 返回False (限流)
Router-->>Client: 返回429错误
else 用户请求数正常
Note over Activity, DB: 全局并发检查
Activity->>DB: SELECT COUNT(*) FROM framework_session_activity
DB-->>Activity: 返回当前活跃任务数
- Activity->>Activity: 检查是否超过MAX_CONCURRENT_TASKS
-
+ Activity->>Activity: 检查是否 >= MAX_CONCURRENT_TASKS
+
alt 全局并发超限
- Activity-->>Router: 返回True (限流)
+ Activity-->>Router: 返回False (限流)
Router-->>Client: 返回429错误
else 系统可处理
- Activity-->>Router: 返回False (允许)
+ Activity-->>Router: 返回True (允许)
Router->>Activity: set_active(user_id)
Note over Activity, DB: 设置活动状态
Activity->>DB: SELECT COUNT(*) FROM framework_session_activity
DB-->>Activity: 返回当前活跃任务数
- Activity->>Activity: 检查是否超过MAX_CONCURRENT_TASKS
-
+ Activity->>Activity: 检查是否 >= MAX_CONCURRENT_TASKS
+
alt 并发超限
Activity-->>Router: 抛出ActivityError
Router-->>Client: 返回503错误
else 系统仍可处理
- Activity->>DB: MERGE INTO framework_session_activity
(userId, timestamp)
- DB-->>Activity: 插入或更新成功
+ Activity->>DB: INSERT INTO framework_session_activity
(userId, timestamp)
+ DB-->>Activity: 插入成功
Activity-->>Router: 设置成功
Router-->>Client: 处理请求
@@ -144,35 +159,37 @@ erDiagram
```mermaid
flowchart TD
- A[用户请求] --> B[Activity.is_active检查]
-
+ A[用户请求] --> B[Activity.can_active检查]
+
B --> C{滑动窗口限流检查}
- C -->|超过限制| D[返回限流状态]
+ C -->|超过限制| D[返回False]
C -->|未超过| E{全局并发检查}
-
+
E -->|超过限制| D
- E -->|未超过| F[Activity.set_active]
-
- F --> G{并发检查}
- G -->|检查失败| H[抛出ActivityError]
- G -->|检查通过| I[插入/更新活动记录]
-
- I --> J[处理用户请求]
- J --> K[请求完成]
- K --> L[Activity.remove_active]
- L --> M[删除活动记录]
- M --> N[释放资源]
+ E -->|未超过| F[返回True]
+
+ F --> G[Activity.set_active]
- D --> O[返回429错误]
- H --> P[返回503错误]
- N --> Q[请求处理完成]
+ G --> H{并发检查}
+ H -->|检查失败| I[抛出ActivityError]
+ H -->|检查通过| J[插入活动记录]
+
+ J --> K[处理用户请求]
+ K --> L[请求完成]
+ L --> M[Activity.remove_active]
+ M --> N[删除活动记录]
+ N --> O[释放资源]
+
+ D --> P[返回429错误]
+ I --> Q[返回503错误]
+ O --> R[请求处理完成]
style A fill:#e1f5fe
- style Q fill:#c8e6c9
- style O fill:#ffcdd2
+ style R fill:#c8e6c9
style P fill:#ffcdd2
+ style Q fill:#ffcdd2
style D fill:#fff3e0
- style H fill:#fff3e0
+ style I fill:#fff3e0
```
## 限流机制详解
@@ -195,9 +212,9 @@ flowchart LR
subgraph "登记活跃任务"
K[set_active调用] --> L[统计当前活跃任务数]
- L --> M{超过上限?}
- M -->|是| O[抛出异常]
- M -->|否| N[插入/更新记录]
+ L --> M{>= 上限?}
+ M -->|是| O[抛出ActivityError]
+ M -->|否| N[插入新记录]
end
E --> F
@@ -306,14 +323,15 @@ SLIDE_WINDOW_QUESTION_COUNT = 5 # 窗口内最大请求数
## 使用示例
```python
-# 检查是否被限流
-if await Activity.is_active(user_id):
- raise HTTPException(status_code=429, detail="请求过于频繁")
+# 检查系统是否可以接受新任务
+if not await Activity.can_active(user_id):
+ raise HTTPException(status_code=429, detail="请求过于频繁或系统繁忙")
# 设置活动状态
try:
await Activity.set_active(user_id)
# 处理业务逻辑
+ ...
finally:
# 清理活动状态
await Activity.remove_active(user_id)
diff --git a/design/services/session.md b/design/services/session.md
deleted file mode 100644
index 717fa0a84d1d8a7f322b9ee7f84ac4b82eb81916..0000000000000000000000000000000000000000
--- a/design/services/session.md
+++ /dev/null
@@ -1,267 +0,0 @@
-# Session模块设计文档
-
-## 概述
-
-Session 模块是 openEuler Intelligence 框架中的会话管理系统,负责创建、删除和验证用户会话。该模块实现了基于数据库的会话存储机制,支持会话创建、会话删除、用户信息获取以及黑名单用户检查功能,确保系统安全性和用户身份验证的可靠性。
-
-## 核心功能
-
-- **会话创建**: 为用户创建新的浏览器会话
-- **会话删除**: 删除指定的会话记录
-- **用户信息获取**: 从会话中获取用户标识
-- **黑名单检查**: 验证用户是否在黑名单中
-- **会话查询**: 根据用户标识查询会话
-
-## 数据模型
-
-### Session实体
-
-- **表名**: `framework_session`
-- **主键**: `id` (String(255), 默认为随机生成的16字节十六进制字符串)
-- **字段**:
- - `userId`: 用户标识 (String(50), 外键关联framework_user.id)
- - `ip`: IP地址 (String(255), 可为空)
- - `pluginId`: 插件ID (String(255), 可为空)
- - `token`: Token信息 (String(2000), 可为空)
- - `validUntil`: 有效期 (DateTime, 时区感知)
- - `sessionType`: 会话类型 (Enum(SessionType))
-
-### SessionType枚举
-
-- `ACCESS_TOKEN`: 访问令牌
-- `REFRESH_TOKEN`: 刷新令牌
-- `PLUGIN_TOKEN`: 插件令牌
-- `CODE`: 代码类型会话
-
-## 配置常量
-
-- `SESSION_TTL`: 会话有效期,单位为分钟 (默认: 30 \* 24 \* 60,即30天)
-
-## 服务层
-
-### SessionManager类
-
-#### 静态方法
-
-- `create_session(user_id, ip)`: 创建浏览器会话
-- `delete_session(session_id)`: 删除浏览器会话
-- `get_user(session_id)`: 从会话中获取用户
-- `get_session_by_user(user_id)`: 根据用户标识获取会话
-
-## 时序图
-
-```mermaid
-sequenceDiagram
- participant Client as 客户端
- participant SessionMgr as SessionManager
- participant BlacklistMgr as UserBlacklistManager
- participant DB as 数据库
-
- Note over Client, DB: 创建会话流程
- Client->>SessionMgr: create_session(user_id, ip)
- SessionMgr->>SessionMgr: 验证参数
- alt 参数无效
- SessionMgr-->>Client: 抛出ValueError
- else 参数有效
- SessionMgr->>DB: 创建Session对象
- Note over SessionMgr, DB: 设置会话有效期为当前时间+SESSION_TTL
- SessionMgr->>DB: session.merge(data)
- SessionMgr->>DB: session.commit()
- DB-->>SessionMgr: 提交成功
- SessionMgr-->>Client: 返回session_id
- end
-
- Note over Client, DB: 获取用户流程
- Client->>SessionMgr: get_user(session_id)
- SessionMgr->>DB: 查询Session.userId
- DB-->>SessionMgr: 返回user_id或None
-
- alt 用户不存在
- SessionMgr-->>Client: 返回None
- else 用户存在
- SessionMgr->>BlacklistMgr: check_blacklisted_users(user_id)
- BlacklistMgr->>DB: 查询用户黑名单状态
- DB-->>BlacklistMgr: 返回黑名单状态
- BlacklistMgr-->>SessionMgr: 返回是否在黑名单中
-
- alt 用户在黑名单中
- SessionMgr->>SessionMgr: 记录错误日志
- SessionMgr->>SessionMgr: delete_session(session_id)
- SessionMgr->>DB: 删除会话
- DB-->>SessionMgr: 删除成功
- SessionMgr-->>Client: 返回None
- else 用户不在黑名单中
- SessionMgr-->>Client: 返回user_id
- end
- end
-
- Note over Client, DB: 删除会话流程
- Client->>SessionMgr: delete_session(session_id)
- alt session_id为空
- SessionMgr-->>Client: 直接返回
- else session_id有效
- SessionMgr->>DB: 查询Session
- DB-->>SessionMgr: 返回session_data或None
- alt 会话存在
- SessionMgr->>DB: session.delete(session_data)
- DB-->>SessionMgr: 删除成功
- end
- SessionMgr->>DB: session.commit()
- DB-->>SessionMgr: 提交成功
- SessionMgr-->>Client: 返回None
- end
-
- Note over Client, DB: 根据用户查询会话流程
- Client->>SessionMgr: get_session_by_user(user_id)
- SessionMgr->>DB: 查询Session.id
- DB-->>SessionMgr: 返回session_id或None
- SessionMgr-->>Client: 返回session_id或None
-```
-
-## ER图
-
-```mermaid
-erDiagram
- User ||--o{ Session : "用户拥有会话"
- User ||--o{ SessionActivity : "用户产生活动"
-
- User {
- string userId PK "用户标识"
- boolean isWhitelisted "是否白名单"
- integer credit "信用分"
- string personalToken "个人令牌"
- }
-
- Session {
- string id PK "会话ID"
- string userId FK "用户标识"
- string ip "IP地址"
- string pluginId "插件ID"
- string token "Token信息"
- datetime validUntil "有效期"
- enum sessionType "会话类型"
- }
-
- SessionActivity {
- BigInteger id PK
- string userId FK "用户标识"
- datetime timestamp "活动时间戳"
- }
-```
-
-## 流程图
-
-```mermaid
-flowchart TD
- subgraph "创建会话流程"
- A1[客户端请求创建会话] --> B1{验证参数}
- B1 -->|参数无效| C1[抛出ValueError]
- B1 -->|参数有效| D1[创建Session对象]
- D1 --> E1[设置会话有效期]
- E1 --> F1[保存到数据库]
- F1 --> G1[返回session_id]
- end
-
- subgraph "获取用户流程"
- A2[客户端请求获取用户] --> B2[查询会话]
- B2 --> C2{会话存在?}
- C2 -->|不存在| D2[返回None]
- C2 -->|存在| E2[查询黑名单]
- E2 --> F2{用户在黑名单?}
- F2 -->|是| G2[记录错误日志]
- G2 --> H2[删除会话]
- H2 --> I2[返回None]
- F2 -->|否| J2[返回user_id]
- end
-
- subgraph "删除会话流程"
- A3[客户端请求删除会话] --> B3{session_id为空?}
- B3 -->|是| C3[直接返回]
- B3 -->|否| D3[查询会话]
- D3 --> E3{会话存在?}
- E3 -->|是| F3[删除会话]
- E3 -->|否| G3[提交事务]
- F3 --> G3
- G3 --> H3[返回None]
- end
-
- subgraph "根据用户查询会话流程"
- A4[客户端请求查询会话] --> B4[查询数据库]
- B4 --> C4[返回session_id或None]
- end
-
- style A1 fill:#e1f5fe
- style G1 fill:#c8e6c9
- style A2 fill:#e1f5fe
- style D2 fill:#fff3e0
- style I2 fill:#fff3e0
- style J2 fill:#c8e6c9
- style A3 fill:#e1f5fe
- style H3 fill:#c8e6c9
- style A4 fill:#e1f5fe
- style C4 fill:#c8e6c9
-```
-
-## 安全考虑
-
-1. **会话有效期**: 会话设置了30天的默认有效期,防止长期未使用的会话被滥用
-2. **IP地址验证**: 创建会话时验证IP地址,防止无效请求
-3. **用户黑名单检查**: 获取用户信息时检查用户是否在黑名单中,增强系统安全性
-4. **会话自动清理**: 对于黑名单用户的会话自动删除,防止未授权访问
-5. **参数验证**: 对输入参数进行严格验证,防止无效数据
-
-## 性能优化
-
-1. **数据库索引**: 对userId和id字段建立索引,提高查询效率
-2. **异步操作**: 所有数据库操作使用异步方式,提高并发性能
-3. **连接池管理**: 使用数据库连接池管理连接,减少连接开销
-4. **最小化查询**: get_user方法只查询必要的userId字段,而非整个Session对象
-
-## 与其他模块的交互
-
-1. **UserBlacklistManager**: 用于检查用户是否在黑名单中
-2. **PostgreSQL数据库**: 用于存储和检索会话数据
-3. **认证系统**: 提供会话创建和验证功能
-4. **路由层**: 使用会话管理功能进行用户身份验证
-
-## 异常处理
-
-### ValueError异常
-
-- **触发条件**: 当创建会话时提供的IP地址或用户标识为空
-- **错误信息**: "用户IP错误!" 或 "用户名错误!"
-- **处理方式**: 向上层抛出异常,由调用方处理
-
-## 配置说明
-
-```toml
-# 会话配置
-SESSION_TTL = 43200 # 会话有效期(分钟),默认30天
-```
-
-## 使用示例
-
-```python
-# 创建会话
-session_id = await SessionManager.create_session(user_id="user123", ip="192.168.1.1")
-
-# 获取用户信息
-user_id = await SessionManager.get_user(session_id)
-if user_id:
- # 用户有效,处理业务逻辑
-else:
- # 用户无效或在黑名单中
-
-# 删除会话
-await SessionManager.delete_session(session_id)
-
-# 根据用户查询会话
-session_id = await SessionManager.get_session_by_user(user_id)
-```
-
-## 扩展性
-
-1. **会话类型扩展**: SessionType枚举可以扩展支持更多会话类型
-2. **会话属性扩展**: Session模型可以添加更多字段以支持额外功能
-3. **验证机制扩展**: 可以增加更多的验证逻辑,如设备指纹验证
-4. **分布式会话**: 可以扩展支持分布式环境下的会话管理
diff --git "a/documents/user-guide/\345\274\200\345\217\221\346\214\207\345\215\227/EulerCopilot\346\217\222\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.md" "b/documents/user-guide/\345\274\200\345\217\221\346\214\207\345\215\227/EulerCopilot\346\217\222\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.md"
index 4698438ce0ce3fe940f87e7219a303c162e6aac0..ae75486cc6fef44e792513972bc2ba95f6a56435 100644
--- "a/documents/user-guide/\345\274\200\345\217\221\346\214\207\345\215\227/EulerCopilot\346\217\222\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.md"
+++ "b/documents/user-guide/\345\274\200\345\217\221\346\214\207\345\215\227/EulerCopilot\346\217\222\344\273\266\345\274\200\345\217\221\346\214\207\345\215\227.md"
@@ -48,17 +48,16 @@ test_plugin # 插件文件夹,该文件夹的名称即为插件ID;
### 字段说明
- ID:插件的ID,用于在EulerCopilot内唯一标识该插件。
- - 要求:小写英文字母与符号的组合
+ - 要求:小写英文字母与符号的组合
- name:插件的名字,用于提供给前端进行展示。
- - 要求:任意字符串,长度小于15个字。
+ - 要求:任意字符串,长度小于15个字。
- description:插件的描述,用户提供给大模型进行自动插件选择。
- - 要求:精准、完整地描述插件的功能、输入与输出。
+ - 要求:精准、完整地描述插件的功能、输入与输出。
- predefined_question:插件的预定义问题,用于在用户无输入时自动填充该问题。(建设中)
- automatic_flow:是否将每个API自动拆分为Flow
- auth:插件的鉴权信息
- - type:插件的鉴权类型。可以为“param”、“header”和“cookie”和“oidc”四种类型。
- - args:实际的鉴权字段(键值对)。
-
+ - type:插件的鉴权类型。可以为“param”、“header”和“cookie”三种类型。
+ - args:实际的鉴权字段(键值对)。
## openapi.yaml
@@ -133,12 +132,14 @@ curl -X POST http://example.com:port/suffix/url \
> 由于YAML有诸多层级,因此此处使用如下方式描述YAML中特定的字段:
> 有YAML文件如下
+>
> ```yaml
> a:
> b1:
> c: test1
> b2: ["test2"]
>```
+>
> 则:`a.b1.c`指值为`test1`的字段;`a.b2[]`指值为`["test2"]`的数组。
#### 全局字段
@@ -170,7 +171,6 @@ curl -X POST http://example.com:port/suffix/url \
JSON Schema的全部规范内容可参照[JSON Schema官方文档](https://json-schema.org/understanding-json-schema/reference)。
-
##### Schema格式样例
有如下的Schema YAML样例:
@@ -257,7 +257,7 @@ YAML格式的Schema编写,可以参考[OpenAPI文档中的DataType章节](http
- 正确工作流逻辑示例:
-```
+```text
工作流功能:查询某一主机的所有CVE列表,并生成特定格式输出
步骤1:调用API接口,获取某一主机的全部CVE ID
步骤2:根据获得的CVE ID和给定的输出格式,生成自然语言结果
@@ -265,7 +265,7 @@ YAML格式的Schema编写,可以参考[OpenAPI文档中的DataType章节](http
- 错误工作流逻辑示例:多个低耦合任务
-```
+```text
工作流功能:根据用户输入,到特定的数据库中查询数据。再根据用户输入,查询输入对应的任务metadata。结合数据库中的数据和任务metadata,生成任务报告。
```
@@ -273,13 +273,12 @@ YAML格式的Schema编写,可以参考[OpenAPI文档中的DataType章节](http
- 错误工作流逻辑示例:工作流耦合
-```
+```text
工作流功能:需要先调用flow_1获取测试数据才能使用该工作流。该工作流的作用是将flow_1返回值中的data字段提取出来并存储在数据库的test_data表中,...
```
工作流间的先后关系应通过用户问题和自然语言上下文进行实现;不同工作流之间暂时无法进行结构化数据的传递。
-
### 基本格式
一个`flow.yaml`的基本格式如下: