Skip to content

Commit cbc31f4

Browse files
committed
feat: Enhance chat type handling and rule formatting in dispatch system
1 parent ab993ca commit cbc31f4

File tree

4 files changed

+57
-49
lines changed

4 files changed

+57
-49
lines changed

framework/im/sender.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,20 @@ class ChatType(Enum):
77
C2C = "c2c"
88
GROUP = "group"
99

10+
@classmethod
11+
def from_str(cls, value: str) -> "ChatType":
12+
if value == "c2c" or value == "私聊":
13+
return cls.C2C
14+
elif value == "group" or value == "群聊":
15+
return cls.GROUP
16+
raise ValueError(f"Invalid chat type: {value}")
17+
18+
def to_str(self) -> str:
19+
if self == self.C2C:
20+
return "私聊"
21+
elif self == self.GROUP:
22+
return "群聊"
23+
raise ValueError(f"Invalid chat type: {self}")
1024

1125
@dataclass
1226
class ChatSender:

framework/web/api/dispatch/models.py

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,10 @@
1-
from typing import Any, Dict, List, Literal
1+
from typing import List
22

33
from pydantic import BaseModel
44

55
from framework.workflow.core.dispatch import CombinedDispatchRule
66

77

8-
class SimpleRule(BaseModel):
9-
"""简单调度规则(单一条件)"""
10-
11-
type: str
12-
config: Dict[str, Any] = {} # 规则类型特定的配置
13-
14-
15-
class RuleGroup(BaseModel):
16-
"""规则组"""
17-
18-
operator: Literal["and", "or"] = "or"
19-
rules: List[SimpleRule]
20-
21-
228
class DispatchRuleList(BaseModel):
239
"""调度规则列表"""
2410

framework/workflow/core/dispatch/rules/sender_rules.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Optional
1+
from typing import Literal, Optional
22

33
from pydantic import Field
44

@@ -88,13 +88,13 @@ def from_config(
8888
workflow_registry: WorkflowRegistry,
8989
workflow_id: str,
9090
) -> "ChatSenderMismatchRule":
91-
return cls(config.sender_id, config.sender_group, workflow_registry, workflow_id)
92-
93-
91+
return cls(config.sender_id, config.sender_group, workflow_registry, workflow_id)
92+
93+
9494
class ChatTypeMatchRuleConfig(RuleConfig):
9595
"""聊天类型规则配置"""
96-
chat_type: ChatType = Field(title="聊天类型", description="聊天类型")
97-
96+
chat_type: Literal["私聊", "群聊"] = Field(title="聊天类型", description="聊天类型")
97+
9898
class ChatTypeMatchRule(DispatchRule):
9999
"""根据聊天类型匹配的规则"""
100100
config_class = ChatTypeMatchRuleConfig
@@ -106,11 +106,12 @@ def __init__(self, chat_type: ChatType, workflow_registry: WorkflowRegistry, wor
106106

107107
def match(self, message: IMMessage) -> bool:
108108
return message.sender.chat_type == self.chat_type
109-
109+
110110
def get_config(self) -> ChatTypeMatchRuleConfig:
111111
return ChatTypeMatchRuleConfig(chat_type=self.chat_type)
112112

113113
@classmethod
114114
def from_config(cls, config: ChatTypeMatchRuleConfig, workflow_registry: WorkflowRegistry, workflow_id: str) -> "ChatTypeMatchRule":
115-
return cls(config.chat_type, workflow_registry, workflow_id)
116-
115+
chat_type = ChatType.from_str(config.chat_type)
116+
return cls(chat_type, workflow_registry, workflow_id)
117+

framework/workflow/implementations/blocks/system/help.py

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,40 @@
44
from framework.im.sender import ChatSender
55
from framework.ioc.container import DependencyContainer
66
from framework.workflow.core.block import Block, Output
7+
from framework.workflow.core.dispatch.models.dispatch_rules import RuleGroup
78
from framework.workflow.core.dispatch.registry import DispatchRuleRegistry
89

910

11+
def _format_rule_condition(rule_type: str, config: Dict[str, Any]) -> str:
12+
"""格式化单个规则的条件描述"""
13+
if rule_type == "prefix":
14+
return f"输入以 {config['prefix']} 开头"
15+
elif rule_type == "keyword":
16+
keywords = config.get("keywords", [])
17+
return f"输入包含 {' 或 '.join(keywords)}"
18+
elif rule_type == "regex":
19+
return f"输入匹配正则 {config['pattern']}"
20+
elif rule_type == "fallback":
21+
return "任意输入"
22+
elif rule_type == "bot_mention":
23+
return f"@我"
24+
elif rule_type == "chat_type":
25+
return f"使用 {config['chat_type']} 聊天类型"
26+
return f"使用 {rule_type} 规则"
27+
28+
29+
def _format_rule_group(group: RuleGroup) -> str:
30+
"""格式化规则组的条件描述"""
31+
rule_conditions = []
32+
for rule in group.rules:
33+
rule_conditions.append(
34+
_format_rule_condition(rule.type, rule.config)
35+
)
36+
37+
operator = " 且 " if group.operator == "and" else " 或 "
38+
return operator.join(rule_conditions)
39+
40+
1041
class GenerateHelp(Block):
1142
"""生成帮助信息 block"""
1243

@@ -15,30 +46,6 @@ class GenerateHelp(Block):
1546
outputs = {"response": Output("response", "帮助信息", IMMessage, "帮助信息")}
1647
container: DependencyContainer
1748

18-
def _format_rule_condition(self, rule_type: str, config: Dict[str, Any]) -> str:
19-
"""格式化单个规则的条件描述"""
20-
if rule_type == "prefix":
21-
return f"输入以 {config['prefix']} 开头"
22-
elif rule_type == "keyword":
23-
keywords = config.get("keywords", [])
24-
return f"输入包含 {' 或 '.join(keywords)}"
25-
elif rule_type == "regex":
26-
return f"输入匹配正则 {config['pattern']}"
27-
elif rule_type == "fallback":
28-
return "任意输入"
29-
return f"使用 {rule_type} 规则"
30-
31-
def _format_rule_group(self, group: Dict[str, Any]) -> str:
32-
"""格式化规则组的条件描述"""
33-
rule_conditions = []
34-
for rule in group["rules"]:
35-
rule_conditions.append(
36-
self._format_rule_condition(rule["type"], rule["config"])
37-
)
38-
39-
operator = " 且 " if group["operator"] == "and" else " 或 "
40-
return operator.join(rule_conditions)
41-
4249
def execute(self) -> Dict[str, Any]:
4350
# 从容器获取调度规则注册表
4451
registry = self.container.resolve(DispatchRuleRegistry)
@@ -55,7 +62,7 @@ def execute(self) -> Dict[str, Any]:
5562
# 格式化规则组条件
5663
conditions = []
5764
for group in rule.rule_groups:
58-
conditions.append(self._format_rule_group(group.model_dump()))
65+
conditions.append(_format_rule_group(group))
5966

6067
# 组合所有条件(规则组之间是 AND 关系)
6168
rule_format = " 并且 ".join(f"({condition})" for condition in conditions)

0 commit comments

Comments
 (0)