|
1 | 1 | package models
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "regexp" |
4 | 5 | "strings"
|
5 | 6 | "time"
|
6 | 7 |
|
@@ -156,8 +157,33 @@ const (
|
156 | 157 | AIModelGemini = "gemini"
|
157 | 158 | )
|
158 | 159 |
|
159 |
| -// HasCommand 检查上下文是否包含命令 |
| 160 | +// MentionConfig 提及配置接口 |
| 161 | +type MentionConfig interface { |
| 162 | + GetTriggers() []string |
| 163 | + GetDefaultTrigger() string |
| 164 | +} |
| 165 | + |
| 166 | +// ConfigMentionAdapter 从内部config包适配到models包 |
| 167 | +type ConfigMentionAdapter struct { |
| 168 | + Triggers []string |
| 169 | + DefaultTrigger string |
| 170 | +} |
| 171 | + |
| 172 | +func (c *ConfigMentionAdapter) GetTriggers() []string { |
| 173 | + return c.Triggers |
| 174 | +} |
| 175 | + |
| 176 | +func (c *ConfigMentionAdapter) GetDefaultTrigger() string { |
| 177 | + return c.DefaultTrigger |
| 178 | +} |
| 179 | + |
| 180 | +// HasCommand 检查上下文是否包含命令(使用默认mention配置) |
160 | 181 | func HasCommand(ctx GitHubContext) (*CommandInfo, bool) {
|
| 182 | + return HasCommandWithConfig(ctx, nil) |
| 183 | +} |
| 184 | + |
| 185 | +// HasCommandWithConfig 检查上下文是否包含命令(支持自定义mention配置) |
| 186 | +func HasCommandWithConfig(ctx GitHubContext, mentionConfig MentionConfig) (*CommandInfo, bool) { |
161 | 187 | var content string
|
162 | 188 |
|
163 | 189 | switch c := ctx.(type) {
|
@@ -186,7 +212,11 @@ func HasCommand(ctx GitHubContext) (*CommandInfo, bool) {
|
186 | 212 | return cmdInfo, true
|
187 | 213 | }
|
188 | 214 |
|
189 |
| - // Then try to parse as @claude mention |
| 215 | + // Then try to parse as mention with config |
| 216 | + if mentionConfig != nil { |
| 217 | + return parseMentionWithConfig(content, mentionConfig) |
| 218 | + } |
| 219 | + // Fallback to default mention parsing |
190 | 220 | return parseMention(content)
|
191 | 221 | }
|
192 | 222 |
|
@@ -231,43 +261,58 @@ func parseCommand(content string) (*CommandInfo, bool) {
|
231 | 261 | }, true
|
232 | 262 | }
|
233 | 263 |
|
234 |
| -// parseMention 解析@qiniu-ci提及 |
| 264 | +// parseMention 解析@qiniu-ci提及(默认触发词,向后兼容) |
235 | 265 | func parseMention(content string) (*CommandInfo, bool) {
|
236 |
| - content = strings.TrimSpace(content) |
| 266 | + return parseMentionWithTrigger(content, CommandClaude) |
| 267 | +} |
237 | 268 |
|
238 |
| - // 检查是否包含@qiniu-ci |
239 |
| - if !strings.Contains(content, CommandClaude) { |
240 |
| - return nil, false |
| 269 | +// parseMentionWithConfig 使用配置解析mention |
| 270 | +func parseMentionWithConfig(content string, config MentionConfig) (*CommandInfo, bool) { |
| 271 | + triggers := config.GetTriggers() |
| 272 | + if len(triggers) == 0 { |
| 273 | + triggers = []string{config.GetDefaultTrigger()} |
241 | 274 | }
|
242 | 275 |
|
243 |
| - // 找到@qiniu-ci的位置 |
244 |
| - mentionIndex := strings.Index(content, CommandClaude) |
245 |
| - if mentionIndex == -1 { |
| 276 | + // 尝试所有配置的触发词 |
| 277 | + for _, trigger := range triggers { |
| 278 | + if trigger == "" { |
| 279 | + continue |
| 280 | + } |
| 281 | + if cmdInfo, found := parseMentionWithTrigger(content, trigger); found { |
| 282 | + return cmdInfo, true |
| 283 | + } |
| 284 | + } |
| 285 | + |
| 286 | + return nil, false |
| 287 | +} |
| 288 | + |
| 289 | +// parseMentionWithTrigger 使用指定触发词解析mention,传递完整评论内容 |
| 290 | +func parseMentionWithTrigger(content string, trigger string) (*CommandInfo, bool) { |
| 291 | + content = strings.TrimSpace(content) |
| 292 | + pattern := `(^|\s)` + regexp.QuoteMeta(trigger) + `([\s.,!?;:]|$)` |
| 293 | + re := regexp.MustCompile(pattern) |
| 294 | + |
| 295 | + match := re.FindStringSubmatch(content) |
| 296 | + if match == nil { |
246 | 297 | return nil, false
|
247 | 298 | }
|
248 | 299 |
|
249 |
| - // 提取@qiniu-ci之后的内容作为参数 |
250 |
| - afterMention := strings.TrimSpace(content[mentionIndex+len(CommandClaude):]) |
| 300 | + // NOTE(CarlJin): mention 模式传递暂时完整评论内容 |
| 301 | + fullContent := content |
251 | 302 |
|
252 |
| - // 解析AI模型和参数(类似于parseCommand的逻辑) |
253 | 303 | var aiModel string
|
254 |
| - var args string |
255 | 304 |
|
256 |
| - if strings.HasPrefix(afterMention, "-claude") { |
| 305 | + // 查找模型指定标志 |
| 306 | + if strings.Contains(fullContent, "-claude") { |
257 | 307 | aiModel = AIModelClaude
|
258 |
| - args = strings.TrimSpace(strings.TrimPrefix(afterMention, "-claude")) |
259 |
| - } else if strings.HasPrefix(afterMention, "-gemini") { |
| 308 | + } else if strings.Contains(fullContent, "-gemini") { |
260 | 309 | aiModel = AIModelGemini
|
261 |
| - args = strings.TrimSpace(strings.TrimPrefix(afterMention, "-gemini")) |
262 |
| - } else { |
263 |
| - aiModel = "" |
264 |
| - args = afterMention |
265 | 310 | }
|
266 | 311 |
|
267 | 312 | return &CommandInfo{
|
268 |
| - Command: CommandClaude, |
| 313 | + Command: CommandClaude, // 总是使用CommandClaude作为mention的标识 |
269 | 314 | AIModel: aiModel,
|
270 |
| - Args: args, |
| 315 | + Args: fullContent, // 传递完整评论内容 |
271 | 316 | RawText: content,
|
272 | 317 | }, true
|
273 | 318 | }
|
|
0 commit comments