NODEDC_1C/llm_normalizer/backend/tests/assistantTransitionPolicy.t...

883 lines
34 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, expect, it } from "vitest";
import { createAssistantTransitionPolicy } from "../src/services/assistantTransitionPolicy";
import { buildRootScopedCarryoverFilters } from "../src/services/assistantContinuityPolicy";
function toNonEmptyString(value: unknown): string | null {
if (value === null || value === undefined) {
return null;
}
const text = String(value).trim();
return text.length > 0 ? text : null;
}
function buildPolicy(overrides: Record<string, unknown> = {}) {
return createAssistantTransitionPolicy({
compactWhitespace: (value: string) => String(value ?? "").replace(/\s+/g, " ").trim(),
repairAddressMojibake: (value: string) => value,
countTokens: (value: string) => String(value ?? "").split(/\s+/).filter(Boolean).length,
shouldHandleAsAssistantCapabilityMetaQuery: () => false,
hasDataRetrievalRequestSignal: () => false,
findLastAddressAssistantItem: () => ({
text: "1. Рабочая станция",
debug: {
detected_intent: "inventory_purchase_documents_for_item",
extracted_filters: {
item: "Рабочая станция"
},
anchor_type: "item",
anchor_value_resolved: "Рабочая станция"
}
}),
findLastOrganizationClarificationAddressDebug: () => null,
mergeKnownOrganizations: (values: unknown[]) => values,
resolveOrganizationSelectionFromMessage: () => null,
toNonEmptyString,
buildAddressFollowupOffer: () => null,
isImplicitAddressContinuationByLlm: () => false,
isInventorySelectedObjectIntent: (intent: unknown) =>
[
"inventory_purchase_provenance_for_item",
"inventory_purchase_documents_for_item",
"inventory_sale_trace_for_item",
"inventory_profitability_for_item",
"inventory_purchase_to_sale_chain",
"inventory_aging_by_purchase_date"
].includes(String(intent ?? "")),
hasShortInventoryObjectFollowupSignal: () => false,
resolveDebtRoleSwapFollowupIntent: () => null,
hasAddressFollowupContextSignal: () => false,
extractDisplayedEntityIndexMention: () => null,
findRecentInventoryRootFrame: () => ({
intent: "inventory_on_hand_as_of_date",
filters: {
as_of_date: "2020-03-31",
organization: 'ООО "Альтернатива Плюс"'
},
anchorType: "organization",
anchorValue: 'ООО "Альтернатива Плюс"'
}),
hasInventoryRootTemporalFollowupSignal: (message: string) => /март 2020/i.test(message),
hasFollowupMarker: () => false,
hasReferentialPointer: () => false,
hasStandaloneAddressTopicSignal: () => false,
resolveAddressIntent: () => ({ intent: "unknown" }),
resolveAddressIntentFamily: (intent: unknown) => (intent ? String(intent) : null),
readAddressFilterString: (debug: Record<string, unknown>, key: string) =>
debug?.extracted_filters && typeof debug.extracted_filters === "object"
? toNonEmptyString((debug.extracted_filters as Record<string, unknown>)[key])
: null,
normalizeOrganizationScopeValue: (value: unknown) => toNonEmptyString(value),
isInventoryDrilldownFrameIntent: (intent: unknown) =>
[
"inventory_purchase_provenance_for_item",
"inventory_purchase_documents_for_item",
"inventory_sale_trace_for_item",
"inventory_profitability_for_item",
"inventory_purchase_to_sale_chain",
"inventory_aging_by_purchase_date"
].includes(String(intent ?? "")),
isInventoryRootFrameIntent: (intent: unknown) => String(intent ?? "") === "inventory_on_hand_as_of_date",
findRecentAddressFilterValue: () => null,
hasForeignAccountingPivotOverInventoryMessage: () => false,
buildRootScopedCarryoverFilters: (
previousFilters: Record<string, unknown>,
inventoryRootFrame: Record<string, unknown>
) => ({
organization:
toNonEmptyString(inventoryRootFrame?.filters?.organization) ?? toNonEmptyString(previousFilters?.organization),
warehouse:
toNonEmptyString(inventoryRootFrame?.filters?.warehouse) ?? toNonEmptyString(previousFilters?.warehouse),
as_of_date:
toNonEmptyString(previousFilters?.as_of_date) ?? toNonEmptyString(inventoryRootFrame?.filters?.as_of_date),
period_from:
toNonEmptyString(previousFilters?.period_from) ?? toNonEmptyString(inventoryRootFrame?.filters?.period_from),
period_to:
toNonEmptyString(previousFilters?.period_to) ?? toNonEmptyString(inventoryRootFrame?.filters?.period_to)
}),
inferDisplayedEntityTypeFromIntent: () => "item",
extractDisplayedAddressEntityCandidates: () => [],
resolveDisplayedAddressEntityMention: () => null,
...overrides
});
}
describe("assistantTransitionPolicy", () => {
it("promotes inventory temporal follow-up into root-scoped carryover", () => {
const policy = buildPolicy();
const carryover = policy.resolveAddressFollowupCarryoverContext(
"остатки на март 2020",
[],
null,
null,
{
session_context: {
active_focus_object: {
object_type: "item",
label: "Рабочая станция"
}
}
}
);
expect(carryover?.followupSelectionMode).toBe("carry_root_context");
expect(carryover?.followupContext?.root_context_only).toBe(true);
expect(carryover?.followupContext?.target_intent).toBe("inventory_on_hand_as_of_date");
expect(carryover?.followupContext?.root_intent).toBe("inventory_on_hand_as_of_date");
expect(carryover?.followupContext?.previous_filters).toMatchObject({
as_of_date: "2020-03-31",
organization: 'ООО "Альтернатива Плюс"'
});
});
it("promotes same-date inventory restatement after drilldown into root-scoped carryover", () => {
const policy = buildPolicy({
hasInventoryRootTemporalFollowupSignal: () => false
});
const carryover = policy.resolveAddressFollowupCarryoverContext(
"покажи еще раз остатки на эту же дату",
[],
null,
null,
null
);
expect(carryover?.followupSelectionMode).toBe("carry_root_context");
expect(carryover?.followupContext?.root_context_only).toBe(true);
expect(carryover?.followupContext?.previous_intent).toBeUndefined();
expect(carryover?.followupContext?.previous_filters).toMatchObject({
as_of_date: "2020-03-31",
organization: 'ООО "Альтернатива Плюс"'
});
expect(carryover?.followupContext?.root_intent).toBe("inventory_on_hand_as_of_date");
});
it("builds continuation contract from extracted root carryover", () => {
const policy = buildPolicy();
const contract = policy.buildAddressDialogContinuationContractV2(
"остатки на эту дату",
"остатки на эту дату",
{
followupContext: {
root_intent: "inventory_on_hand_as_of_date",
previous_anchor_type: "item",
previous_anchor_value: "Рабочая станция"
},
previousSourceIntent: "inventory_purchase_documents_for_item",
previousAddressIntent: null,
followupSelectionMode: "carry_root_context",
hasImplicitContinuationSignal: true
},
{
predecomposeContract: {
intent: "unknown"
}
}
);
expect(contract.decision).toBe("continue_previous");
expect(contract.target_intent).toBe("inventory_on_hand_as_of_date");
expect(contract.decision_reasons).toContain("root_context_only_carryover");
expect(contract.decision_reasons).toContain("implicit_continuation_by_llm");
expect(contract.anchor_type).toBe("item");
expect(contract.anchor_value).toBe("Рабочая станция");
});
it("prefers carryover target intent over llm contract drift in continuation contract", () => {
const policy = buildPolicy();
const contract = policy.buildAddressDialogContinuationContractV2(
"покажи договор по гамме",
"покажи договор по гамме",
{
followupContext: {
previous_intent: "customer_revenue_and_payments",
target_intent: "list_contracts_by_counterparty",
previous_anchor_type: "counterparty",
previous_anchor_value: "Гамма-мебель, ООО"
},
previousSourceIntent: "customer_revenue_and_payments",
previousAddressIntent: "customer_revenue_and_payments",
followupSelectionMode: "carry_referenced_entity",
hasImplicitContinuationSignal: false
},
{
predecomposeContract: {
intent: "unknown"
}
}
);
expect(contract.target_intent).toBe("list_contracts_by_counterparty");
expect(contract.decision).toBe("continue_previous");
});
it("retargets displayed counterparty follow-up through shared referenced-entity carryover", () => {
const policy = buildPolicy({
findLastAddressAssistantItem: () => ({
text: "1. SVK Group\n2. Gamma",
debug: {
detected_intent: "customer_revenue_and_payments",
extracted_filters: {
organization: 'ООО "Альтернатива Плюс"',
period_from: "2017-01-01",
period_to: "2017-12-31"
}
}
}),
hasAddressFollowupContextSignal: () => true,
inferDisplayedEntityTypeFromIntent: () => "counterparty",
extractDisplayedAddressEntityCandidates: () => [{ entityType: "counterparty", value: "SVK Group" }],
resolveDisplayedAddressEntityMention: () => ({ entityType: "counterparty", value: "SVK Group" }),
resolveAddressIntent: () => ({ intent: "unknown" })
});
const carryover = policy.resolveAddressFollowupCarryoverContext(
"покажи договоры по СВК",
[],
null,
null,
null
);
expect(carryover?.followupSelectionMode).toBe("carry_referenced_entity");
expect(carryover?.followupContext?.target_intent).toBe("list_contracts_by_counterparty");
expect(carryover?.followupContext?.previous_anchor_type).toBe("counterparty");
expect(carryover?.followupContext?.previous_anchor_value).toBe("SVK Group");
expect(carryover?.followupContext?.previous_filters).toMatchObject({
organization: 'ООО "Альтернатива Плюс"',
counterparty: "SVK Group",
period_from: "2017-01-01",
period_to: "2017-12-31"
});
expect(carryover?.followupContext?.resolved_counterparty_from_display).toBe(true);
});
it("retargets same-date inventory follow-up away from receivables intent", () => {
const policy = buildPolicy({
findLastAddressAssistantItem: () => ({
text: "Подтвержденная дебиторская задолженность на 31.03.2020 собрана.",
debug: {
detected_intent: "receivables_confirmed_as_of_date",
extracted_filters: {
organization: 'ООО "Альтернатива Плюс"',
as_of_date: "2020-03-31",
period_from: "2020-03-01",
period_to: "2020-03-31"
},
anchor_type: "organization",
anchor_value_resolved: 'ООО "Альтернатива Плюс"'
}
}),
hasAddressFollowupContextSignal: () => true,
hasReferentialPointer: () => true,
findRecentInventoryRootFrame: () => null,
resolveAddressIntent: () => ({ intent: "unknown" })
});
const carryover = policy.resolveAddressFollowupCarryoverContext(
"остатки по складу на эту же дату",
[],
null,
null,
null
);
expect(carryover?.followupSelectionMode).toBe("carry_previous_intent");
expect(carryover?.followupContext?.previous_intent).toBe("receivables_confirmed_as_of_date");
expect(carryover?.followupContext?.target_intent).toBe("inventory_on_hand_as_of_date");
expect(carryover?.followupContext?.previous_filters).toMatchObject({
organization: 'ООО "Альтернатива Плюс"',
as_of_date: "2020-03-31",
period_from: "2020-03-01",
period_to: "2020-03-31"
});
expect(carryover?.followupContext?.root_context_only).toBeUndefined();
});
it("hydrates follow-up organization from shared assistant authority when local history filters are empty", () => {
const policy = buildPolicy({
findLastAddressAssistantItem: () => ({
text: "Подтвержденная дебиторская задолженность на 31.03.2020 собрана.",
debug: {
detected_intent: "receivables_confirmed_as_of_date",
extracted_filters: {
as_of_date: "2020-03-31",
period_from: "2020-03-01",
period_to: "2020-03-31"
},
anchor_type: "organization",
anchor_value_resolved: null
}
}),
hasAddressFollowupContextSignal: () => true,
hasReferentialPointer: () => true,
findRecentInventoryRootFrame: () => null,
findRecentAddressFilterValue: () => null,
resolveAddressIntent: () => ({ intent: "unknown" })
});
const carryover = policy.resolveAddressFollowupCarryoverContext(
"остатки по складу на эту же дату",
[
{
role: "assistant",
text: "Компания уже выбрана в живом чате.",
debug: {
assistant_active_organization: 'ООО "Альтернатива Плюс"',
assistant_known_organizations: ['ООО "Альтернатива Плюс"', 'ООО "Лайт"']
}
}
],
null,
null,
null
);
expect(carryover?.followupContext?.previous_filters).toMatchObject({
organization: 'ООО "Альтернатива Плюс"',
as_of_date: "2020-03-31",
period_from: "2020-03-01",
period_to: "2020-03-31"
});
expect(carryover?.followupContext?.target_intent).toBe("inventory_on_hand_as_of_date");
});
it("hydrates carryover anchor from shared debug helpers when explicit anchor fields are absent", () => {
const policy = buildPolicy({
findLastAddressAssistantItem: () => ({
text: "Подтвержденный складской срез собран.",
debug: {
detected_intent: "inventory_on_hand_as_of_date",
extracted_filters: {
item: "Рабочая станция",
period_from: "2020-03-01"
},
address_root_frame_context: {
as_of_date: "2020-03-31",
period_to: "2020-03-31"
},
anchor_type: null,
anchor_value_resolved: null
}
}),
hasAddressFollowupContextSignal: () => true,
hasReferentialPointer: () => true,
findRecentInventoryRootFrame: () => null,
findRecentAddressFilterValue: () => null,
resolveAddressIntent: () => ({ intent: "unknown" })
});
const carryover = policy.resolveAddressFollowupCarryoverContext("по этой позиции", [], null, null, null);
expect(carryover?.followupContext?.previous_anchor_type).toBe("item");
expect(carryover?.followupContext?.previous_anchor_value).toBe("Рабочая станция");
expect(carryover?.followupContext?.previous_filters).toMatchObject({
item: "Рабочая станция",
period_from: "2020-03-01"
});
});
it("bridges selected-item purchase provenance into a VAT period follow-up", () => {
const item = "Рабочая станция универсального специалиста";
const policy = buildPolicy({
findLastAddressAssistantItem: () => ({
text: [
`По позиции ${item} однозначный поставщик не подтвержден.`,
"Подтверждение:",
"- Первая найденная дата закупки: 05.02.2015.",
"- Последняя найденная дата закупки: 22.07.2015."
].join("\n"),
debug: {
detected_intent: "inventory_purchase_provenance_for_item",
extracted_filters: {
item,
organization: 'ООО "Альтернатива Плюс"',
as_of_date: "2016-03-31"
},
anchor_type: "item",
anchor_value_resolved: item
}
}),
hasAddressFollowupContextSignal: () => false,
findRecentInventoryRootFrame: () => null,
resolveAddressIntent: () => ({ intent: "unknown" })
});
const carryover = policy.resolveAddressFollowupCarryoverContext(
"ндс можешь прикинуть на дату покупки рабочей станции?",
[],
null,
null,
{
session_context: {
active_focus_object: {
object_type: "item",
label: item,
provenance_result_set_id: "rs-provenance"
},
active_result_set_id: "rs-provenance"
},
result_sets: [
{
result_set_id: "rs-provenance",
intent: "inventory_purchase_provenance_for_item",
entity_refs: [
{
index: 1,
entity_type: "item",
value: "Поступление товаров и услуг 00000000023 от 05.02.2015 0:00:00"
}
]
}
]
}
);
expect(carryover?.followupContext?.previous_intent).toBe("inventory_purchase_provenance_for_item");
expect(carryover?.followupContext?.target_intent).toBe("vat_liability_confirmed_for_tax_period");
expect(carryover?.followupContext?.previous_filters).toMatchObject({
item,
organization: 'ООО "Альтернатива Плюс"',
period_from: "2015-02-01",
period_to: "2015-02-28"
});
});
it("keeps selected-object continuity for purchase-date VAT bridge even when an inventory root frame exists", () => {
const item = "Рабочая станция универсального специалиста";
const policy = buildPolicy({
findLastAddressAssistantItem: () => ({
text: [
`По позиции ${item} однозначный поставщик не подтвержден.`,
"Подтверждение:",
"- Первая найденная дата закупки: 05.02.2015."
].join("\n"),
debug: {
detected_intent: "inventory_purchase_provenance_for_item",
extracted_filters: {
item,
organization: 'ООО "Альтернатива Плюс"',
as_of_date: "2016-03-31"
},
anchor_type: "item",
anchor_value_resolved: item
}
}),
hasAddressFollowupContextSignal: () => false,
hasForeignAccountingPivotOverInventoryMessage: () => true,
resolveAddressIntent: () => ({ intent: "unknown" })
});
const carryover = policy.resolveAddressFollowupCarryoverContext(
"ндс можешь прикинуть на дату покупки рабочей станции?",
[],
null,
null,
{
session_context: {
active_focus_object: {
object_type: "item",
label: item,
provenance_result_set_id: "rs-provenance"
},
active_result_set_id: "rs-provenance"
},
result_sets: [
{
result_set_id: "rs-provenance",
intent: "inventory_purchase_provenance_for_item",
entity_refs: [
{
index: 1,
entity_type: "item",
value: "Поступление товаров и услуг 00000000023 от 05.02.2015 0:00:00"
}
]
}
]
}
);
expect(carryover?.followupSelectionMode).toBe("carry_previous_intent");
expect(carryover?.followupContext?.root_context_only).toBeUndefined();
expect(carryover?.followupContext?.previous_intent).toBe("inventory_purchase_provenance_for_item");
expect(carryover?.followupContext?.target_intent).toBe("vat_liability_confirmed_for_tax_period");
});
it("keeps purchase-date VAT bridge after unsupported verification interrupt", () => {
const item = "Рабочая станция универрсального специалиста";
const provenanceItem = {
role: "assistant",
text: [
`По позиции ${item} однозначный поставщик не подтвержден.`,
"Подтверждение:",
"- Первая найденная дата закупки: 05.02.2015."
].join("\n"),
debug: {
execution_lane: "address_query",
answer_grounding_check: {
status: "grounded"
},
detected_intent: "inventory_purchase_provenance_for_item",
extracted_filters: {
item,
organization: 'ООО "Альтернатива Плюс"',
as_of_date: "2016-03-31"
},
anchor_type: "item",
anchor_value_resolved: item
}
} as any;
const unsupportedInterrupt = {
role: "assistant",
text: "РџРѕРєР° РЅРµ РјРѕРіСѓ точно подтвердить, что именно это СС РёРјРµРµС€СЊ РІ РІРёРґСѓ.",
debug: {
execution_lane: "address_query",
detected_intent: "unknown",
answer_grounding_check: {
status: "unsupported"
}
}
} as any;
const policy = buildPolicy({
findLastAddressAssistantItem: () => unsupportedInterrupt,
hasAddressFollowupContextSignal: () => false,
findRecentInventoryRootFrame: () => null,
resolveAddressIntent: () => ({ intent: "unknown" })
});
const carryover = policy.resolveAddressFollowupCarryoverContext(
"ндс можешь прикинуть на дату покупки рабочей станции?",
[provenanceItem, unsupportedInterrupt],
null,
null,
{
session_context: {
active_focus_object: {
object_type: "item",
label: item,
provenance_result_set_id: "rs-provenance-interrupt"
},
active_result_set_id: "rs-provenance-interrupt"
},
result_sets: [
{
result_set_id: "rs-provenance-interrupt",
intent: "inventory_purchase_provenance_for_item",
entity_refs: [
{
index: 1,
entity_type: "item",
value: "Поступление товаров и услуг 00000000023 от 05.02.2015 0:00:00"
}
]
}
]
}
);
expect(carryover?.followupContext?.previous_intent).toBe("inventory_purchase_provenance_for_item");
expect(carryover?.followupContext?.target_intent).toBe("vat_liability_confirmed_for_tax_period");
expect(carryover?.followupContext?.previous_filters).toMatchObject({
item,
organization: 'ООО "Альтернатива Плюс"',
period_from: "2015-02-01",
period_to: "2015-02-28"
});
});
it("drops stale carryover for a fresh standalone topic from another intent family", () => {
const policy = buildPolicy({
findLastAddressAssistantItem: () => ({
text: "Прогноз НДС на март 2020 собран.",
debug: {
detected_intent: "vat_payable_forecast",
extracted_filters: {
period_from: "2020-03-01",
period_to: "2020-03-31"
}
}
}),
hasAddressFollowupContextSignal: () => true,
hasStandaloneAddressTopicSignal: () => true,
resolveAddressIntent: () => ({ intent: "inventory_on_hand_as_of_date" }),
resolveAddressIntentFamily: (intent: unknown) => {
if (String(intent ?? "").startsWith("vat_")) return "vat";
if (String(intent ?? "").startsWith("inventory_")) return "inventory";
return null;
}
});
const carryover = policy.resolveAddressFollowupCarryoverContext(
"остаток на складе за май 2020",
[],
null,
null,
null
);
expect(carryover).toBeNull();
});
it("keeps document intent for short counterparty retarget wording with action verb", () => {
const policy = buildPolicy({
findLastAddressAssistantItem: () => ({
text: "Собран список документов по контрагенту Чапурнов.",
debug: {
detected_intent: "list_documents_by_counterparty",
extracted_filters: {
counterparty: "Чапурнов"
},
anchor_type: "counterparty",
anchor_value_resolved: "Чапурнов"
}
}),
buildAddressFollowupOffer: () => ({
enabled: true,
source_intent: "list_documents_by_counterparty",
suggested_intents: ["bank_operations_by_counterparty"]
}),
isImplicitAddressContinuationByLlm: () => true
});
const carryover = policy.resolveAddressFollowupCarryoverContext("покажи по свк", [], null, null, null);
expect(carryover?.followupContext?.previous_intent).toBe("list_documents_by_counterparty");
expect(carryover?.followupSelectionMode).toBe("carry_previous_intent");
});
it("keeps root-scoped carryover for foreign accounting pivot over inventory drilldown", () => {
const policy = buildPolicy({
findLastAddressAssistantItem: () => ({
text: "Собран sale trace по позиции.",
debug: {
detected_intent: "inventory_sale_trace_for_item",
extracted_filters: {
item: "Кромка с клеем 33 дуб ниагара 137 м",
organization: 'ООО "Альтернатива Плюс"',
as_of_date: "2021-03-31"
},
anchor_type: "item",
anchor_value_resolved: "Кромка с клеем 33 дуб ниагара 137 м"
}
}),
hasAddressFollowupContextSignal: () => true,
resolveAddressIntent: () => ({ intent: "vat_payable_confirmed_as_of_date" }),
resolveAddressIntentFamily: (intent: unknown) => {
if (String(intent ?? "").startsWith("vat_")) return "vat";
if (String(intent ?? "").startsWith("inventory_")) return "inventory";
return null;
},
hasForeignAccountingPivotOverInventoryMessage: () => true,
findRecentInventoryRootFrame: () => ({
intent: "inventory_on_hand_as_of_date",
filters: {
organization: 'ООО "Альтернатива Плюс"',
warehouse: "Основной склад",
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2021-03-31"
},
anchorType: "organization",
anchorValue: 'ООО "Альтернатива Плюс"'
})
});
const carryover = policy.resolveAddressFollowupCarryoverContext("а ндс?", [], null, null, null);
expect(carryover?.followupSelectionMode).toBe("carry_root_context");
expect(carryover?.followupContext?.root_context_only).toBe(true);
expect(carryover?.followupContext?.previous_intent).toBeUndefined();
expect(carryover?.followupContext?.root_intent).toBe("inventory_on_hand_as_of_date");
expect(carryover?.followupContext?.previous_filters).toEqual({
organization: 'ООО "Альтернатива Плюс"',
warehouse: "Основной склад",
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2021-03-31"
});
});
it("prefers the freshest previous date scope over a stale inventory root frame during same-date pivot", () => {
const filters = buildRootScopedCarryoverFilters(
{
organization: 'ООО "Альтернатива Плюс"',
as_of_date: "2020-03-31",
period_from: "2020-03-01",
period_to: "2020-03-31"
},
{
filters: {
organization: 'ООО "Альтернатива Плюс"',
warehouse: "Основной склад",
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2021-03-31"
}
}
);
expect(filters).toEqual({
organization: 'ООО "Альтернатива Плюс"',
warehouse: "Основной склад",
as_of_date: "2020-03-31",
period_from: "2020-03-01",
period_to: "2020-03-31"
});
});
it("does not attach address follow-up carryover to explicit capability-meta questions", () => {
const policy = buildPolicy({
shouldHandleAsAssistantCapabilityMetaQuery: (message: unknown) =>
/дельт[ауы]?\s+по\s+договорам/iu.test(String(message ?? "")),
hasAddressFollowupContextSignal: () => true
});
const carryover = policy.resolveAddressFollowupCarryoverContext(
"ты умеешь считать дельту по договорам?",
[],
"проверить возможность расчета дельты по договорам",
{
predecomposeContract: {
mode: "address_query",
intent: "unknown"
}
},
null
);
expect(carryover).toBeNull();
});
it("retargets selected-object provenance follow-up from inventory root when semantic scope is already detected", () => {
const policy = buildPolicy({
findLastAddressAssistantItem: () => ({
text: "На 31.03.2016 на складе подтверждено 2 позиции.",
debug: {
detected_intent: "inventory_on_hand_as_of_date",
extracted_filters: {
organization: 'ООО "Альтернатива Плюс"',
warehouse: "Основной склад",
as_of_date: "2016-03-31",
period_from: "2016-03-01",
period_to: "2016-03-31"
},
anchor_type: "organization",
anchor_value_resolved: 'ООО "Альтернатива Плюс"'
}
}),
hasAddressFollowupContextSignal: () => true
});
const carryover = policy.resolveAddressFollowupCarryoverContext(
'По выбранному объекту "Рабочая станция универсального специалиста (индивидуальное изготовление)": где взяли это?',
[],
null,
{
predecomposeContract: {
mode: "address_query",
intent: "unknown",
semantics: {
selected_object_scope_detected: true
}
}
},
null
);
expect(carryover?.followupContext?.target_intent).toBe("inventory_purchase_provenance_for_item");
expect(carryover?.followupContext?.previous_filters).toMatchObject({
organization: 'ООО "Альтернатива Плюс"',
item: "Рабочая станция универсального специалиста (индивидуальное изготовление)"
});
expect(carryover?.followupContext?.previous_anchor_type).toBe("item");
});
it("prefers root-frame dates over stale drilldown filters when hydrating previous filters", () => {
const organization = "Org Alt";
const policy = buildPolicy({
findLastAddressAssistantItem: (_items: unknown[]) => ({
text: "Workstation drilldown",
debug: {
detected_intent: "inventory_purchase_documents_for_item",
extracted_filters: {
item: "Workstation",
organization,
as_of_date: "2021-04-15"
},
anchor_type: "item",
anchor_value_resolved: "Workstation",
address_root_frame_context: {
root_intent: "inventory_on_hand_as_of_date",
root_filters: {
organization,
warehouse: "Main Warehouse",
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2021-03-31"
},
root_anchor_type: "organization",
root_anchor_value: organization,
current_frame_kind: "inventory_drilldown"
}
}
}),
findRecentInventoryRootFrame: () => null,
hasInventoryRootTemporalFollowupSignal: (message: string) => /эту же дату/i.test(message)
});
const items = [
{
role: "assistant",
text: "Workstation drilldown",
debug: {
execution_lane: "address_query",
answer_grounding_check: { status: "grounded" },
detected_intent: "inventory_purchase_documents_for_item",
extracted_filters: {
item: "Workstation",
organization,
as_of_date: "2021-04-15"
},
anchor_type: "item",
anchor_value_resolved: "Workstation",
address_root_frame_context: {
root_intent: "inventory_on_hand_as_of_date",
root_filters: {
organization,
warehouse: "Main Warehouse",
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2021-03-31"
},
root_anchor_type: "organization",
root_anchor_value: organization,
current_frame_kind: "inventory_drilldown"
}
}
}
];
const carryover = policy.resolveAddressFollowupCarryoverContext(
"остатки на эту же дату",
items as any,
null,
null,
null
);
expect(carryover?.followupContext?.root_context_only).toBe(true);
expect(carryover?.followupContext?.previous_filters).toMatchObject({
organization,
warehouse: "Main Warehouse",
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2021-03-31"
});
expect(carryover?.followupContext?.previous_filters?.as_of_date).not.toBe("2021-04-15");
});
});