Skip to content

Commit 761b033

Browse files
authored
feat: Web 管理 API (#1390)
* feat: add comprehensive web management API and authentication system - Implemented web server with Quart and Hypercorn - Added authentication middleware with JWT and bcrypt - Created RESTful APIs for managing: * IM adapters * LLM backends * Dispatch rules * Workflows * Blocks - Introduced first-time setup and password management - Enhanced configuration loading with backup mechanism - Added support for rule and workflow priority, enabling/disabling - Integrated web configuration into global config * feat: comprehensive web management system with plugin and system status APIs - Added new web API modules for system and plugin management - Implemented system status API with resource usage tracking - Created plugin management API with support for: * Plugin listing * Plugin details retrieval * Plugin update (with restrictions) - Enhanced web framework with modular API design - Added setup files for internal plugins - Introduced new web API tests for system, plugin, and workflow management - Improved authentication and authorization mechanisms - Updated configuration models to support new plugin and system features * fix(web auth): cannot import UTC from datetime in old Python * docs(web api): update content to match current implementation * feat(plugin): implement missing plugin management API - Added new plugin management routes with full lifecycle support - Implemented plugin installation, uninstallation, enabling, and disabling - Updated PluginLoader with async methods for plugin operations - Enhanced plugin info model with more metadata - Added plugin API documentation with detailed usage examples - Created unit tests for plugin management functionality - Integrated plugin configuration updates with config backup mechanism * tests: fix tests * ci: Remove pull_request triggers from Windows quickstart workflows - Simplify concurrency group definition to use only github.ref - Maintain workflow dispatch and push to browser-version-dev branch * tests(config): add config backup mechanism and save methods - Implemented `save_config_with_backup` method in ConfigLoader - Added tests for config saving with and without existing backup - Updated LLM and IM API routes to use config backup when modifying configurations - Enhanced config management with automatic file backup before modifications * feat(llm): restore previous missing parameters - Added ability tracking to LLMBackendRegistry - Introduced logging for backend adapter registration - Updated register method to include LLMAbility parameter - Improved plugin loader with internal plugin tracking
1 parent 3df8927 commit 761b033

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+6190
-296
lines changed

.github/workflows/quickstart-windows-dev-gocqhttp.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ name: Windows Quickstart Dev (go-cqhttp)
22

33
on:
44
workflow_dispatch:
5-
pull_request:
65
push:
76
branches:
87
- 'browser-version-dev'
98

109
concurrency:
11-
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
10+
group: ${{ github.workflow }}-${{ github.ref }}
1211
cancel-in-progress: true
1312

1413
jobs:

.github/workflows/quickstart-windows-dev-mirai.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ name: Windows Quickstart Dev (Mirai)
22

33
on:
44
workflow_dispatch:
5-
pull_request:
65
push:
76
branches:
87
- 'browser-version-dev'
98

109
concurrency:
11-
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
10+
group: ${{ github.workflow }}-${{ github.ref }}
1211
cancel-in-progress: true
1312

1413
jobs:

.github/workflows/run-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ jobs:
2828
2929
- name: Run tests
3030
run: |
31-
python -m pytest
31+
python -m pytest -v

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ Dockerfile.dev
1010
venv/
1111
.vscode/
1212
config.yaml
13+
config.yaml.bak
1314
logs/

config.yaml.example

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,36 @@
11
ims:
2-
enable:
3-
telegram: ['telegram-bot-1234']
4-
configs:
5-
telegram-bot-1234:
6-
token: 'abcd'
2+
- name: "telegram-bot-1234"
3+
enable: true
4+
adapter: "telegram"
5+
config:
6+
token: "abcd"
77

88
plugins:
9-
enable: []
9+
enable: []
10+
11+
web:
12+
host: "127.0.0.1"
13+
port: 8080
14+
secret_key: "please-change-this-to-a-secure-secret-key"
15+
16+
llms:
17+
api_backends:
18+
- name: "deepseek-official"
19+
adapter: "deepseek"
20+
enable: true
21+
config:
22+
api_key: "your-api-key"
23+
base_url: "https://api.deepseek.com/v1"
24+
models:
25+
- "deepseek-chat"
26+
- "deepseek-coder"
27+
28+
- name: "openai-gpt4"
29+
adapter: "openai"
30+
enable: true
31+
config:
32+
api_key: "your-openai-key"
33+
base_url: "https://api.openai.com/v1"
34+
models:
35+
- "gpt-4"
36+
- "gpt-4-turbo"

data/dispatch_rules/chat.yaml

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,55 @@
11
# 聊天相关的调度规则
22
# 每个规则包含:
3+
# - rule_id: 规则唯一标识符
4+
# - name: 规则名称
5+
# - description: 规则描述
36
# - type: 规则类型 (prefix/keyword/regex)
4-
# - workflow: 要执行的工作流 (格式: groupId:workflowId)
5-
# - 其他特定类型的参数
7+
# - workflow_id: 要执行的工作流 (格式: groupId:workflowId)
8+
# - priority: 优先级 (数字越大优先级越高)
9+
# - enabled: 是否启用
10+
# - metadata: 元数据
611

7-
# 前缀匹配规则示例
8-
- type: prefix
9-
workflow: chat:normal
10-
prefix: "/chat"
12+
# 普通聊天
13+
- rule_id: chat_normal
14+
name: "普通聊天"
1115
description: "普通聊天,使用默认参数"
16+
type: prefix
17+
workflow_id: chat:normal
18+
prefix: "/chat"
19+
priority: 5
20+
enabled: true
21+
metadata:
22+
category: chat
23+
permission: user
24+
temperature: 0.7
1225

13-
# 关键词匹配规则示例
14-
- type: keyword
15-
workflow: chat:creative
26+
# 创意聊天
27+
- rule_id: chat_creative
28+
name: "创意聊天"
29+
description: "创意聊天,使用更高的温度参数"
30+
type: keyword
31+
workflow_id: chat:creative
1632
keywords:
1733
- "创意"
1834
- "发散"
1935
- "brainstorm"
20-
description: "创意聊天,使用更高的温度参数"
36+
priority: 5
37+
enabled: true
38+
metadata:
39+
category: chat
40+
permission: user
41+
temperature: 0.9
2142

22-
# 正则匹配规则示例
23-
- type: regex
24-
workflow: chat:roleplay
43+
# 角色扮演
44+
- rule_id: chat_roleplay
45+
name: "角色扮演"
46+
description: "角色扮演聊天,自动提取角色设定"
47+
type: regex
48+
workflow_id: chat:roleplay
2549
pattern: "^扮演(.+?)[::]"
26-
description: "角色扮演聊天,自动提取角色设定"
50+
priority: 8
51+
enabled: true
52+
metadata:
53+
category: chat
54+
permission: user
55+
temperature: 0.8

data/dispatch_rules/system.yaml

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,66 @@
22
# 这些规则主要用于系统管理和控制
33

44
# 帮助命令
5-
- type: prefix
6-
workflow: system:help
7-
prefix: "/help"
5+
- rule_id: system_help
6+
name: "帮助命令"
87
description: "显示帮助信息"
8+
type: prefix
9+
workflow_id: system:help
10+
prefix: "/help"
11+
priority: 10
12+
enabled: true
13+
metadata:
14+
category: system
15+
permission: user
916

1017
# 系统状态
11-
- type: prefix
12-
workflow: system:status
13-
prefix: "/status"
18+
- rule_id: system_status
19+
name: "系统状态"
1420
description: "显示系统状态"
21+
type: prefix
22+
workflow_id: system:status
23+
prefix: "/status"
24+
priority: 10
25+
enabled: true
26+
metadata:
27+
category: system
28+
permission: user
1529

1630
# 管理员命令
17-
- type: regex
18-
workflow: system:admin
19-
pattern: "^/(ban|unban|kick|mute) \\S+"
31+
- rule_id: system_admin
32+
name: "管理员命令"
2033
description: "管理员命令,需要管理员权限"
34+
type: regex
35+
workflow_id: system:admin
36+
pattern: "^/(ban|unban|kick|mute) \\S+"
37+
priority: 20
38+
enabled: true
39+
metadata:
40+
category: system
41+
permission: admin
2142

2243
# 系统设置
23-
- type: prefix
24-
workflow: system:settings
25-
prefix: "/settings"
44+
- rule_id: system_settings
45+
name: "系统设置"
2646
description: "修改系统设置"
47+
type: prefix
48+
workflow_id: system:settings
49+
prefix: "/settings"
50+
priority: 10
51+
enabled: true
52+
metadata:
53+
category: system
54+
permission: admin
2755

2856
# 清空记忆
29-
- type: prefix
30-
workflow: system:clear_memory
57+
- rule_id: system_clear_memory
58+
name: "清空记忆"
59+
description: "清空当前对话的记忆"
60+
type: prefix
61+
workflow_id: system:clear_memory
3162
prefix: "/清空记忆"
32-
description: "清空当前对话的记忆"
63+
priority: 10
64+
enabled: true
65+
metadata:
66+
category: system
67+
permission: user
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
name: Test Workflow
2+
blocks:
3+
- type: test:message
4+
name: Message Node
5+
params: {}

framework/config/config_loader.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
import sys
2+
import warnings
13
from ruamel.yaml import YAML
24
from pydantic import BaseModel, ValidationError
35
from typing import Type
6+
import shutil
7+
import os
48

59
class ConfigLoader:
610
"""
@@ -34,4 +38,17 @@ def save_config(config_path: str, config_object: BaseModel):
3438
:param config_object: 配置对象。
3539
"""
3640
with open(config_path, "w", encoding="utf-8") as f:
37-
ConfigLoader.yaml.dump(config_object.dict(), f)
41+
ConfigLoader.yaml.dump(config_object.model_dump(), f)
42+
43+
@staticmethod
44+
def save_config_with_backup(config_path: str, config_object: BaseModel):
45+
"""
46+
将配置对象保存到 YAML 文件中,并在保存前创建备份。
47+
:param config_path: 配置文件路径。
48+
:param config_object: 配置对象。
49+
"""
50+
51+
if os.path.exists(config_path):
52+
backup_path = f"{config_path}.bak"
53+
shutil.copy2(config_path, backup_path)
54+
ConfigLoader.save_config(config_path, config_object)

framework/config/global_config.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,25 @@
22

33
from pydantic import BaseModel, Field
44

5+
56
class IMConfig(BaseModel):
6-
enable: Dict[str, List[str]] = dict()
7-
configs: Dict[str, Dict[str, Any]] = Field(description="IM 的凭证配置", default=dict())
7+
"""IM配置"""
8+
name: str = Field(default="", description="IM标识名称")
9+
enable: bool = Field(default=True, description="是否启用IM")
10+
adapter: str = Field(default="dummy", description="IM适配器类型")
11+
config: Dict[str, Any] = Field(default={}, description="IM的配置")
812

913
class LLMBackendConfig(BaseModel):
10-
enable: bool
11-
adapter: str
12-
configs: List[Dict]
13-
models: List[str]
14+
"""LLM后端配置"""
15+
name: str = Field(description="后端标识名称")
16+
adapter: str = Field(description="LLM适配器类型")
17+
config: Dict[str, Any] = Field(default={}, description="后端配置")
18+
enable: bool = Field(default=True, description="是否启用")
19+
models: List[str] = Field(default=[], description="支持的模型列表")
1420

1521
class LLMConfig(BaseModel):
16-
backends: Dict[str, LLMBackendConfig] = dict()
17-
22+
api_backends: List[LLMBackendConfig] = Field(default=[], description="LLM API后端列表")
23+
1824
class DefaultConfig(BaseModel):
1925
llm_model: str = Field(default="gemini-1.5-flash", description="默认使用的 LLM 模型名称")
2026

@@ -40,8 +46,20 @@ class MemoryConfig(BaseModel):
4046
max_entries: int = Field(default=100, description="每个作用域最大记忆条目数")
4147
default_scope: str = Field(default="member", description="默认作用域类型")
4248

49+
class WebConfig(BaseModel):
50+
host: str = Field(default="127.0.0.1", description="Web服务绑定的IP地址")
51+
port: int = Field(default=8080, description="Web服务端口号")
52+
secret_key: str = Field(default="", description="Web服务的密钥,用于JWT等加密")
53+
password_file: str = Field(default="./data/web/password.hash", description="密码哈希存储路径")
54+
55+
class PluginConfig(BaseModel):
56+
"""插件配置"""
57+
enable: List[str] = Field(default=[], description="启用的外部插件列表")
58+
4359
class GlobalConfig(BaseModel):
44-
ims: IMConfig = IMConfig()
60+
ims: List[IMConfig] = Field(default=[], description="IM配置列表")
4561
llms: LLMConfig = LLMConfig()
4662
defaults: DefaultConfig = DefaultConfig()
4763
memory: MemoryConfig = MemoryConfig()
64+
web: WebConfig = WebConfig()
65+
plugins: PluginConfig = PluginConfig()

0 commit comments

Comments
 (0)