242 lines
8.6 KiB
Go
242 lines
8.6 KiB
Go
package chat_test
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
|
|
"chat-agent-system/internal/bizdev"
|
|
"chat-agent-system/internal/chat"
|
|
"chat-agent-system/internal/coordinator"
|
|
"chat-agent-system/internal/intent"
|
|
"chat-agent-system/internal/squad"
|
|
)
|
|
|
|
func TestChatSession_EndToEndDialog(t *testing.T) {
|
|
rec := intent.NewRecognizer()
|
|
engine := coordinator.NewCoordinatorEngine(nil)
|
|
|
|
userCtx := &coordinator.UserProjectContext{
|
|
SnapshotID: "sess_ctx_1",
|
|
User: coordinator.UserInfo{
|
|
ID: "u1",
|
|
Name: "张工",
|
|
Role: "engineer",
|
|
ProjectRole: "composer",
|
|
},
|
|
Project: coordinator.ProjectInfo{
|
|
Name: "掌上无线超声系统",
|
|
CurrentStage: bizdev.StageV01_Triage,
|
|
},
|
|
LatestAdvisorBrief: &squad.AdvisorBriefing{
|
|
MaturityScore: 75,
|
|
MaturityLevel: "V0.1",
|
|
MaturityHeadline: "初步框架已就绪",
|
|
PreemptiveRisks: []string{"探头功耗与散热设计"},
|
|
NextBestActions: []string{"补充客户供电参数", "推进到V0.5可行性论证"},
|
|
CommunicationKit: "建议与客户确认供电方式",
|
|
},
|
|
}
|
|
|
|
session := chat.NewSession("sess_001", userCtx, rec, engine)
|
|
|
|
// Turn 1: 问候 (分支 2: 新指令/对话)
|
|
resp1, err := session.SendMessage(context.Background(), "你好,请问你是谁?")
|
|
if err != nil {
|
|
t.Fatalf("turn 1 failed: %v", err)
|
|
}
|
|
if resp1.IntentResult.TopIntent.Intent != intent.IntentCasualChat {
|
|
t.Errorf("turn 1 expected CASUAL_CHAT, got %s", resp1.IntentResult.TopIntent.Intent)
|
|
}
|
|
|
|
// Turn 2: 查进展与风险 (分支 2: 抢占查询)
|
|
resp2, err := session.SendMessage(context.Background(), "现在这个项目进展怎么样?有啥风险没?")
|
|
if err != nil {
|
|
t.Fatalf("turn 2 failed: %v", err)
|
|
}
|
|
if resp2.IntentResult.TopIntent.Intent != intent.IntentQueryProgress {
|
|
t.Errorf("turn 2 expected QUERY_PROGRESS, got %s", resp2.IntentResult.TopIntent.Intent)
|
|
}
|
|
if !strings.Contains(resp2.ReplyText, "掌上无线超声系统") {
|
|
t.Errorf("turn 2 reply should mention project name: %s", resp2.ReplyText)
|
|
}
|
|
|
|
// Turn 3: 补充信息 (分支 2: 补充事实)
|
|
resp3, err := session.SendMessage(context.Background(), "客户补充说目标市场是国内及欧洲CE")
|
|
if err != nil {
|
|
t.Fatalf("turn 3 failed: %v", err)
|
|
}
|
|
if resp3.IntentResult.TopIntent.Intent != intent.IntentSupplementInfo {
|
|
t.Errorf("turn 3 expected SUPPLEMENT_INFO, got %s", resp3.IntentResult.TopIntent.Intent)
|
|
}
|
|
if session.UserCtx.BlackboardFacts["target_market"] != "国内及欧洲CE" {
|
|
t.Errorf("target_market not updated: %v", session.UserCtx.BlackboardFacts)
|
|
}
|
|
|
|
// Turn 4: 单字快速肯定兑现上轮推荐 (分支 1: 极速兑现)
|
|
resp4, err := session.SendMessage(context.Background(), "好")
|
|
if err != nil {
|
|
t.Fatalf("turn 4 failed: %v", err)
|
|
}
|
|
if resp4.Branch != intent.BranchExpectationHit {
|
|
t.Errorf("turn 4 expected branch EXPECTATION_HIT, got %s", resp4.Branch)
|
|
}
|
|
if resp4.IntentResult.TopIntent.Intent != intent.IntentAdvanceStage {
|
|
t.Errorf("turn 4 expected ADVANCE_STAGE, got %s", resp4.IntentResult.TopIntent.Intent)
|
|
}
|
|
if session.UserCtx.Project.CurrentStage != bizdev.StageV05_Feasibility {
|
|
t.Errorf("expected project advanced to V0.5, got %s", session.UserCtx.Project.CurrentStage)
|
|
}
|
|
|
|
if len(session.Messages) != 8 {
|
|
t.Errorf("expected 8 messages (4 user + 4 asst), got %d", len(session.Messages))
|
|
}
|
|
}
|
|
|
|
// 用例 1: 分支 1 极速兑现 ("好" / "1")
|
|
func TestChatSession_Branch1_FastAffirmative(t *testing.T) {
|
|
rec := intent.NewRecognizer()
|
|
engine := coordinator.NewCoordinatorEngine(nil)
|
|
userCtx := &coordinator.UserProjectContext{
|
|
Project: coordinator.ProjectInfo{
|
|
Name: "心电贴片系统",
|
|
CurrentStage: bizdev.StageV01_Triage,
|
|
},
|
|
}
|
|
|
|
session := chat.NewSession("sess_fast", userCtx, rec, engine)
|
|
resp, err := session.SendMessage(context.Background(), "好")
|
|
if err != nil {
|
|
t.Fatalf("send message failed: %v", err)
|
|
}
|
|
|
|
if resp.Branch != intent.BranchExpectationHit {
|
|
t.Errorf("expected EXPECTATION_HIT, got %s", resp.Branch)
|
|
}
|
|
if resp.IntentResult.TopIntent.Intent != intent.IntentAdvanceStage {
|
|
t.Errorf("expected ADVANCE_STAGE, got %s", resp.IntentResult.TopIntent.Intent)
|
|
}
|
|
if session.UserCtx.Project.CurrentStage != bizdev.StageV05_Feasibility {
|
|
t.Errorf("expected stage V0.5, got %s", session.UserCtx.Project.CurrentStage)
|
|
}
|
|
}
|
|
|
|
// 用例 2: 分支 1 复合打补丁 ("好,但目标市场改成欧洲CE")
|
|
func TestChatSession_Branch1_AffirmativeWithPatch(t *testing.T) {
|
|
rec := intent.NewRecognizer()
|
|
engine := coordinator.NewCoordinatorEngine(nil)
|
|
userCtx := &coordinator.UserProjectContext{
|
|
Project: coordinator.ProjectInfo{
|
|
Name: "便携超声设备",
|
|
CurrentStage: bizdev.StageV01_Triage,
|
|
},
|
|
BlackboardFacts: make(map[string]string),
|
|
}
|
|
|
|
session := chat.NewSession("sess_patch", userCtx, rec, engine)
|
|
resp, err := session.SendMessage(context.Background(), "好,但目标市场改成欧洲CE")
|
|
if err != nil {
|
|
t.Fatalf("send message failed: %v", err)
|
|
}
|
|
|
|
if resp.Branch != intent.BranchExpectationHit {
|
|
t.Errorf("expected EXPECTATION_HIT, got %s", resp.Branch)
|
|
}
|
|
if resp.IntentResult.TopIntent.Intent != intent.IntentAdvanceStage {
|
|
t.Errorf("expected ADVANCE_STAGE, got %s", resp.IntentResult.TopIntent.Intent)
|
|
}
|
|
if session.UserCtx.BlackboardFacts["target_market"] != "欧洲CE" {
|
|
t.Errorf("expected blackboard target_market '欧洲CE', got '%s'", session.UserCtx.BlackboardFacts["target_market"])
|
|
}
|
|
if session.UserCtx.Project.TargetMarket != "欧洲CE" {
|
|
t.Errorf("expected project TargetMarket '欧洲CE', got '%s'", session.UserCtx.Project.TargetMarket)
|
|
}
|
|
}
|
|
|
|
// 用例 3: 分支 1 否定撤销 ("先别推,等等")
|
|
func TestChatSession_Branch1_Decline(t *testing.T) {
|
|
rec := intent.NewRecognizer()
|
|
engine := coordinator.NewCoordinatorEngine(nil)
|
|
userCtx := &coordinator.UserProjectContext{
|
|
Project: coordinator.ProjectInfo{
|
|
Name: "骨科手术机器人",
|
|
CurrentStage: bizdev.StageV01_Triage,
|
|
},
|
|
}
|
|
|
|
session := chat.NewSession("sess_decline", userCtx, rec, engine)
|
|
resp, err := session.SendMessage(context.Background(), "先别推,等等")
|
|
if err != nil {
|
|
t.Fatalf("send message failed: %v", err)
|
|
}
|
|
|
|
if resp.Branch != intent.BranchExpectationHit {
|
|
t.Errorf("expected EXPECTATION_HIT, got %s", resp.Branch)
|
|
}
|
|
if resp.IntentResult.TopIntent.Intent != intent.IntentDeclineExpectation {
|
|
t.Errorf("expected DECLINE_EXPECTATION, got %s", resp.IntentResult.TopIntent.Intent)
|
|
}
|
|
if session.UserCtx.PendingExpectation != nil {
|
|
t.Errorf("expected PendingExpectation to be cleared after decline")
|
|
}
|
|
if !strings.Contains(resp.ReplyText, "听您的") {
|
|
t.Errorf("expected polite advisor reply: %s", resp.ReplyText)
|
|
}
|
|
}
|
|
|
|
// 用例 4: 分支 2 突发话题抢占 ("查一下探头功耗要怎么设计")
|
|
func TestChatSession_Branch2_TopicPreemption(t *testing.T) {
|
|
rec := intent.NewRecognizer()
|
|
engine := coordinator.NewCoordinatorEngine(nil)
|
|
userCtx := &coordinator.UserProjectContext{
|
|
Project: coordinator.ProjectInfo{
|
|
Name: "无线超声系统",
|
|
CurrentStage: bizdev.StageV01_Triage,
|
|
},
|
|
}
|
|
|
|
session := chat.NewSession("sess_preempt", userCtx, rec, engine)
|
|
resp, err := session.SendMessage(context.Background(), "查一下探头功耗要怎么设计")
|
|
if err != nil {
|
|
t.Fatalf("send message failed: %v", err)
|
|
}
|
|
|
|
if resp.Branch != intent.BranchNewIntentPreempt {
|
|
t.Errorf("expected NEW_INTENT_PREEMPT, got %s", resp.Branch)
|
|
}
|
|
if resp.IntentResult.TopIntent.Intent != intent.IntentQueryProgress {
|
|
t.Errorf("expected QUERY_PROGRESS, got %s", resp.IntentResult.TopIntent.Intent)
|
|
}
|
|
if !strings.Contains(resp.ReplyText, "功耗") && !strings.Contains(resp.ReplyText, "架构") {
|
|
t.Errorf("expected technical answer in reply: %s", resp.ReplyText)
|
|
}
|
|
}
|
|
|
|
// 用例 5: 分支 3 模糊分忧 ("这个先放放,你觉得呢")
|
|
func TestChatSession_Branch3_AmbiguousConsult(t *testing.T) {
|
|
rec := intent.NewRecognizer()
|
|
engine := coordinator.NewCoordinatorEngine(nil)
|
|
userCtx := &coordinator.UserProjectContext{
|
|
Project: coordinator.ProjectInfo{
|
|
Name: "智能输注泵项目",
|
|
CurrentStage: bizdev.StageV01_Triage,
|
|
},
|
|
}
|
|
|
|
session := chat.NewSession("sess_consult", userCtx, rec, engine)
|
|
resp, err := session.SendMessage(context.Background(), "这个先放放,你觉得呢")
|
|
if err != nil {
|
|
t.Fatalf("send message failed: %v", err)
|
|
}
|
|
|
|
if resp.Branch != intent.BranchAmbiguousFallback {
|
|
t.Errorf("expected AMBIGUOUS_FALLBACK, got %s", resp.Branch)
|
|
}
|
|
if !strings.Contains(resp.ReplyText, "审慎考量") && !strings.Contains(resp.ReplyText, "参谋建议") {
|
|
t.Errorf("expected thoughtful advisor consult in reply: %s", resp.ReplyText)
|
|
}
|
|
if session.UserCtx.PendingExpectation == nil {
|
|
t.Errorf("expected NextExpectation to be populated for user choice")
|
|
}
|
|
}
|