diff --git a/internal/coordinator/stage_aware_confirm_e2e_test.go b/internal/coordinator/stage_aware_confirm_e2e_test.go new file mode 100644 index 00000000..199e4917 --- /dev/null +++ b/internal/coordinator/stage_aware_confirm_e2e_test.go @@ -0,0 +1,59 @@ +package coordinator_test + +import ( + "context" + "strings" + "testing" + + "chat-agent-system/internal/coordinator" + "chat-agent-system/internal/intent" + "chat-agent-system/internal/maturity" +) + +func TestProcessIntent_WeakRequirementsConfirmsIntake(t *testing.T) { + eng := coordinator.NewCoordinatorEngine(nil) + userCtx := &coordinator.UserProjectContext{ + User: coordinator.UserInfo{ID: "1", Name: "u"}, + Project: coordinator.ProjectInfo{ + ID: "9", + Name: "商务对接演示", + CurrentStage: maturity.StageV01_Triage, + ActiveWorkflowKey: "main", + }, + } + rec := intent.NewRecognizer() + recRes, err := rec.Recognize(context.Background(), "整理一下需求", userCtx.ToSnapshot()) + if err != nil { + t.Fatal(err) + } + res, err := eng.ProcessIntent(context.Background(), recRes, userCtx) + if err != nil { + t.Fatal(err) + } + if res.Status != coordinator.StatusClarificationRequired { + t.Fatalf("status=%s want CLARIFICATION_REQUIRED", res.Status) + } + if res.NextExpectation == nil || res.NextExpectation.Options[0].Slots[intent.SlotTargetTask] != "intake" { + t.Fatalf("default option want intake: %+v", res.NextExpectation) + } + if !strings.Contains(res.NaturalReply, "用户初始需求收集表") { + t.Fatalf("reply=%q", res.NaturalReply) + } + + // 用户拍板「好」→ 兑现 TriggerTask/intake,不再要求确认(无 tasks runner 时 Accepted stub) + userCtx.PendingExpectation = res.NextExpectation + aff, err := rec.Recognize(context.Background(), "好", userCtx.ToSnapshot()) + if err != nil { + t.Fatal(err) + } + if aff.TopIntent.Intent != intent.IntentTriggerTask || aff.TopIntent.FilledSlots[intent.SlotTargetTask] != "intake" { + t.Fatalf("affirm want TRIGGER_TASK/intake, got %s %v", aff.TopIntent.Intent, aff.TopIntent.FilledSlots) + } + done, err := eng.ProcessIntent(context.Background(), aff, userCtx) + if err != nil { + t.Fatal(err) + } + if done.Status != coordinator.StatusAccepted { + t.Fatalf("after affirm status=%s want ACCEPTED", done.Status) + } +}