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.
98 lines
3.0 KiB
Go
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")
|
|
}
|
|
}
|