Архитектура: централизовать displayed-entity retarget в continuity policy и убрать dead owner из transition
This commit is contained in:
@@ -536,6 +536,122 @@ export function applyReferencedEntityCarryover(
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveDisplayedEntityRetargetIntent(
|
||||
userMessage: unknown,
|
||||
entityType: unknown,
|
||||
compactWhitespace: (value: string) => string,
|
||||
repairAddressMojibake: (value: string) => string
|
||||
): string | null {
|
||||
return resolveDisplayedEntityRetargetIntentUtf8Safe(
|
||||
userMessage,
|
||||
entityType,
|
||||
compactWhitespace,
|
||||
repairAddressMojibake
|
||||
);
|
||||
}
|
||||
|
||||
function resolveDisplayedEntityRetargetIntentUtf8Safe(
|
||||
userMessage: unknown,
|
||||
entityType: unknown,
|
||||
compactWhitespace: (value: string) => string,
|
||||
repairAddressMojibake: (value: string) => string
|
||||
): string | null {
|
||||
const normalized = compactWhitespace(repairAddressMojibake(String(userMessage ?? "")).toLowerCase());
|
||||
if (!normalized) {
|
||||
return null;
|
||||
}
|
||||
if (String(entityType ?? "") === "counterparty") {
|
||||
if (/(?:\u0434\u043e\u0433\u043e\u0432\u043e\u0440|\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442)/iu.test(normalized)) {
|
||||
return "list_contracts_by_counterparty";
|
||||
}
|
||||
if (
|
||||
/(?:\u0431\u0430\u043d\u043a|\u0432\u044b\u043f\u0438\u0441\u043a|\u043f\u043b\u0430\u0442[\u0435\u0451]\u0436|\u043e\u043f\u043b\u0430\u0442|statement|payment|wire)/iu.test(
|
||||
normalized
|
||||
)
|
||||
) {
|
||||
return "bank_operations_by_counterparty";
|
||||
}
|
||||
if (
|
||||
/(?:\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\u043d\u0430\u043a\u043b\u0430\u0434\u043d|\u0441\u0447\u0435\u0442|\u0441\u0447[\u0435\u0451]\u0442|\u0430\u043a\u0442|\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446|\u043f\u043e\u0441\u0442\u0443\u043f\u043b)/iu.test(
|
||||
normalized
|
||||
)
|
||||
) {
|
||||
return "list_documents_by_counterparty";
|
||||
}
|
||||
if (
|
||||
/(?:\u0441\u043a\u043e\u043b\u044c\u043a\u043e\s+\u0434\u0435\u043d\u0435\u0433|\u0441\u043a\u043e\u043b\u044c\u043a\u043e\s+\u043f\u0440\u0438\u043d\u0435\u0441|\u0432\u044b\u0440\u0443\u0447\u043a|\u0441\u0443\u043c\u043c[\u0430\u044b]?|\u043e\u043f\u043b\u0430\u0442\u0438\u043b|\u043f\u0440\u043e\u0434\u0430\u0436)/iu.test(
|
||||
normalized
|
||||
)
|
||||
) {
|
||||
return "customer_revenue_and_payments";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (String(entityType ?? "") === "contract") {
|
||||
if (
|
||||
/(?:\u0431\u0430\u043d\u043a|\u0432\u044b\u043f\u0438\u0441\u043a|\u043f\u043b\u0430\u0442[\u0435\u0451]\u0436|\u043e\u043f\u043b\u0430\u0442|statement|payment|wire)/iu.test(
|
||||
normalized
|
||||
)
|
||||
) {
|
||||
return "bank_operations_by_contract";
|
||||
}
|
||||
if (
|
||||
/(?:\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\u043d\u0430\u043a\u043b\u0430\u0434\u043d|\u0441\u0447\u0435\u0442|\u0441\u0447[\u0435\u0451]\u0442|\u0430\u043a\u0442|\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446|\u043f\u043e\u0441\u0442\u0443\u043f\u043b)/iu.test(
|
||||
normalized
|
||||
)
|
||||
) {
|
||||
return "list_documents_by_contract";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function resolveDisplayedEntityFollowupRetarget(
|
||||
userMessage: unknown,
|
||||
resolvedEntityFromFollowup:
|
||||
| {
|
||||
entityType?: unknown;
|
||||
value?: unknown;
|
||||
}
|
||||
| null
|
||||
| undefined,
|
||||
previousFilters: Record<string, unknown> | null,
|
||||
previousAnchorType: string | null,
|
||||
previousAnchorValue: string | null,
|
||||
followupSelectionMode: string | null,
|
||||
rootScopedPivot: boolean,
|
||||
compactWhitespace: (value: string) => string,
|
||||
repairAddressMojibake: (value: string) => string,
|
||||
toNonEmptyString: (value: unknown) => string | null = fallbackToNonEmptyString
|
||||
): {
|
||||
displayedEntityTargetIntent: string | null;
|
||||
previousFilters: Record<string, unknown>;
|
||||
previousAnchorType: string | null;
|
||||
previousAnchorValue: string | null;
|
||||
followupSelectionMode: string | null;
|
||||
resolvedCounterpartyFromDisplay: boolean;
|
||||
} {
|
||||
const displayedEntityTargetIntent = resolveDisplayedEntityRetargetIntentUtf8Safe(
|
||||
userMessage,
|
||||
resolvedEntityFromFollowup?.entityType,
|
||||
compactWhitespace,
|
||||
repairAddressMojibake
|
||||
);
|
||||
const carryover = applyReferencedEntityCarryover(
|
||||
previousFilters,
|
||||
previousAnchorType,
|
||||
previousAnchorValue,
|
||||
followupSelectionMode,
|
||||
resolvedEntityFromFollowup,
|
||||
rootScopedPivot,
|
||||
toNonEmptyString
|
||||
);
|
||||
return {
|
||||
displayedEntityTargetIntent,
|
||||
...carryover
|
||||
};
|
||||
}
|
||||
|
||||
export function applySelectedItemCarryover(
|
||||
previousFilters: Record<string, unknown> | null,
|
||||
previousAnchorType: string | null,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import {
|
||||
applyHistoricalPartyCarryoverFilters,
|
||||
applyOrganizationCarryoverFilters,
|
||||
applyReferencedEntityCarryover,
|
||||
applySelectedItemCarryover,
|
||||
applyTemporalCarryoverFilters,
|
||||
buildRootScopedCarryoverFilters,
|
||||
@@ -13,6 +12,7 @@ import {
|
||||
readAddressDebugTemporalScope,
|
||||
resolveAddressDebugCarryoverFilters,
|
||||
resolveAddressDebugAnchorContext,
|
||||
resolveDisplayedEntityFollowupRetarget,
|
||||
resolveAssistantOrganizationAuthority
|
||||
} from "./assistantContinuityPolicy";
|
||||
|
||||
@@ -364,39 +364,6 @@ export function createAssistantTransitionPolicy(deps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function resolveDisplayedEntityRetargetIntent(userMessage, entityType) {
|
||||
const normalized = deps.compactWhitespace(
|
||||
deps.repairAddressMojibake(String(userMessage ?? "")).toLowerCase()
|
||||
);
|
||||
if (!normalized) {
|
||||
return null;
|
||||
}
|
||||
if (entityType === "counterparty") {
|
||||
if (/(?:договор|контракт)/iu.test(normalized)) {
|
||||
return "list_contracts_by_counterparty";
|
||||
}
|
||||
if (/(?:банк|выписк|плат[её]ж|оплат|statement|payment|wire)/iu.test(normalized)) {
|
||||
return "bank_operations_by_counterparty";
|
||||
}
|
||||
if (/(?:документ|накладн|счет|сч[её]т|акт|реализац|поступл)/iu.test(normalized)) {
|
||||
return "list_documents_by_counterparty";
|
||||
}
|
||||
if (/(?:сколько\s+денег|сколько\s+принес|выручк|сумм[аы]?|оплатил|продаж)/iu.test(normalized)) {
|
||||
return "customer_revenue_and_payments";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (entityType === "contract") {
|
||||
if (/(?:банк|выписк|плат[её]ж|оплат|statement|payment|wire)/iu.test(normalized)) {
|
||||
return "bank_operations_by_contract";
|
||||
}
|
||||
if (/(?:документ|накладн|счет|сч[её]т|акт|реализац|поступл)/iu.test(normalized)) {
|
||||
return "list_documents_by_contract";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function resolveAddressFollowupCarryoverContext(
|
||||
userMessage,
|
||||
items,
|
||||
@@ -854,25 +821,23 @@ export function createAssistantTransitionPolicy(deps) {
|
||||
(deps.toNonEmptyString(alternateMessage)
|
||||
? deps.resolveDisplayedAddressEntityMention(String(alternateMessage ?? ""), displayedEntities)
|
||||
: null);
|
||||
if (resolvedEntityFromFollowup && !rootScopedPivot) {
|
||||
displayedEntityTargetIntent = resolveDisplayedEntityRetargetIntent(
|
||||
userMessage,
|
||||
resolvedEntityFromFollowup.entityType
|
||||
);
|
||||
}
|
||||
({
|
||||
displayedEntityTargetIntent,
|
||||
previousFilters,
|
||||
previousAnchorType,
|
||||
previousAnchorValue: previousAnchor,
|
||||
followupSelectionMode,
|
||||
resolvedCounterpartyFromDisplay
|
||||
} = applyReferencedEntityCarryover(
|
||||
} = resolveDisplayedEntityFollowupRetarget(
|
||||
userMessage,
|
||||
resolvedEntityFromFollowup,
|
||||
previousFilters,
|
||||
previousAnchorType,
|
||||
previousAnchor,
|
||||
followupSelectionMode,
|
||||
resolvedEntityFromFollowup,
|
||||
rootScopedPivot,
|
||||
deps.compactWhitespace,
|
||||
deps.repairAddressMojibake,
|
||||
deps.toNonEmptyString
|
||||
));
|
||||
({
|
||||
|
||||
Reference in New Issue
Block a user