112 lines
3.8 KiB
Go
112 lines
3.8 KiB
Go
package squad_test
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"chat-agent-system/internal/squad"
|
|
)
|
|
|
|
func TestPrepareWorkspaceWritesDialogueContext(t *testing.T) {
|
|
dir := t.TempDir()
|
|
engine := squad.NewWorkspaceEngine()
|
|
ws, err := engine.PrepareWorkspace(squad.WorkspacePrepareRequest{
|
|
WorkDir: dir,
|
|
TaskKey: "system_reqs",
|
|
StageTitle: "系统需求",
|
|
ProjectName: "Demo",
|
|
CustomerName: "Acme",
|
|
DialoguePackage: &squad.DialoguePackage{
|
|
DigestMD: "# 项目对话纪要\n\n- **2026-09-24**: 张工: 器械类型眼科OCT\n",
|
|
TurnsMD: "# turns\n\n[2026-09-24 15:00] 张工(engineer/member) 用户: 器械类型:眼科OCT\n",
|
|
FactsJSON: []byte(`[{"key":"device_type","value":"眼科OCT"}]`),
|
|
ConfirmationsMD: "# 裁决\n\n无冲突\n",
|
|
TurnCount: 2,
|
|
ExcludedPrivate: 1,
|
|
ExcludedNoAccess: 0,
|
|
ExcludedNoise: 3,
|
|
},
|
|
WorkflowSteps: []squad.StepSpec{{
|
|
ID: "s1", Title: "整理", Role: "organizer", Mode: "write",
|
|
SubWorkspace: "tasks/01_organizer", Status: "pending",
|
|
}},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ws == nil {
|
|
t.Fatal("nil workspace")
|
|
}
|
|
for _, name := range []string{"digest.md", "turns.md", "facts.json", "CONFIRMATIONS.md", "README.md"} {
|
|
p := filepath.Join(dir, "context", "dialogue", name)
|
|
if _, err := os.Stat(p); err != nil {
|
|
t.Fatalf("missing %s: %v", name, err)
|
|
}
|
|
}
|
|
readme, _ := os.ReadFile(filepath.Join(dir, "context", "README.md"))
|
|
if !strings.Contains(string(readme), "collab_dialogue") {
|
|
t.Fatalf("README missing collab_dialogue: %s", readme)
|
|
}
|
|
dlgReadme, _ := os.ReadFile(filepath.Join(dir, "context", "dialogue", "README.md"))
|
|
if !strings.Contains(string(dlgReadme), "采集统计:保留 2 轮;滤除私密 1、阶段不可见 0、噪声 3") {
|
|
t.Fatalf("dialogue README missing collection stats: %s", dlgReadme)
|
|
}
|
|
taskMD, _ := os.ReadFile(filepath.Join(dir, "tasks", "01_organizer", "TASK.md"))
|
|
if !strings.Contains(string(taskMD), "context/dialogue/") {
|
|
t.Fatalf("TASK.md missing dialogue nav: %s", taskMD)
|
|
}
|
|
}
|
|
|
|
func TestPrepareWorkspaceExplainsMissingDialogue(t *testing.T) {
|
|
t.Setenv("DIALOGUE_CTX_INJECTION", "")
|
|
unbound := prepareDialogueWorkspace(t, squad.WorkspacePrepareRequest{})
|
|
readme, err := os.ReadFile(filepath.Join(unbound, "context", "dialogue", "README.md"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !strings.Contains(string(readme), "任务未绑定项目") {
|
|
t.Fatalf("unbound readme=%s", readme)
|
|
}
|
|
if _, err := os.Stat(filepath.Join(unbound, "context", "dialogue", "turns.md")); err == nil {
|
|
t.Fatal("unbound project must not pretend turns were filtered")
|
|
}
|
|
|
|
bound := prepareDialogueWorkspace(t, squad.WorkspacePrepareRequest{ProjectID: 6022})
|
|
readme, err = os.ReadFile(filepath.Join(bound, "context", "dialogue", "README.md"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !strings.Contains(string(readme), "没有对话包") {
|
|
t.Fatalf("bound readme=%s", readme)
|
|
}
|
|
|
|
t.Setenv("DIALOGUE_CTX_INJECTION", "off")
|
|
disabled := prepareDialogueWorkspace(t, squad.WorkspacePrepareRequest{ProjectID: 6022})
|
|
readme, err = os.ReadFile(filepath.Join(disabled, "context", "dialogue", "README.md"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !strings.Contains(string(readme), "开关已关闭") {
|
|
t.Fatalf("disabled readme=%s", readme)
|
|
}
|
|
}
|
|
|
|
func prepareDialogueWorkspace(t *testing.T, req squad.WorkspacePrepareRequest) string {
|
|
t.Helper()
|
|
req.WorkDir = t.TempDir()
|
|
req.TaskKey = "research"
|
|
req.StageTitle = "调研报告"
|
|
req.ProjectName = "测试项目"
|
|
req.CustomerName = "客户"
|
|
req.WorkflowSteps = []squad.StepSpec{{
|
|
ID: "s1", Title: "整理", Role: "organizer", Mode: "write",
|
|
SubWorkspace: "tasks/01_organizer", Status: "pending",
|
|
}}
|
|
if _, err := squad.NewWorkspaceEngine().PrepareWorkspace(req); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return req.WorkDir
|
|
}
|