Архитектура: вынести exact-route protection arbitration в assistantRoutePolicy и защитить address lane от ложного deep fallback

This commit is contained in:
2026-04-19 14:14:40 +03:00
parent f3099a2c4b
commit 6e6f94b08c
4 changed files with 235 additions and 92 deletions
@@ -229,6 +229,51 @@ describe("assistantRoutePolicy", () => {
expect(decision.orchestrationContract?.deep_session_continuation_fallback_to_deep).toBe(false);
});
it("keeps an exact address route out of deep fallback when only semantic deep hint is present", () => {
const policy = buildPolicy({
detectAddressQuestionMode: () => ({ mode: "address_query", confidence: "high" }),
resolveAddressIntent: () => ({ intent: "vat_liability_confirmed_for_tax_period", confidence: "high" }),
resolveAddressToolGateDecision: () => ({
runAddressLane: true,
decision: "run_address_lane",
reason: "address_mode_classifier_detected"
})
});
const decision = policy.resolveAssistantOrchestrationDecision({
rawUserMessage: "какой НДС мы должны заплатить на март 2020",
effectiveAddressUserMessage: "какой НДС мы должны заплатить на март 2020",
followupContext: null,
llmPreDecomposeMeta: {
applied: true,
llmCanonicalCandidateDetected: true,
predecomposeContract: {
mode: "address_query",
mode_confidence: "high",
intent: "vat_liability_confirmed_for_tax_period",
intent_confidence: "high"
},
semanticExtractionContract: {
valid: true,
apply_canonical_recommended: true,
extraction: {
query_shape: "UNKNOWN",
aggregation_profile: "unknown"
},
guard_hints: {
deep_investigation_signal_detected: true
}
}
} as any,
useMock: false
});
expect(decision.runAddressLane).toBe(true);
expect(decision.livingMode).toBe("address_data");
expect(decision.orchestrationContract?.semantic_route_arbitration?.supported_address_intent_detected).toBe(true);
expect(decision.orchestrationContract?.deep_analysis_signal_fallback_to_deep).toBe(false);
});
it("routes memory recap follow-up over grounded answer to chat", () => {
const policy = buildPolicy({
resolveRouteMemorySignals: () => ({