Files
weichenandCursor 525047b841 feat(intent): depend on maturity vocabulary instead of bizdev
Intent only needed the three official stage tokens. Moving them to a
leaf package lets the recognizer compile without the orchestration root.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 10:29:38 +00:00

87 lines
2.5 KiB
Go

package intent
import (
"context"
"testing"
"chat-agent-system/internal/maturity"
)
func TestBuildIntentFrameV2_FromCandidate(t *testing.T) {
res := &IntentRecognitionResult{
RawInput: "先帮我出一版初步报价单看看",
Branch: BranchNewIntentPreempt,
TopIntent: &CandidateIntent{
Intent: IntentTriggerTask,
Confidence: 0.92,
FilledSlots: map[string]string{
SlotTargetTask: "cdo_quote",
},
Reasoning: "触发交付任务",
},
Candidates: []CandidateIntent{
{Intent: IntentTriggerTask, Confidence: 0.92},
{Intent: IntentCasualChat, Confidence: 0.20},
},
}
enrichShadowFields(res)
frame := BuildIntentFrameV2(res, DefaultRegistry())
if frame == nil {
t.Fatal("expected frame")
}
if frame.Version != IntentFrameV2Version {
t.Errorf("version: want %s got %s", IntentFrameV2Version, frame.Version)
}
if frame.ActionKey != "task.run" {
t.Errorf("action_key: want task.run got %s", frame.ActionKey)
}
if frame.LegacyIntent != IntentTriggerTask {
t.Errorf("legacy_intent: want TRIGGER_TASK got %s", frame.LegacyIntent)
}
if frame.Goal != GoalGenerate {
t.Errorf("goal: want generate got %s", frame.Goal)
}
if LegacyIntentFromFrame(frame) != IntentTriggerTask {
t.Errorf("LegacyIntentFromFrame round-trip failed")
}
}
func TestRecognize_DualWriteIntentFrameV2(t *testing.T) {
rec := NewRecognizer()
ctx := &ContextSnapshot{CurrentStage: string(maturity.StageV01_Triage)}
res, err := rec.Recognize(context.Background(), "现在这个便携超声立项评估到哪一步了?", ctx)
if err != nil {
t.Fatalf("recognize: %v", err)
}
if res.IntentFrameV2 == nil {
t.Fatal("expected intent_frame_v2 dual-write")
}
if res.IntentFrameV2.LegacyIntent != res.TopIntent.Intent {
t.Errorf("v2 legacy %s != top %s", res.IntentFrameV2.LegacyIntent, res.TopIntent.Intent)
}
if res.IntentFrameV2.ActionKey == "" {
t.Error("expected action_key on v2 frame")
}
if res.RankedFrames == nil || len(res.RankedFrames.Candidates) == 0 {
t.Error("expected ranked_frames candidates")
}
}
func TestBuildIntentFrameV2_ExpectationHitRelation(t *testing.T) {
res := &IntentRecognitionResult{
RawInput: "好",
Branch: BranchExpectationHit,
TopIntent: &CandidateIntent{
Intent: IntentAdvanceStage,
Confidence: 1.0,
FilledSlots: map[string]string{
SlotTargetStage: string(maturity.StageV05_Feasibility),
},
},
}
frame := BuildIntentFrameV2(res, DefaultRegistry())
if frame.Relation != RelationExpectationHit {
t.Errorf("relation: want expectation_hit got %s", frame.Relation)
}
}