ARCH: защитить documents pivot от inventory selected-object drift
This commit is contained in:
parent
d7ee95286d
commit
5acb016573
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"schema_version": "domain_truth_harness_spec_v1",
|
||||
"scenario_id": "address_truth_harness_phase78_payments_to_contracts_all_time",
|
||||
"domain": "address_phase78_payments_to_contracts_all_time",
|
||||
"title": "Phase 78 payments to contracts all-time continuity",
|
||||
"description": "Replay for a human chain where the user opens documents by counterparty, pivots to payments, then pivots again to contracts via pronoun follow-up, and finally requests the same contracts for all available time without renaming the counterparty.",
|
||||
"bindings": {},
|
||||
"steps": [
|
||||
{
|
||||
"step_id": "step_01_documents_by_counterparty",
|
||||
"title": "Open documents for the counterparty",
|
||||
"question": "Покажи документы по Жуковке 51.",
|
||||
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
|
||||
"required_answer_patterns_all": [
|
||||
"(?i)жуковк",
|
||||
"(?i)документ|сч[её]т|акт|накладн|строк"
|
||||
],
|
||||
"criticality": "critical",
|
||||
"semantic_tags": ["documents_by_counterparty", "pivot_seed", "integrity_guard"]
|
||||
},
|
||||
{
|
||||
"step_id": "step_02_payments_by_pronoun_followup",
|
||||
"title": "Pivot to payments",
|
||||
"question": "А по нему платежи?",
|
||||
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
|
||||
"required_answer_patterns_all": [
|
||||
"(?i)жуковк|контрагент",
|
||||
"(?i)платеж|операц|банк|поступлен|списан"
|
||||
],
|
||||
"criticality": "critical",
|
||||
"semantic_tags": ["payments_followup", "counterparty_pronoun_resolution", "integrity_guard"]
|
||||
},
|
||||
{
|
||||
"step_id": "step_03_contracts_after_payments_pivot",
|
||||
"title": "Pivot again to contracts",
|
||||
"question": "А по нему договоры?",
|
||||
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
|
||||
"required_answer_patterns_all": [
|
||||
"(?i)жуковк|контрагент",
|
||||
"(?i)договор|контракт|соглаш"
|
||||
],
|
||||
"criticality": "critical",
|
||||
"semantic_tags": ["contracts_followup", "second_pivot", "integrity_guard"]
|
||||
},
|
||||
{
|
||||
"step_id": "step_04_all_time_after_second_pivot",
|
||||
"title": "Request all available time after the second pivot",
|
||||
"question": "А за все время?",
|
||||
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
|
||||
"required_answer_patterns_all": [
|
||||
"(?i)жуковк|контрагент",
|
||||
"(?i)договор|контракт|соглаш"
|
||||
],
|
||||
"forbidden_answer_patterns": [
|
||||
"(?i)уточните .* контрагент",
|
||||
"(?i)уточните .* период",
|
||||
"(?i)метадан",
|
||||
"(?i)схем",
|
||||
"(?i)объект[а-я]* 1с"
|
||||
],
|
||||
"criticality": "critical",
|
||||
"semantic_tags": ["all_time_after_second_pivot", "contracts_followup", "integrity_guard"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"schema_version": "domain_truth_harness_spec_v1",
|
||||
"scenario_id": "address_truth_harness_phase79_payments_to_contracts_to_documents_year_switch",
|
||||
"domain": "address_phase79_payments_to_contracts_to_documents_year_switch",
|
||||
"title": "Phase 79 payments to contracts to documents year-switch continuity",
|
||||
"description": "Replay for a human chain where the user opens documents by counterparty, pivots to payments, then to contracts, then back to documents by pronoun follow-up, and finally narrows the same document contour to 2021 without renaming the counterparty.",
|
||||
"bindings": {},
|
||||
"steps": [
|
||||
{
|
||||
"step_id": "step_01_documents_by_counterparty",
|
||||
"title": "Open documents for the counterparty",
|
||||
"question": "Покажи документы по Жуковке 51.",
|
||||
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
|
||||
"required_answer_patterns_all": [
|
||||
"(?i)жуковк",
|
||||
"(?i)документ|сч[её]т|акт|накладн|строк"
|
||||
],
|
||||
"criticality": "critical",
|
||||
"semantic_tags": ["documents_by_counterparty", "pivot_seed", "integrity_guard"]
|
||||
},
|
||||
{
|
||||
"step_id": "step_02_payments_by_pronoun_followup",
|
||||
"title": "Pivot to payments",
|
||||
"question": "А по нему платежи?",
|
||||
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
|
||||
"required_answer_patterns_all": [
|
||||
"(?i)жуковк|контрагент",
|
||||
"(?i)платеж|операц|банк|поступлен|списан"
|
||||
],
|
||||
"criticality": "critical",
|
||||
"semantic_tags": ["payments_followup", "counterparty_pronoun_resolution", "integrity_guard"]
|
||||
},
|
||||
{
|
||||
"step_id": "step_03_contracts_after_payments_pivot",
|
||||
"title": "Pivot to contracts",
|
||||
"question": "А по нему договоры?",
|
||||
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
|
||||
"required_answer_patterns_all": [
|
||||
"(?i)жуковк|контрагент",
|
||||
"(?i)договор|контракт|соглаш"
|
||||
],
|
||||
"criticality": "critical",
|
||||
"semantic_tags": ["contracts_followup", "second_pivot", "integrity_guard"]
|
||||
},
|
||||
{
|
||||
"step_id": "step_04_documents_after_contracts_pivot",
|
||||
"title": "Pivot back to documents",
|
||||
"question": "А по нему документы?",
|
||||
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
|
||||
"required_answer_patterns_all": [
|
||||
"(?i)жуковк|контрагент",
|
||||
"(?i)документ|сч[её]т|акт|накладн|строк"
|
||||
],
|
||||
"criticality": "critical",
|
||||
"semantic_tags": ["documents_followup", "third_pivot", "integrity_guard"]
|
||||
},
|
||||
{
|
||||
"step_id": "step_05_year_switch_after_third_pivot",
|
||||
"title": "Switch the year after the third pivot",
|
||||
"question": "А за 2021?",
|
||||
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
|
||||
"required_answer_patterns_all": [
|
||||
"(?i)2021",
|
||||
"(?i)жуковк|контрагент",
|
||||
"(?i)документ|сч[её]т|акт|накладн|строк"
|
||||
],
|
||||
"forbidden_answer_patterns": [
|
||||
"(?i)уточните .* контрагент",
|
||||
"(?i)метадан",
|
||||
"(?i)схем",
|
||||
"(?i)объект[а-я]* 1с"
|
||||
],
|
||||
"criticality": "critical",
|
||||
"semantic_tags": ["year_switch_after_third_pivot", "documents_followup", "integrity_guard"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1152,7 +1152,15 @@ function deriveIntentWithFollowupContext(detectedIntent, userMessage, followupCo
|
|||
const hasAnyPartyAnchor = hasPreviousContract || hasPreviousCounterparty;
|
||||
const isVatFollowup = hasVatCue(normalizedMessage);
|
||||
const previousIsInventoryFamily = isInventoryIntent(sourceIntent ?? undefined);
|
||||
const inventorySelectedObjectFollowup = hasSelectedObjectInventorySignal(normalizedMessage) || (previousIsInventoryFamily && hasFollowupSignal);
|
||||
const rootIsInventoryFamily = isInventoryIntent(followupContext.root_intent ?? undefined);
|
||||
const inventoryLineageActive = previousIsInventoryFamily ||
|
||||
rootIsInventoryFamily ||
|
||||
followupContext.previous_anchor_type === "item" ||
|
||||
followupContext.root_anchor_type === "item" ||
|
||||
followupContext.current_frame_kind === "inventory_root" ||
|
||||
followupContext.current_frame_kind === "inventory_drilldown";
|
||||
const inventorySelectedObjectFollowup = inventoryLineageActive &&
|
||||
(hasSelectedObjectInventorySignal(normalizedMessage) || (previousIsInventoryFamily && hasFollowupSignal));
|
||||
const inventoryPurchaseDateVatBridge = inventorySelectedObjectFollowup && hasInventoryPurchaseDateVatBridgeCue(normalizedMessage);
|
||||
if (inventoryPurchaseDateVatBridge &&
|
||||
(detectedIntent.intent === "unknown" ||
|
||||
|
|
|
|||
|
|
@ -1440,8 +1440,17 @@ function deriveIntentWithFollowupContext(
|
|||
const hasAnyPartyAnchor = hasPreviousContract || hasPreviousCounterparty;
|
||||
const isVatFollowup = hasVatCue(normalizedMessage);
|
||||
const previousIsInventoryFamily = isInventoryIntent(sourceIntent ?? undefined);
|
||||
const rootIsInventoryFamily = isInventoryIntent(followupContext.root_intent ?? undefined);
|
||||
const inventoryLineageActive =
|
||||
previousIsInventoryFamily ||
|
||||
rootIsInventoryFamily ||
|
||||
followupContext.previous_anchor_type === "item" ||
|
||||
followupContext.root_anchor_type === "item" ||
|
||||
followupContext.current_frame_kind === "inventory_root" ||
|
||||
followupContext.current_frame_kind === "inventory_drilldown";
|
||||
const inventorySelectedObjectFollowup =
|
||||
hasSelectedObjectInventorySignal(normalizedMessage) || (previousIsInventoryFamily && hasFollowupSignal);
|
||||
inventoryLineageActive &&
|
||||
(hasSelectedObjectInventorySignal(normalizedMessage) || (previousIsInventoryFamily && hasFollowupSignal));
|
||||
const inventoryPurchaseDateVatBridge =
|
||||
inventorySelectedObjectFollowup && hasInventoryPurchaseDateVatBridgeCue(normalizedMessage);
|
||||
|
||||
|
|
|
|||
|
|
@ -4632,6 +4632,22 @@ describe("address decompose stage follow-up carryover", () => {
|
|||
).toBe(true);
|
||||
});
|
||||
|
||||
it("does not drift into inventory selected-object documents on a counterparty contracts follow-up", () => {
|
||||
const result = runAddressDecomposeStage("а по нему документы?", {
|
||||
previous_intent: "list_contracts_by_counterparty",
|
||||
target_intent: "list_documents_by_counterparty",
|
||||
previous_filters: {
|
||||
counterparty: "ТСЖ \\Жуковка 51\\"
|
||||
},
|
||||
previous_anchor_type: "counterparty",
|
||||
previous_anchor_value: "ТСЖ \\Жуковка 51\\"
|
||||
});
|
||||
expect(result).not.toBeNull();
|
||||
expect(result?.intent.intent).toBe("list_documents_by_counterparty");
|
||||
expect(result?.filters.extracted_filters.counterparty).toBe("ТСЖ \\Жуковка 51\\");
|
||||
expect(result?.baseReasons).not.toContain("intent_adjusted_to_inventory_followup_context");
|
||||
});
|
||||
|
||||
it("replaces 'кроме этого документа...' pseudo-anchor with previous counterparty from follow-up context", () => {
|
||||
const result = runAddressDecomposeStage("кроме этого документа есть еще чтото?", {
|
||||
previous_intent: "list_documents_by_counterparty",
|
||||
|
|
|
|||
Loading…
Reference in New Issue