Skip to content

Commit 9e87134

Browse files
committed
refactor: support combined dispatch rules
1 parent c8ad268 commit 9e87134

File tree

14 files changed

+484
-300
lines changed

14 files changed

+484
-300
lines changed

framework/llm/llm_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ def load_backend(self, backend_name: str):
5757
with self.container.scoped() as scoped_container:
5858
scoped_container.register(config_class, config_class(**backend.config))
5959
adapter = Inject(scoped_container).create(adapter_class)()
60+
self.backends[backend_name] = adapter
6061

6162
# 注册到每个支持的模型
6263
for model in backend.models:
6364
if model not in self.active_backends:
6465
self.active_backends[model] = []
6566
self.active_backends[model].append(adapter)
66-
self.backends[backend_name] = adapter
6767

6868
self.logger.info(f"Backend {backend_name} loaded successfully")
6969

framework/plugin_manager/plugin_loader.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ async def disable_plugin(self, plugin_name: str) -> bool:
294294
# 找到并停止插件实例
295295
if plugin_name in self.plugins:
296296
plugin = self.plugins[plugin_name]
297+
print(isinstance(plugin, Plugin))
297298
plugin.on_stop()
298299
del self.plugins[plugin_name]
299300

@@ -302,6 +303,7 @@ async def disable_plugin(self, plugin_name: str) -> bool:
302303
self.config.plugins.enable.remove(plugin_name)
303304

304305
plugin_info.is_enabled = False
306+
self.plugin_infos[plugin_name] = plugin_info
305307

306308
self.logger.info(f"Plugin {plugin_name} disabled")
307309
return True

framework/web/api/dispatch/README.md

Lines changed: 118 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,33 @@ GET/backend-api/api/dispatch/rules
2020
"rule_id": "chat_normal",
2121
"name": "普通聊天",
2222
"description": "普通聊天,使用默认参数",
23-
"pattern": "/chat",
24-
"priority": 5,
2523
"workflow_id": "chat:normal",
24+
"priority": 5,
2625
"enabled": true,
26+
"rule_groups": [
27+
{
28+
"operator": "or",
29+
"rules": [
30+
{
31+
"type": "prefix",
32+
"config": {
33+
"prefix": "/chat"
34+
}
35+
},
36+
{
37+
"type": "keyword",
38+
"config": {
39+
"keywords": ["聊天", "对话"]
40+
}
41+
}
42+
]
43+
}
44+
],
2745
"metadata": {
2846
"category": "chat",
2947
"permission": "user",
3048
"temperature": 0.7
31-
},
32-
"is_active": true
49+
}
3350
}
3451
]
3552
}
@@ -57,11 +74,28 @@ POST/backend-api/api/dispatch/rules
5774
"rule_id": "chat_creative",
5875
"name": "创意聊天",
5976
"description": "创意聊天,使用更高的温度参数",
60-
"type": "keyword",
6177
"workflow_id": "chat:creative",
62-
"keywords": ["创意", "发散", "brainstorm"],
6378
"priority": 5,
6479
"enabled": true,
80+
"rule_groups": [
81+
{
82+
"operator": "and",
83+
"rules": [
84+
{
85+
"type": "prefix",
86+
"config": {
87+
"prefix": "/creative"
88+
}
89+
},
90+
{
91+
"type": "keyword",
92+
"config": {
93+
"keywords": ["创意", "发散"]
94+
}
95+
}
96+
]
97+
}
98+
],
6599
"metadata": {
66100
"category": "chat",
67101
"permission": "user",
@@ -104,32 +138,82 @@ POST/backend-api/api/dispatch/rules/{rule_id}/disable
104138

105139
## 数据模型
106140

107-
### DispatchRuleConfig
141+
### SimpleRule
142+
- `type`: 规则类型 (prefix/keyword/regex)
143+
- `config`: 规则类型特定的配置
144+
145+
### RuleGroup
146+
- `operator`: 组合操作符 (and/or)
147+
- `rules`: 规则列表
148+
149+
### CombinedDispatchRule
108150
- `rule_id`: 规则唯一标识符
109151
- `name`: 规则名称
110152
- `description`: 规则描述
111-
- `type`: 规则类型 (prefix/keyword/regex)
112153
- `workflow_id`: 关联的工作流ID
113-
- `pattern`/`prefix`/`keywords`: 匹配规则(根据类型不同)
114154
- `priority`: 优先级(数字越大优先级越高)
115155
- `enabled`: 是否启用
156+
- `rule_groups`: 规则组列表(组之间是 AND 关系)
116157
- `metadata`: 元数据(可选)
117158

118-
### DispatchRuleStatus
119-
继承自 DispatchRuleConfig,额外包含:
120-
- `is_active`: 规则是否处于活动状态
121-
122159
## 规则类型
123160

124161
### 前缀匹配 (prefix)
125162
根据消息前缀进行匹配,例如 "/help"。
126163

164+
配置参数:
165+
- `prefix`: 要匹配的前缀
166+
127167
### 关键词匹配 (keyword)
128168
检查消息中是否包含指定关键词。
129169

170+
配置参数:
171+
- `keywords`: 关键词列表
172+
130173
### 正则匹配 (regex)
131174
使用正则表达式进行匹配,提供最灵活的匹配方式。
132175

176+
配置参数:
177+
- `pattern`: 正则表达式模式
178+
179+
## 组合规则说明
180+
181+
新版本的调度规则系统支持复杂的条件组合:
182+
183+
1. 每个规则可以包含多个规则组(RuleGroup)
184+
2. 规则组之间是 AND 关系,即所有规则组都满足时才会触发
185+
3. 每个规则组内可以包含多个简单规则(SimpleRule)
186+
4. 规则组内的规则可以选择 AND 或 OR 关系
187+
5. 每个简单规则都有自己的类型和配置
188+
189+
例如,可以创建如下规则:
190+
191+
```json
192+
{
193+
"rule_groups": [
194+
{
195+
"operator": "or",
196+
"rules": [
197+
{ "type": "prefix", "config": { "prefix": "/creative" } },
198+
{ "type": "keyword", "config": { "keywords": ["创意", "发散"] } }
199+
]
200+
},
201+
{
202+
"operator": "and",
203+
"rules": [
204+
{ "type": "regex", "config": { "pattern": ".*问题.*" } },
205+
{ "type": "keyword", "config": { "keywords": ["帮我", "请问"] } }
206+
]
207+
}
208+
]
209+
}
210+
```
211+
212+
这个规则表示:
213+
- 当消息以 "/creative" 开头 或 包含 "创意"/"发散" 关键词
214+
- 且 消息包含 "问题" 且 包含 "帮我"/"请问" 中的任一关键词
215+
时触发。
216+
133217
## 相关代码
134218

135219
- [调度规则定义](../../../workflow/core/dispatch/rule.py)
@@ -155,19 +239,36 @@ POST/backend-api/api/dispatch/rules/{rule_id}/disable
155239

156240
## 使用示例
157241

158-
### 创建新规则
242+
### 创建组合规则
159243
```python
160244
import requests
161245

162246
rule_data = {
163247
"rule_id": "chat_creative",
164248
"name": "创意聊天",
165249
"description": "创意聊天模式",
166-
"type": "keyword",
167250
"workflow_id": "chat:creative",
168-
"keywords": ["创意", "发散"],
169251
"priority": 5,
170-
"enabled": True
252+
"enabled": True,
253+
"rule_groups": [
254+
{
255+
"operator": "or",
256+
"rules": [
257+
{
258+
"type": "prefix",
259+
"config": {
260+
"prefix": "/creative"
261+
}
262+
},
263+
{
264+
"type": "keyword",
265+
"config": {
266+
"keywords": ["创意", "发散"]
267+
}
268+
}
269+
]
270+
}
271+
]
171272
}
172273

173274
response = requests.post(
Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,20 @@
1-
from typing import Dict, Any, List, Optional
2-
from pydantic import BaseModel
3-
4-
class DispatchRuleConfig(BaseModel):
5-
"""调度规则配置"""
6-
rule_id: str
7-
name: str
8-
description: str = ""
1+
from typing import Dict, Any, List, Optional, Union, Literal
2+
from pydantic import BaseModel, Field
3+
from framework.workflow.core.dispatch.rule import CombinedDispatchRule
4+
class SimpleRule(BaseModel):
5+
"""简单调度规则(单一条件)"""
96
type: str
10-
priority: int = 5
11-
workflow_id: str
12-
enabled: bool = True
13-
config: Dict[str, Any] = {} # 用于存储规则类型特定的配置
14-
metadata: Dict[str, Any] = {} # 用于存储其他元数据
7+
config: Dict[str, Any] = {} # 规则类型特定的配置
158

16-
class DispatchRuleStatus(BaseModel):
17-
"""调度规则状态"""
18-
rule_id: str
19-
name: str
20-
description: str
21-
type: str # 规则类型
22-
priority: int
23-
workflow_id: str
24-
enabled: bool
25-
config: Dict[str, Any] # 规则类型特定的配置
26-
metadata: Dict[str, Any]
27-
is_active: bool
9+
class RuleGroup(BaseModel):
10+
"""规则组"""
11+
operator: Literal["and", "or"] = "or"
12+
rules: List[SimpleRule]
2813

2914
class DispatchRuleList(BaseModel):
3015
"""调度规则列表"""
31-
rules: List[DispatchRuleStatus]
16+
rules: List[CombinedDispatchRule]
3217

3318
class DispatchRuleResponse(BaseModel):
3419
"""调度规则响应"""
35-
rule: DispatchRuleStatus
20+
rule: CombinedDispatchRule

0 commit comments

Comments
 (0)