NODEDC_1C/llm_normalizer/backend/tests/assistantContinuityPolicy.t...

628 lines
19 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 {
applyHistoricalPartyCarryoverFilters,
applyOrganizationCarryoverFilters,
applyReferencedEntityCarryover,
applySelectedItemCarryover,
applyTemporalCarryoverFilters,
buildRootScopedCarryoverFilters,
hydrateInventoryRootFrameState,
readAddressDebugCounterparty,
readAddressDebugIntent,
readAddressDebugTemporalScope,
resolveNavigationSessionContextState,
resolveAddressDebugCarryoverFilters,
resolveAddressDebugContextFacts,
resolveAddressDebugAnchorContext,
resolveOrganizationClarificationContinuation,
resolveDisplayedEntityFollowupRetarget,
resolveFollowupTargetIntent,
resolveInventoryFollowupPivotFlags,
resolveAssistantOrganizationAuthority
} from "../src/services/assistantContinuityPolicy";
describe("assistantContinuityPolicy organization authority", () => {
it("prefers explicit assistant organization authority over older grounded continuity and merges known organizations once", () => {
const authority = resolveAssistantOrganizationAuthority({
sessionItems: [
{
role: "assistant",
debug: {
execution_lane: "address_query",
answer_grounding_check: { status: "grounded" },
extracted_filters: {
organization: "Org Grounded",
as_of_date: "2020-03-31"
},
detected_intent: "receivables_confirmed_as_of_date"
}
},
{
role: "assistant",
debug: {
execution_lane: "living_chat",
living_chat_selected_organization: "Org Selected",
assistant_active_organization: "Org Selected",
assistant_known_organizations: ["Org Selected", "Org Known"],
living_chat_data_scope_probe_organizations: ["Org Probe"]
}
}
],
sessionKnownOrganizations: ["Org Session"],
lastOrganizationClarificationDebug: {
organization_candidates: ["Org Candidate", "Org Selected"]
}
});
expect(authority.continuitySnapshot.activeOrganization).toBe("Org Grounded");
expect(authority.continuityActiveOrganization).toBe("Org Selected");
expect(authority.selectedOrganization).toBe("Org Selected");
expect(authority.activeOrganization).toBe("Org Selected");
expect(authority.knownOrganizations).toEqual([
"Org Session",
"Org Selected",
"Org Known",
"Org Probe",
"Org Grounded"
]);
expect(authority.organizationClarificationCandidates).toEqual([
"Org Candidate",
"Org Selected",
"Org Session",
"Org Known",
"Org Probe",
"Org Grounded"
]);
expect(authority.organizationClarificationSelectionFromScope).toBe("Org Selected");
});
it("exposes known organizations as switch candidates even without a prior clarification turn", () => {
const authority = resolveAssistantOrganizationAuthority({
sessionItems: [
{
role: "assistant",
debug: {
execution_lane: "living_chat",
assistant_active_organization: "РАЙМ",
assistant_known_organizations: ['ООО "Альтернатива Плюс"', "РАЙМ"]
}
}
],
sessionKnownOrganizations: ['ООО "Альтернатива Плюс"']
});
expect(authority.activeOrganization).toBe("РАЙМ");
expect(authority.organizationClarificationCandidates).toEqual([
'ООО "Альтернатива Плюс"',
"РАЙМ"
]);
});
it("reads item, organization and scoped date from root-frame fallback when direct filters are missing", () => {
const facts = resolveAddressDebugContextFacts({
anchor_type: "item",
anchor_value_resolved: "Рабочая станция",
address_root_frame_context: {
organization: 'ООО "Альтернатива Плюс"',
as_of_date: "2020-03-31"
}
});
expect(facts).toEqual({
item: "Рабочая станция",
counterparty: null,
organization: 'ООО "Альтернатива Плюс"',
scopedDate: "31.03.2020"
});
});
it("reads counterparty, organization and period from grounded MCP discovery fallback", () => {
const facts = resolveAddressDebugContextFacts({
execution_lane: "living_chat",
mcp_discovery_response_applied: true,
assistant_active_organization: "ООО Альтернатива Плюс",
assistant_mcp_discovery_entry_point_v1: {
schema_version: "assistant_mcp_discovery_runtime_entry_point_v1",
entry_status: "bridge_executed",
turn_input: {
turn_meaning_ref: {
explicit_entity_candidates: ["Группа СВК"],
explicit_organization_scope: "ООО Альтернатива Плюс",
explicit_date_scope: "2020"
}
},
bridge: {
bridge_status: "answer_draft_ready",
business_fact_answer_allowed: true,
answer_draft: {
answer_mode: "confirmed_with_bounded_inference"
}
}
}
});
expect(facts).toEqual({
item: null,
counterparty: "Группа СВК",
organization: "ООО Альтернатива Плюс",
scopedDate: "2020"
});
});
it("hydrates intent and carryover filters from grounded MCP discovery payout scope", () => {
const debug = {
execution_lane: "living_chat",
mcp_discovery_response_applied: true,
assistant_active_organization: "ООО Альтернатива Плюс",
assistant_mcp_discovery_entry_point_v1: {
schema_version: "assistant_mcp_discovery_runtime_entry_point_v1",
entry_status: "bridge_executed",
turn_input: {
turn_meaning_ref: {
asked_action_family: "payout",
explicit_entity_candidates: ["Группа СВК"],
explicit_organization_scope: "ООО Альтернатива Плюс",
explicit_date_scope: "2020"
}
},
bridge: {
bridge_status: "answer_draft_ready",
business_fact_answer_allowed: true,
pilot: {
pilot_scope: "counterparty_supplier_payout_query_movements_v1"
},
answer_draft: {
answer_mode: "confirmed_with_bounded_inference"
}
}
}
};
expect(readAddressDebugIntent(debug)).toBe("supplier_payouts_profile");
expect(readAddressDebugTemporalScope(debug)).toEqual({
asOfDate: null,
periodFrom: "2020-01-01",
periodTo: "2020-12-31"
});
expect(resolveAddressDebugCarryoverFilters(debug)).toEqual({
counterparty: "Группа СВК",
organization: "ООО Альтернатива Плюс",
period_from: "2020-01-01",
period_to: "2020-12-31"
});
});
it("prefers the resolved entity from grounded entity-resolution discovery for counterparty carryover", () => {
const debug = {
execution_lane: "living_chat",
mcp_discovery_response_applied: true,
assistant_mcp_discovery_entry_point_v1: {
schema_version: "assistant_mcp_discovery_runtime_entry_point_v1",
entry_status: "bridge_executed",
turn_input: {
turn_meaning_ref: {
asked_domain_family: "entity_resolution",
asked_action_family: "search_business_entity",
explicit_entity_candidates: ["СВК"]
}
},
bridge: {
bridge_status: "answer_draft_ready",
business_fact_answer_allowed: true,
pilot: {
pilot_scope: "entity_resolution_search_v1",
derived_entity_resolution: {
requested_entity: "СВК",
resolution_status: "resolved",
resolved_entity: "Группа СВК",
ambiguity_candidates: []
}
},
answer_draft: {
answer_mode: "confirmed_with_bounded_inference"
}
}
}
};
expect(readAddressDebugCounterparty(debug)).toBe("Группа СВК");
expect(resolveAddressDebugCarryoverFilters(debug)).toEqual({
counterparty: "Группа СВК"
});
expect(resolveAddressDebugAnchorContext(debug)).toEqual({
anchorType: "counterparty",
anchorValue: "Группа СВК"
});
});
it("resolves navigation session context through one shared helper", () => {
const state = resolveNavigationSessionContextState({
session_context: {
organization_scope: "Org Alt",
active_result_set_id: "rs-42",
date_scope: {
as_of_date: "2020-03-31",
period_from: "2020-03-01",
period_to: "2020-03-31"
},
active_focus_object: {
object_type: "item",
label: "Workstation",
provenance_result_set_id: "rs-focus"
}
}
});
expect(state).toEqual({
organization: "Org Alt",
activeResultSetId: "rs-42",
dateScope: {
as_of_date: "2020-03-31",
period_from: "2020-03-01",
period_to: "2020-03-31"
},
focusObject: {
objectType: "item",
label: "Workstation",
provenanceResultSetId: "rs-focus"
}
});
});
it("resolves organization clarification continuation through one shared helper", () => {
const continuation = resolveOrganizationClarificationContinuation({
rawMessages: ["Альтернатива Плюс", null, " "],
organizationClarificationCandidates: ["ООО Альтернатива Плюс", "РАЙМ"],
organizationClarificationSelectionFromScope: "РАЙМ",
lastOrganizationClarificationDebug: {
organization_candidates: ["ООО Альтернатива Плюс", "РАЙМ"]
},
resolveOrganizationSelectionFromMessage: (message, candidates) =>
/альтернатива/i.test(String(message))
? String(candidates[0] ?? "")
: null
});
expect(continuation).toEqual({
explicitSelection: "ООО Альтернатива Плюс",
selection: "ООО Альтернатива Плюс",
hasContinuation: true
});
});
it("resolves carryover temporal scope and inferred anchor from debug filters when explicit anchor fields are absent", () => {
const debug = {
extracted_filters: {
item: "Рабочая станция",
period_from: "2020-03-01"
},
address_root_frame_context: {
as_of_date: "2020-03-31",
period_to: "2020-03-31"
}
};
expect(readAddressDebugTemporalScope(debug)).toEqual({
asOfDate: "2020-03-31",
periodFrom: "2020-03-01",
periodTo: "2020-03-31"
});
expect(resolveAddressDebugAnchorContext(debug)).toEqual({
anchorType: "item",
anchorValue: "Рабочая станция"
});
});
it("prefers inventory root-frame filters over stale drilldown date scope in carryover filters", () => {
const filters = resolveAddressDebugCarryoverFilters({
detected_intent: "inventory_purchase_documents_for_item",
extracted_filters: {
item: "Workstation",
organization: "Org Alt",
as_of_date: "2021-04-15"
},
address_root_frame_context: {
root_intent: "inventory_on_hand_as_of_date",
root_filters: {
organization: "Org Alt",
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: "Org Alt",
current_frame_kind: "inventory_drilldown"
}
});
expect(filters).toEqual({
item: "Workstation",
organization: "Org Alt",
warehouse: "Main Warehouse",
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2021-03-31"
});
});
it("hydrates inventory root-frame state from navigation scope and preserves derived current frame kind", () => {
const state = hydrateInventoryRootFrameState(
{
intent: "inventory_on_hand_as_of_date",
filters: {
warehouse: "Main Warehouse"
},
anchorType: "organization",
anchorValue: "Org Alt",
currentFrameKind: null
},
"inventory_purchase_documents_for_item",
"Org Alt",
{
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2021-03-31"
},
undefined,
(intent) => String(intent ?? "") === "inventory_purchase_documents_for_item",
(intent) => String(intent ?? "") === "inventory_on_hand_as_of_date"
);
expect(state.currentFrameKind).toBe("inventory_drilldown");
expect(state.inventoryRootFrame).toMatchObject({
currentFrameKind: "inventory_drilldown",
filters: {
organization: "Org Alt",
warehouse: "Main Warehouse",
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2021-03-31"
}
});
});
it("builds root-scoped carryover filters with previous date precedence over inventory root frame", () => {
const filters = buildRootScopedCarryoverFilters(
{
organization: "Org Alt",
as_of_date: "2020-03-31",
period_from: "2020-03-01",
period_to: "2020-03-31"
},
{
filters: {
organization: "Org Alt",
warehouse: "Main Warehouse",
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2021-03-31"
}
}
);
expect(filters).toEqual({
organization: "Org Alt",
warehouse: "Main Warehouse",
as_of_date: "2020-03-31",
period_from: "2020-03-01",
period_to: "2020-03-31"
});
});
it("applies temporal carryover from navigation scope first and falls back to continuity scope", () => {
const filters = applyTemporalCarryoverFilters(
{
organization: "Org Alt"
},
{
as_of_date: "2021-03-31",
period_from: "2021-03-01"
},
{
asOfDate: "2020-12-31",
periodFrom: "2020-12-01",
periodTo: "2020-12-31"
},
"inventory_purchase_documents_for_item"
);
expect(filters).toEqual({
organization: "Org Alt",
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2020-12-31"
});
});
it("does not inject temporal carryover for unrelated intent families", () => {
const filters = applyTemporalCarryoverFilters(
{
organization: "Org Alt"
},
{
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2021-03-31"
},
{
asOfDate: "2020-12-31",
periodFrom: "2020-12-01",
periodTo: "2020-12-31"
},
"list_documents_by_counterparty"
);
expect(filters).toEqual({
organization: "Org Alt"
});
});
it("resolves inventory root pivots through one shared helper", () => {
const flags = resolveInventoryFollowupPivotFlags(
{ intent: "inventory_on_hand_as_of_date" },
"inventory_purchase_documents_for_item",
"inventory_drilldown",
false,
false,
true,
false,
false,
false,
false,
false,
(intent) => String(intent ?? "") === "inventory_purchase_documents_for_item",
(intent) => String(intent ?? "") === "inventory_on_hand_as_of_date"
);
expect(flags).toEqual({
rootScopedPivot: true,
explicitInventorySameDatePivot: false
});
});
it("resolves follow-up target intent precedence through one shared helper", () => {
const targetIntent = resolveFollowupTargetIntent(
false,
null,
null,
"customer_revenue_and_payments",
"carry_root_context",
"inventory_on_hand_as_of_date",
"list_contracts_by_counterparty",
"customer_revenue_and_payments",
false
);
expect(targetIntent).toBe("inventory_on_hand_as_of_date");
});
it("applies organization carryover precedence from historical to shared authority to navigation and clarification", () => {
const filters = applyOrganizationCarryoverFilters(
{},
null,
"Org Authority",
"Org Continuity",
"Org Navigation",
"Org Clarification"
);
expect(filters).toEqual({
organization: "Org Authority"
});
});
it("keeps existing organization and does not overwrite it during organization carryover backfill", () => {
const filters = applyOrganizationCarryoverFilters(
{
organization: "Org Existing"
},
"Org Historical",
"Org Authority",
"Org Continuity",
"Org Navigation",
"Org Clarification"
);
expect(filters).toEqual({
organization: "Org Existing"
});
});
it("backfills historical contract and counterparty only for party-driven follow-up families", () => {
const filters = applyHistoricalPartyCarryoverFilters(
{},
true,
"Contract Legacy",
"Counterparty Legacy"
);
expect(filters).toEqual({
contract: "Contract Legacy",
counterparty: "Counterparty Legacy"
});
});
it("applies referenced entity carryover into filters, anchor, and selection mode", () => {
const carryover = applyReferencedEntityCarryover(
{
organization: "Org Alt"
},
null,
null,
"carry_previous_intent",
{
entityType: "counterparty",
value: "SVK Group"
},
false
);
expect(carryover).toEqual({
previousFilters: {
organization: "Org Alt",
counterparty: "SVK Group"
},
previousAnchorType: "counterparty",
previousAnchorValue: "SVK Group",
followupSelectionMode: "carry_referenced_entity",
resolvedCounterpartyFromDisplay: true
});
});
it("applies selected-item carryover from navigation focus before continuity and explicit labels", () => {
const carryover = applySelectedItemCarryover(
{
organization: "Org Alt"
},
null,
null,
false,
true,
"Workstation Navigation",
"Workstation Continuity",
"Workstation User",
"Workstation Alternate"
);
expect(carryover).toEqual({
previousFilters: {
organization: "Org Alt",
item: "Workstation Navigation"
},
previousAnchorType: "item",
previousAnchorValue: "Workstation Navigation"
});
});
it("resolves displayed-entity follow-up retarget and carryover through one shared helper", () => {
const carryover = resolveDisplayedEntityFollowupRetarget(
"покажи договоры по СВК",
{
entityType: "counterparty",
value: "SVK Group"
},
{
organization: "Org Alt"
},
null,
null,
"carry_previous_intent",
false,
(value) => String(value ?? "").replace(/\s+/g, " ").trim(),
(value) => value
);
expect(carryover).toEqual({
displayedEntityTargetIntent: "list_contracts_by_counterparty",
previousFilters: {
organization: "Org Alt",
counterparty: "SVK Group"
},
previousAnchorType: "counterparty",
previousAnchorValue: "SVK Group",
followupSelectionMode: "carry_referenced_entity",
resolvedCounterpartyFromDisplay: true
});
});
});