feat: simplify SOP to immediate-effect configuration

This commit is contained in:
Eric 1549169735@qq.com
2026-08-18 16:27:02 +08:00
parent c5ab886b70
commit 8de48fb05e
150 changed files with 6764 additions and 1626 deletions

View File

@@ -0,0 +1,62 @@
package run
import (
"encoding/json"
"testing"
"git.iwork-ai.com/xdc/iqudo-top1/internal/model"
"gorm.io/datatypes"
)
func TestValidateKnowledgeSelectionsRejectsUnrelatedPlan(t *testing.T) {
config := map[string]interface{}{
"knowledge_selector": map[string]interface{}{"derived_field": "matched"},
"knowledge_collection": map[string]interface{}{"steps": []map[string]interface{}{
{"field_key": "segments", "name": "客户分群", "root": true, "required": true, "multiple": true},
{"field_key": "strategies", "name": "推荐策略", "from_field": "segments", "relation_type": "matched_strategy", "required": true, "multiple": true},
{"field_key": "offers", "name": "推荐内容", "from_field": "strategies", "relation_type": "recommended_offer", "required": true, "multiple": true},
}},
}
configRaw, _ := json.Marshal(config)
snapshotRaw, _ := json.Marshal(knowledgeSnapshot{
Items: []model.KnowledgeItem{
{Base: model.Base{ID: 1}, ItemKey: "vip", Name: "高价值客户", Status: "active"},
{Base: model.Base{ID: 2}, ItemKey: "renewal", Name: "续费策略", Status: "active"},
{Base: model.Base{ID: 3}, ItemKey: "annual", Name: "年度套餐", Status: "active"},
{Base: model.Base{ID: 4}, ItemKey: "trial", Name: "试用课程", Status: "active"},
},
Relations: []model.KnowledgeRelation{
{FromKnowledgeID: 1, ToKnowledgeID: 2, RelationType: "matched_strategy"},
{FromKnowledgeID: 2, ToKnowledgeID: 3, RelationType: "recommended_offer"},
},
})
derivedRaw, _ := json.Marshal(map[string]interface{}{"matched": []string{"高价值客户"}})
run := model.SOPRun{Derived: datatypes.JSON(derivedRaw), KnowledgeSnapshot: datatypes.JSON(snapshotRaw)}
node := model.SOPNode{Type: "knowledge", Config: datatypes.JSON(configRaw)}
valid := map[string]interface{}{"segments": []interface{}{"高价值客户"}, "strategies": []interface{}{"续费策略"}, "offers": []interface{}{"年度套餐"}}
if err := validateKnowledgeSelections(node, run, valid); err != nil {
t.Fatalf("valid selection rejected: %v", err)
}
invalid := map[string]interface{}{"segments": []interface{}{"高价值客户"}, "strategies": []interface{}{"续费策略"}, "offers": []interface{}{"试用课程"}}
if err := validateKnowledgeSelections(node, run, invalid); err == nil {
t.Fatal("unrelated plan should be rejected")
}
}
func TestValidateKnowledgeSelectionsAllowsAdditionalRootFromConfiguredKnowledgeType(t *testing.T) {
configRaw := datatypes.JSON([]byte(`{"knowledge_selector":{"derived_field":"matched"},"knowledge_collection":{"steps":[{"field_key":"symptoms","name":"症状","root":true,"candidate_scope":"all","knowledge_types":["symptom"],"required":true,"multiple":true}]}}`))
snapshotRaw, _ := json.Marshal(knowledgeSnapshot{Items: []model.KnowledgeItem{
{Base: model.Base{ID: 1}, ItemKey: "diarrhea", Name: "腹泻", Type: "symptom", Status: "active"},
{Base: model.Base{ID: 2}, ItemKey: "vomiting", Name: "呕吐", Type: "symptom", Status: "active"},
{Base: model.Base{ID: 3}, ItemKey: "disease", Name: "胃肠炎", Type: "disease", Status: "active"},
}})
derivedRaw, _ := json.Marshal(map[string]interface{}{"matched": []string{"腹泻"}})
run := model.SOPRun{Derived: datatypes.JSON(derivedRaw), KnowledgeSnapshot: datatypes.JSON(snapshotRaw)}
node := model.SOPNode{Type: "knowledge", Config: configRaw}
if err := validateKnowledgeSelections(node, run, map[string]interface{}{"symptoms": []interface{}{"腹泻", "呕吐"}}); err != nil {
t.Fatalf("additional symptom should be accepted: %v", err)
}
if err := validateKnowledgeSelections(node, run, map[string]interface{}{"symptoms": []interface{}{"胃肠炎"}}); err == nil {
t.Fatal("knowledge item of another type should be rejected")
}
}