fix(intent): accept 编写/编制/起草 and keep intake markers on intake
The chat fallback only treated 生成/做/跑/出 as task verbs, and the shorter RDev alias 用户需求 stole 初始用户需求表. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1177,6 +1177,15 @@ func matchQueryProgress(input string) *CandidateIntent {
|
||||
return nil
|
||||
}
|
||||
|
||||
func hasTaskWriteVerb(input string) bool {
|
||||
for _, verb := range []string{"生成", "做", "跑", "出", "编写", "编制", "起草"} {
|
||||
if strings.Contains(input, verb) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func matchTriggerTask(input string) *CandidateIntent {
|
||||
type phrase struct {
|
||||
text string
|
||||
@@ -1210,24 +1219,39 @@ func matchTriggerTask(input string) *CandidateIntent {
|
||||
return phrases[i].text < phrases[j].text
|
||||
})
|
||||
|
||||
if !(strings.Contains(input, "生成") || strings.Contains(input, "做") || strings.Contains(input, "跑") || strings.Contains(input, "出")) {
|
||||
if !hasTaskWriteVerb(input) {
|
||||
return nil
|
||||
}
|
||||
// 「初始 / 首轮 / 摸底」是 V0.1 摸底,不能被更短的研发别名「用户需求」截走。
|
||||
if hasIntakeSemanticMarker(input) && strings.Contains(input, "需求") {
|
||||
return triggerTaskCandidate("需求表", "intake")
|
||||
}
|
||||
for _, item := range phrases {
|
||||
if strings.Contains(input, item.text) {
|
||||
return &CandidateIntent{
|
||||
Intent: IntentTriggerTask,
|
||||
Confidence: 0.86,
|
||||
FilledSlots: map[string]string{
|
||||
SlotTargetTask: item.key,
|
||||
},
|
||||
Reasoning: fmt.Sprintf("用户要求显式生成交付任务: %s (%s)", item.text, item.key),
|
||||
}
|
||||
return triggerTaskCandidate(item.text, item.key)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func hasIntakeSemanticMarker(input string) bool {
|
||||
return strings.Contains(input, "首轮") ||
|
||||
strings.Contains(input, "初始") ||
|
||||
strings.Contains(input, "需求摸底") ||
|
||||
strings.Contains(input, "摸底")
|
||||
}
|
||||
|
||||
func triggerTaskCandidate(phrase, taskKey string) *CandidateIntent {
|
||||
return &CandidateIntent{
|
||||
Intent: IntentTriggerTask,
|
||||
Confidence: 0.86,
|
||||
FilledSlots: map[string]string{
|
||||
SlotTargetTask: taskKey,
|
||||
},
|
||||
Reasoning: fmt.Sprintf("用户要求显式生成交付任务: %s (%s)", phrase, taskKey),
|
||||
}
|
||||
}
|
||||
|
||||
func isGreetingOrHelp(input string) bool {
|
||||
greetings := []string{"你好", "您好", "早上好", "下午好", "晚上好", "早啊", "在吗", "hi", "hello", "你是谁"}
|
||||
for _, g := range greetings {
|
||||
|
||||
@@ -126,6 +126,14 @@ func TestIntentRecognition_RDevProposalAndLongerTitleWins(t *testing.T) {
|
||||
if intake.TopIntent.FilledSlots[intent.SlotTargetTask] != "intake" {
|
||||
t.Fatalf("用户需求收集表 must stay intake, got %s", intake.TopIntent.FilledSlots[intent.SlotTargetTask])
|
||||
}
|
||||
|
||||
written, err := rec.Recognize(context.Background(), "编写初始用户需求表", ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if written.TopIntent.Intent != intent.IntentTriggerTask || written.TopIntent.FilledSlots[intent.SlotTargetTask] != "intake" {
|
||||
t.Fatalf("编写初始用户需求表 want TRIGGER_TASK/intake, got %s %s", written.TopIntent.Intent, written.TopIntent.FilledSlots[intent.SlotTargetTask])
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntentRecognition_CasualChat(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user