Skip to content

Commit 1ce0e79

Browse files
committed
refactor: remove yaml mention dependency from trigger pipeline
1 parent 59c31ef commit 1ce0e79

File tree

5 files changed

+71
-85
lines changed

5 files changed

+71
-85
lines changed

.github/workflows/orchestrator.yml

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,15 @@ jobs:
103103
FOUND_AGENTS=$(python - <<'PY'
104104
import os
105105
import re
106+
import sys
106107
from pathlib import Path
107108
109+
src_path = Path.cwd() / "src"
110+
if src_path.exists():
111+
sys.path.insert(0, str(src_path))
112+
113+
from issuelab.utils.mentions import extract_controlled_mentions
114+
108115
comment = os.environ.get("COMMENT_BODY", "")
109116
agents_dir = Path("agents")
110117
@@ -137,26 +144,7 @@ jobs:
137144
system_agents.add(owner_match.group(1).strip().lower())
138145
139146
found: list[str] = []
140-
controlled_lines: list[str] = []
141-
in_list_section = False
142-
for raw_line in comment.splitlines():
143-
line = raw_line.strip()
144-
if "相关人员:" in line:
145-
controlled_lines.append(line.split("相关人员:", 1)[1])
146-
in_list_section = False
147-
continue
148-
if line.startswith("协作请求:"):
149-
in_list_section = True
150-
continue
151-
if in_list_section:
152-
if re.match(r"^\s*-\s+@", raw_line):
153-
controlled_lines.append(raw_line)
154-
continue
155-
if line and not line.startswith("-"):
156-
in_list_section = False
157-
158-
controlled_text = "\n".join(controlled_lines)
159-
for mention in re.findall(r"@([a-zA-Z0-9_-]+)", controlled_text):
147+
for mention in extract_controlled_mentions(comment):
160148
candidate = mention.lower()
161149
if candidate in system_agents and candidate not in found:
162150
found.append(candidate)

config/response_format.yml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,7 @@ limits:
2222
actions_max_chars: 160
2323
mentions_max_count: 5
2424

25-
rules:
26-
mentions_only_in_actions: true
27-
yaml_required: true
28-
2925
notes:
30-
- mentions is required when you want to notify others; it must be a list of GitHub usernames (without @).
31-
- do not use @mentions in the free-text body; use the mentions field instead.
26+
- mentions are parsed from controlled sections only.
27+
- "use `相关人员: @user1 @user2` or `协作请求:` bullet list for dispatch."
3228
- observer should include decision fields in YAML: analysis, should_trigger, reason, agent, comment.

src/issuelab/response_processor.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
clean_mentions_in_text,
2121
filter_mentions,
2222
)
23+
from issuelab.utils.mentions import extract_controlled_mentions
2324
from issuelab.utils.yaml_text import extract_yaml_block
2425

2526
logger = logging.getLogger(__name__)
@@ -56,8 +57,7 @@
5657
"mentions_max_count": 5,
5758
},
5859
"rules": {
59-
"mentions_only_in_actions": True,
60-
"yaml_required": True,
60+
# Reserved for future rule flags.
6161
},
6262
}
6363

@@ -456,7 +456,7 @@ def trigger_mentioned_agents(
456456
Returns:
457457
(results, allowed_mentions, filtered_mentions)
458458
"""
459-
mentions = extract_mentions_from_yaml(response)
459+
mentions = extract_controlled_mentions(response)
460460

461461
if not mentions:
462462
logger.info("[INFO] Response中没有@mentions")
@@ -554,7 +554,7 @@ def process_agent_response(
554554
response_text = normalized_response
555555

556556
# 提取所有 @mentions(基于原始回复,避免规范化后丢失)
557-
mentions = extract_mentions_from_yaml(raw_response_text)
557+
mentions = extract_controlled_mentions(raw_response_text)
558558

559559
# 清理主体内容(将所有 @username 替换为 "用户 username")
560560
clean_response = clean_mentions_in_text(response_text)

tests/test_github.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def fake_filter_mentions(mentions, policy=None, issue_number=None):
138138
monkeypatch.setattr("issuelab.tools.github.os.unlink", lambda _path: None)
139139
monkeypatch.setattr("issuelab.mention_policy.filter_mentions", fake_filter_mentions)
140140
monkeypatch.setattr(
141-
"issuelab.response_processor.extract_mentions_from_yaml",
141+
"issuelab.utils.mentions.extract_controlled_mentions",
142142
lambda _body: (_ for _ in ()).throw(AssertionError("should not parse body mentions")),
143143
)
144144

@@ -156,8 +156,7 @@ def fake_run(cmd, capture_output, text, env):
156156

157157
monkeypatch.setattr("issuelab.tools.github.subprocess.run", fake_run)
158158
monkeypatch.setattr("issuelab.tools.github.os.unlink", lambda _path: None)
159-
monkeypatch.setattr("issuelab.response_processor.extract_mentions_from_yaml", lambda _body: [])
160-
monkeypatch.setattr("issuelab.utils.mentions.extract_github_mentions", lambda _body: ["alice"])
159+
monkeypatch.setattr("issuelab.utils.mentions.extract_controlled_mentions", lambda _body: [])
161160
monkeypatch.setattr(
162161
"issuelab.mention_policy.filter_mentions", lambda mentions, policy=None, issue_number=None: (mentions, [])
163162
)

tests/test_response_processor.py

Lines changed: 55 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,14 @@ def test_trigger_single_mentioned_agent(self, mock_trigger):
8383

8484
mock_trigger.return_value = True
8585

86-
response = """```yaml
87-
summary: "Test"
88-
findings: []
89-
recommendations: []
90-
mentions:
91-
- moderator
92-
confidence: "high"
93-
```"""
86+
response = """[Agent: moderator]
87+
88+
## Summary
89+
Test
90+
91+
---
92+
相关人员: @moderator
93+
"""
9494
results, allowed, filtered = trigger_mentioned_agents(response, 1, "Title", "Body")
9595

9696
assert results == {"moderator": True}
@@ -107,15 +107,14 @@ def test_trigger_multiple_mentioned_agents(self, mock_trigger):
107107

108108
mock_trigger.return_value = True
109109

110-
response = """```yaml
111-
summary: "Test"
112-
findings: []
113-
recommendations: []
114-
mentions:
115-
- reviewer_a
116-
- reviewer_b
117-
confidence: "high"
118-
```"""
110+
response = """[Agent: moderator]
111+
112+
## Summary
113+
Test
114+
115+
---
116+
相关人员: @reviewer_a @reviewer_b
117+
"""
119118
results, allowed, filtered = trigger_mentioned_agents(response, 2, "Title", "Body")
120119

121120
assert results == {"reviewer_a": True, "reviewer_b": True}
@@ -128,15 +127,14 @@ def test_skip_system_accounts(self, mock_trigger):
128127
"""跳过系统账号"""
129128
from issuelab.response_processor import trigger_mentioned_agents
130129

131-
response = """```yaml
132-
summary: "Test"
133-
findings: []
134-
recommendations: []
135-
mentions:
136-
- github
137-
- github-actions
138-
confidence: "high"
139-
```"""
130+
response = """[Agent: moderator]
131+
132+
## Summary
133+
Test
134+
135+
---
136+
相关人员: @github @github-actions
137+
"""
140138
results, allowed, filtered = trigger_mentioned_agents(response, 1, "Title", "Body")
141139

142140
assert results == {}
@@ -151,15 +149,14 @@ def test_trigger_with_system_and_real_users(self, mock_trigger):
151149

152150
mock_trigger.return_value = True
153151

154-
response = """```yaml
155-
summary: "Test"
156-
findings: []
157-
recommendations: []
158-
mentions:
159-
- github-actions
160-
- reviewer_a
161-
confidence: "high"
162-
```"""
152+
response = """[Agent: moderator]
153+
154+
## Summary
155+
Test
156+
157+
---
158+
相关人员: @github-actions @reviewer_a
159+
"""
163160
results, allowed, filtered = trigger_mentioned_agents(response, 1, "Title", "Body")
164161

165162
assert results == {"reviewer_a": True}
@@ -187,14 +184,14 @@ def test_handle_trigger_failure(self, mock_trigger):
187184

188185
mock_trigger.return_value = False
189186

190-
response = """```yaml
191-
summary: "Test"
192-
findings: []
193-
recommendations: []
194-
mentions:
195-
- reviewer_a
196-
confidence: "high"
197-
```"""
187+
response = """[Agent: moderator]
188+
189+
## Summary
190+
Test
191+
192+
---
193+
相关人员: @reviewer_a
194+
"""
198195
results, allowed, filtered = trigger_mentioned_agents(response, 1, "Title", "Body")
199196

200197
assert results == {"reviewer_a": False}
@@ -218,10 +215,12 @@ def test_process_string_response(self, mock_trigger):
218215
summary: "Test"
219216
findings: []
220217
recommendations: []
221-
mentions:
222-
- reviewer_a
223218
confidence: "high"
224-
```""",
219+
```
220+
221+
---
222+
相关人员: @reviewer_a
223+
""",
225224
issue_number=1,
226225
issue_title="Title",
227226
issue_body="Body",
@@ -246,10 +245,12 @@ def test_process_dict_response(self, mock_trigger):
246245
summary: "Test"
247246
findings: []
248247
recommendations: []
249-
mentions:
250-
- reviewer_b
251248
confidence: "high"
252-
```""",
249+
```
250+
251+
---
252+
相关人员: @reviewer_b
253+
""",
253254
"cost_usd": 0.01,
254255
},
255256
issue_number=1,
@@ -270,10 +271,12 @@ def test_auto_dispatch_disabled(self, mock_trigger):
270271
summary: "Test"
271272
findings: []
272273
recommendations: []
273-
mentions:
274-
- reviewer_a
275274
confidence: "high"
276-
```""",
275+
```
276+
277+
---
278+
相关人员: @reviewer_a
279+
""",
277280
issue_number=1,
278281
auto_dispatch=False,
279282
)

0 commit comments

Comments
 (0)