package coordinator_test import ( "os" "path/filepath" "testing" "chat-agent-system/internal/coordinator" "chat-agent-system/internal/intent" "chat-agent-system/internal/maturity" ) func TestComputeAvailableActions(t *testing.T) { actionsV01 := coordinator.ComputeAvailableActions(maturity.StageV01_Triage, "composer") foundAdvance := false for _, a := range actionsV01 { if a == "ADVANCE_STAGE:V0.5_feasibility" { foundAdvance = true } } if !foundAdvance { t.Errorf("expected V0.1 actions to contain advance to V0.5: %v", actionsV01) } actionsV05 := coordinator.ComputeAvailableActions(maturity.StageV05_Feasibility, "composer") foundAdvanceQuote := false for _, a := range actionsV05 { if a == "ADVANCE_STAGE:V1.0_quoting" { foundAdvanceQuote = true } } if !foundAdvanceQuote { t.Errorf("expected V0.5 actions to contain advance to V1.0: %v", actionsV05) } } func TestAssembleFromWorkspace(t *testing.T) { tmpDir := t.TempDir() wsJSON := `{ "project_name": "智能听诊器系统", "customer_name": "水木清研", "device_type": "电子听诊器", "task_key": "intake" }` _ = os.WriteFile(filepath.Join(tmpDir, "workspace.json"), []byte(wsJSON), 0o644) bbJSON := `{ "fields": { "project_name": "智能听诊器系统", "target_market": "国内" }, "gaps": [ {"item": "缺少蓝牙传输规格", "blocking": true, "resolved": false} ] }` _ = os.WriteFile(filepath.Join(tmpDir, "blackboard.json"), []byte(bbJSON), 0o644) outputMD := "# 用户初始需求收集表\n\n## 结论\n初步整理完成。\n\n## 待确认清单\n- 蓝牙传输距离与功耗要求\n" _ = os.WriteFile(filepath.Join(tmpDir, "output.md"), []byte(outputMD), 0o644) user := coordinator.UserInfo{ ID: "u_1001", Name: "张工", Role: "engineer", ProjectRole: "composer", } assembler := coordinator.NewContextAssembler() ctx, err := assembler.AssembleFromWorkspace(tmpDir, user) if err != nil { t.Fatalf("assemble context failed: %v", err) } if ctx.Project.Name != "智能听诊器系统" { t.Errorf("expected project name '智能听诊器系统', got '%s'", ctx.Project.Name) } if ctx.BlackboardFacts["target_market"] != "国内" { t.Errorf("expected target_market '国内', got '%s'", ctx.BlackboardFacts["target_market"]) } if len(ctx.Pending.ConfirmModifications) == 0 { t.Errorf("expected blocking gap in pending confirm modifications") } if ctx.LatestAdvisorBrief == nil { t.Fatalf("expected latest advisor brief to be assembled") } if ctx.LatestAdvisorBrief.MaturityLevel != "V0.1" { t.Errorf("expected V0.1 maturity, got %s", ctx.LatestAdvisorBrief.MaturityLevel) } } func TestIntentContractTypes(t *testing.T) { cand := intent.CandidateIntent{ Intent: intent.IntentQueryProgress, Confidence: 0.95, FilledSlots: map[string]string{ intent.SlotQueryTopic: "progress", }, Reasoning: "用户明确询问当前立项走到哪一步了", } if cand.Intent != intent.IntentQueryProgress || cand.Confidence < 0.9 { t.Errorf("candidate intent fields mismatch: %+v", cand) } }