Files
weichen 016135d946 feat(intentflow): wire U9–U12 live adapters for multi-intent closeout
Connect LLM segment proposals into HandleTurn, replace U10–U12 dry-run stubs
with production owners (blackboard supplement, docgov claim/submit, workflow
run/resume) when flags are on, and update policy/sysadmin maturity metadata.
2026-09-23 15:26:46 +00:00

98 lines
3.0 KiB
Go

package intentflow_test
import (
"context"
"testing"
"chat-agent-system/internal/app/intentflow"
)
type stubSpanProposer struct {
spans []intentflow.SegmentSpan
err error
}
func (s stubSpanProposer) Propose(context.Context, intentflow.SegmentProposalRequest) (*intentflow.SegmentProposal, error) {
if s.err != nil {
return nil, s.err
}
return &intentflow.SegmentProposal{
SchemaVersion: intentflow.SegmentProposalSchemaV1,
Digest: "stub-digest",
Spans: s.spans,
}, nil
}
func TestHandleTurnU9FailClosedOnMalformedProposal(t *testing.T) {
intentflow.SetFeatureFlagsForTest(intentflow.FeatureFlags{
PlanTier: intentflow.TierAutoRead, U9Segment: true, ProjectAllowlist: []int64{42},
})
t.Cleanup(intentflow.ResetFeatureFlagsForTest)
intentflow.SetLLMSegmentProposer(stubSpanProposer{err: intentflow.ErrSegmentProposalMalformed})
t.Cleanup(func() { intentflow.SetLLMSegmentProposer(nil) })
p, _, _ := testPlans()
res, err := p.HandleTurn(context.Background(), intentflow.TurnInput{
Principal: principal(), Text: "帮我查法规再查案例",
ClientTurnID: "u9-fail", RequestDigest: "u9-fail-d",
})
if err != nil {
t.Fatal(err)
}
if res.Plan != nil {
t.Fatalf("malformed U9 must fail closed: %+v", res.Plan)
}
}
func TestHandleTurnU9SkipsLLMWhenRulesDecide(t *testing.T) {
intentflow.SetFeatureFlagsForTest(intentflow.FeatureFlags{
PlanTier: intentflow.TierAutoRead, U9Segment: true, ProjectAllowlist: []int64{42},
})
t.Cleanup(intentflow.ResetFeatureFlagsForTest)
intentflow.SetLLMSegmentProposer(stubSpanProposer{
spans: []intentflow.SegmentSpan{{Start: 0, End: 1, Text: "x"}},
})
t.Cleanup(func() { intentflow.SetLLMSegmentProposer(nil) })
p, _, _ := testPlans()
res, err := p.HandleTurn(context.Background(), intentflow.TurnInput{
Principal: principal(), Text: "查一下项目风险,然后查相关法规",
ClientTurnID: "u9-rules", RequestDigest: "u9-rules-d",
})
if err != nil {
t.Fatal(err)
}
if res == nil || res.Plan == nil {
t.Fatal("rules-decided connector split must still plan")
}
}
func TestHandleTurnU9AllowlistStillGates(t *testing.T) {
intentflow.SetFeatureFlagsForTest(intentflow.FeatureFlags{
PlanTier: intentflow.TierAutoRead, U9Segment: true,
})
t.Cleanup(intentflow.ResetFeatureFlagsForTest)
intentflow.ResetMetricsForTest()
text := "帮我查法规再查案例"
intentflow.SetLLMSegmentProposer(stubSpanProposer{spans: []intentflow.SegmentSpan{
{Start: 0, End: 15, Text: "帮我查法规"},
{Start: 15, End: 27, Text: "再查案例"},
}})
t.Cleanup(func() { intentflow.SetLLMSegmentProposer(nil) })
p, _, _ := testPlans()
res, err := p.HandleTurn(context.Background(), intentflow.TurnInput{
Principal: principal(), Text: text,
ClientTurnID: "u9-allow", RequestDigest: "u9-allow-d",
})
if err != nil {
t.Fatal(err)
}
if res.Plan != nil {
t.Fatalf("empty allowlist must deny U9 elevated tier: %+v", res.Plan)
}
if intentflow.Metrics().Snapshot().AllowlistDenied < 1 {
t.Fatal("expected allowlist_denied metric")
}
}