132 lines
5.5 KiB
Go
132 lines
5.5 KiB
Go
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)
|
|
}
|