test(chat): 添加基于真实Agent工作区的多轮人机交互E2E测试用例
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
weichen
co-authored by
Cursor
parent
e2ca8ad55a
commit
aa968d277b
@@ -0,0 +1,131 @@
|
||||
package chat_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"chat-agent-system/internal/bizdev"
|
||||
"chat-agent-system/internal/chat"
|
||||
"chat-agent-system/internal/coordinator"
|
||||
"chat-agent-system/internal/intent"
|
||||
)
|
||||
|
||||
// TestRealE2EWorkspaceChatSimulation 基于真实 Agent 生成的业务工作区开展端到端参谋对话与三分支消解实机验证
|
||||
func TestRealE2EWorkspaceChatSimulation(t *testing.T) {
|
||||
wsDir := "data/dev/workspaces/bizdev/intake_1788792827436879000"
|
||||
if _, err := os.Stat(wsDir); os.IsNotExist(err) {
|
||||
wsDir = filepath.Join("..", "..", wsDir)
|
||||
}
|
||||
|
||||
u := coordinator.UserInfo{
|
||||
ID: "u_test_user",
|
||||
Name: "张工",
|
||||
Role: "研发负责人",
|
||||
ProjectRole: "composer",
|
||||
}
|
||||
|
||||
assembler := coordinator.NewContextAssembler()
|
||||
userCtx, err := assembler.AssembleFromWorkspace(wsDir, u)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to assemble context from real workspace: %v", err)
|
||||
}
|
||||
|
||||
if userCtx.Project.Name != "研发流程辅助智能体系统" {
|
||||
t.Errorf("expected project name '研发流程辅助智能体系统', got %s", userCtx.Project.Name)
|
||||
}
|
||||
if userCtx.Project.CustomerName != "北京水木东方科技有限公司" {
|
||||
t.Errorf("expected customer name '北京水木东方科技有限公司', got %s", userCtx.Project.CustomerName)
|
||||
}
|
||||
|
||||
rec := intent.NewRecognizer()
|
||||
engine := coordinator.NewCoordinatorEngine(nil) // 参谋交互层验证协调决策与上下文更新
|
||||
session := chat.NewSession("real_e2e_session", userCtx, rec, engine)
|
||||
|
||||
// Turn 1: 真实工作区状态与背景查询 (分支 2: 新意图抢占 QUERY_PROGRESS)
|
||||
t.Log("=== Turn 1: 询问真实工作区当前状态与风险 ===")
|
||||
resp1, err := session.SendMessage(context.Background(), "帮我看看当前项目的整体进展如何,材料到底够不够?")
|
||||
if err != nil {
|
||||
t.Fatalf("Turn 1 failed: %v", err)
|
||||
}
|
||||
if resp1.Branch != intent.BranchNewIntentPreempt {
|
||||
t.Errorf("Turn 1 expected NEW_INTENT_PREEMPT, got %s", resp1.Branch)
|
||||
}
|
||||
if resp1.IntentResult.TopIntent.Intent != intent.IntentQueryProgress {
|
||||
t.Errorf("Turn 1 expected QUERY_PROGRESS, got %s", resp1.IntentResult.TopIntent.Intent)
|
||||
}
|
||||
if !strings.Contains(resp1.ReplyText, "研发流程辅助智能体系统") {
|
||||
t.Errorf("Turn 1 reply should mention project name, got: %s", resp1.ReplyText)
|
||||
}
|
||||
t.Logf("Turn 1 响应:\n%s\n", resp1.ReplyText)
|
||||
|
||||
// Turn 2: 补充事实黑板 (分支 2: 补充信息 SUPPLEMENT_INFO)
|
||||
t.Log("=== Turn 2: 补充事实设定至真实项目黑板 ===")
|
||||
resp2, err := session.SendMessage(context.Background(), "客户确定目标市场不仅是国内,还要扩展到欧洲CE")
|
||||
if err != nil {
|
||||
t.Fatalf("Turn 2 failed: %v", err)
|
||||
}
|
||||
if resp2.Branch != intent.BranchNewIntentPreempt {
|
||||
t.Errorf("Turn 2 expected NEW_INTENT_PREEMPT, got %s", resp2.Branch)
|
||||
}
|
||||
if resp2.IntentResult.TopIntent.Intent != intent.IntentSupplementInfo {
|
||||
t.Errorf("Turn 2 expected SUPPLEMENT_INFO, got %s", resp2.IntentResult.TopIntent.Intent)
|
||||
}
|
||||
if !strings.Contains(session.UserCtx.BlackboardFacts["target_market"], "欧洲CE") {
|
||||
t.Errorf("target_market not properly updated in blackboard: %v", session.UserCtx.BlackboardFacts)
|
||||
}
|
||||
t.Logf("Turn 2 响应:\n%s\n", resp2.ReplyText)
|
||||
|
||||
// Turn 3: 模糊分忧/咨询 (分支 3: 模糊降级 AMBIGUOUS_FALLBACK)
|
||||
t.Log("=== Turn 3: 用户犹豫不决,参谋给出客观建议与选项 ===")
|
||||
resp3, err := session.SendMessage(context.Background(), "这个先放放,你觉得呢")
|
||||
if err != nil {
|
||||
t.Fatalf("Turn 3 failed: %v", err)
|
||||
}
|
||||
if resp3.Branch != intent.BranchAmbiguousFallback {
|
||||
t.Errorf("Turn 3 expected AMBIGUOUS_FALLBACK, got %s", resp3.Branch)
|
||||
}
|
||||
if !strings.Contains(resp3.ReplyText, "审慎考量") && !strings.Contains(resp3.ReplyText, "参谋建议") {
|
||||
t.Errorf("Turn 3 expected advisor consultation style, got: %s", resp3.ReplyText)
|
||||
}
|
||||
t.Logf("Turn 3 响应:\n%s\n", resp3.ReplyText)
|
||||
|
||||
// Turn 4: 极速肯定兑现推进 (分支 1: 挂起预期命中 EXPECTATION_HIT)
|
||||
t.Log("=== Turn 4: 用户极速回复“好”,直接兑现挂起预期推进至 V0.5 ===")
|
||||
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 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)
|
||||
}
|
||||
t.Logf("Turn 4 响应:\n%s\n", resp4.ReplyText)
|
||||
|
||||
// Turn 5: 否定/暂缓挂起预期 (分支 1: 显式拒绝 DECLINE_EXPECTATION)
|
||||
t.Log("=== Turn 5: 用户对新阶段的下一步建议表示暂缓 ===")
|
||||
resp5, err := session.SendMessage(context.Background(), "先别推,等等")
|
||||
if err != nil {
|
||||
t.Fatalf("Turn 5 failed: %v", err)
|
||||
}
|
||||
if resp5.Branch != intent.BranchExpectationHit {
|
||||
t.Errorf("Turn 5 expected EXPECTATION_HIT, got %s", resp5.Branch)
|
||||
}
|
||||
if resp5.IntentResult.TopIntent.Intent != intent.IntentDeclineExpectation {
|
||||
t.Errorf("Turn 5 expected DECLINE_EXPECTATION, got %s", resp5.IntentResult.TopIntent.Intent)
|
||||
}
|
||||
if !strings.Contains(resp5.ReplyText, "听您的") {
|
||||
t.Errorf("Turn 5 expected polite reply, got: %s", resp5.ReplyText)
|
||||
}
|
||||
if session.UserCtx.PendingExpectation != nil {
|
||||
t.Errorf("expected PendingExpectation to be cleared after decline")
|
||||
}
|
||||
t.Logf("Turn 5 响应:\n%s\n", resp5.ReplyText)
|
||||
}
|
||||
Reference in New Issue
Block a user