NODEDC_1C/llm_normalizer/backend/dist/services/assistantMcpDiscoveryTurnIn...

2223 lines
132 KiB
JavaScript
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.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ASSISTANT_MCP_DISCOVERY_TURN_INPUT_SCHEMA_VERSION = void 0;
exports.buildAssistantMcpDiscoveryTurnInput = buildAssistantMcpDiscoveryTurnInput;
const assistantMcpDiscoveryDataNeedGraph_1 = require("./assistantMcpDiscoveryDataNeedGraph");
const addressTextRepair_1 = require("./addressTextRepair");
exports.ASSISTANT_MCP_DISCOVERY_TURN_INPUT_SCHEMA_VERSION = "assistant_mcp_discovery_turn_input_v1";
function toRecordObject(value) {
if (!value || typeof value !== "object" || Array.isArray(value)) {
return null;
}
return value;
}
function toNonEmptyString(value) {
if (value === null || value === undefined) {
return null;
}
const text = String(value).trim();
return text.length > 0 ? text : null;
}
function normalizeReasonCode(value) {
const normalized = value
.trim()
.replace(/[^\p{L}\p{N}_.:-]+/gu, "_")
.replace(/^_+|_+$/g, "")
.toLowerCase();
return normalized.length > 0 ? normalized.slice(0, 120) : null;
}
function pushReason(target, value) {
const normalized = normalizeReasonCode(value);
if (normalized && !target.includes(normalized)) {
target.push(normalized);
}
}
function pushUnique(target, value) {
const text = toNonEmptyString(value);
if (text && !target.includes(text)) {
target.push(text);
}
}
function isReferentialEntityPlaceholder(value) {
return new Set([
"он",
"она",
"оно",
"они",
"ему",
"ней",
"нему",
"ним",
"ними",
"его",
"ее",
"их",
"этому",
"этой",
"этим",
"этими",
"этом"
]).has((0, addressTextRepair_1.normalizeRussianComparableText)(value));
}
function isReferentialOrganizationPlaceholder(value) {
if (!value) {
return false;
}
return new Set([
"эта организация",
"этой организации",
"этой организацией",
"эту организацию",
"эта компания",
"этой компании",
"этой компанией",
"эту компанию",
"наша организация",
"нашей организации",
"нашей компанией"
]).has((0, addressTextRepair_1.normalizeRussianComparableText)(value));
}
function isValueFlowPredicateEntityCandidate(value) {
if (!value) {
return false;
}
const text = compactLower(value);
const looksLikeRankingPredicate = /(?:прин[её]с|принес|выручк|доходн|больше\s+всего|наибольш)/iu.test(text) &&
/(?:организац|компан|ден[её]г|выручк|поступлен|плат[её]ж)/iu.test(text);
if (!looksLikeRankingPredicate) {
return false;
}
return !/(?<!\p{L})(?:ооо|ип|ао|пао|зао|llc|inc|corp)(?!\p{L})/iu.test(text);
}
function isActionVerbEntityCandidate(value) {
if (!value) {
return false;
}
return new Set(["провести", "показать", "посмотреть", "смотреть", "найти", "искать", "анализ"]).has((0, addressTextRepair_1.normalizeRussianComparableText)(value));
}
function isGarbageSemanticAnchorCandidate(value) {
if (!value) {
return false;
}
const text = compactLower((0, addressTextRepair_1.repairAddressMojibakeText)(value));
if (!text || text.length < 2) {
return true;
}
const compact = (0, addressTextRepair_1.normalizeRussianComparableText)(text);
if (new Set([
"для",
"по",
"ему",
"нему",
"ней",
"этой",
"этому",
"этим",
"этими",
"данным",
"данными",
"документам",
"документами",
"движение",
"движения",
"движениям",
"операциям",
"данным",
"этим",
"этими",
"итогу",
"итогам",
"всему",
"всей",
"всем",
"год",
"года",
"году",
"годом",
"годы",
"выводу",
"выводам",
"аудиту",
"прокси",
"proxy",
"summary",
"overall",
"деньги",
"денег",
"деньгам",
"деньгами",
"ооо",
"ип",
"ао",
"пао",
"зао",
"llc",
"inc",
"corp",
"документам",
"документами",
"движение",
"движения",
"движениям",
"операциям",
"проверить",
"проверь",
"видно"
]).has(compact)) {
return true;
}
if (/^(?:по\s+)?(?:этим|этими)\s+данн\p{L}*$/iu.test(text) ||
/^(?:и\s+)?кто\s+(?:главн\p{L}*|основн\p{L}*|крупн\p{L}*)\s+(?:клиент|покупател|поставщик|контрагент)(?:\s+в)?$/iu.test(text) ||
/^(?:или\s+)?(?:обычн\p{L}*\s+)?(?:клиент|поставщик|покупател\p{L}*|заказчик|контрагент)(?:\s+или\s+(?:клиент|поставщик|покупател\p{L}*|заказчик|контрагент))?$/iu.test(text) ||
/^(?:что|чего)\s+(?:подтвержден\p{L}*|не\s+хватает)/iu.test(text) ||
/^(?:можно\s+ли|если\s+нет|дай\s+proxy|дай\s+прокси)/iu.test(text)) {
return true;
}
return false;
}
function isInvalidEntityCandidate(value) {
return Boolean(value &&
(isReferentialEntityPlaceholder(value) ||
isValueFlowPredicateEntityCandidate(value) ||
isActionVerbEntityCandidate(value) ||
isGarbageSemanticAnchorCandidate(value)));
}
function normalizeFollowupCounterpartyCandidate(value) {
const text = candidateValue(value);
if (!text || isInvalidEntityCandidate(text)) {
return null;
}
return text;
}
function pushScopedEntityCandidate(target, value, groundedFollowupEntity) {
const text = candidateValue(value);
if (!text) {
return;
}
if (isInvalidEntityCandidate(text) ||
(groundedFollowupEntity && isReferentialEntityPlaceholder(text)) ||
isValueFlowPredicateEntityCandidate(text)) {
return;
}
if (target.some((existing) => sameScopedName(existing, text))) {
return;
}
pushUnique(target, text);
}
function canonicalizeEntityResolutionCandidate(value) {
return normalizeEntityResolutionCandidate(value)
.replace(/^(?:\u0441\s+\u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435\u043c\s+)/iu, "")
.replace(/\s+(?:\u0432\s+\u0441\u0438\u0441\u0442\u0435\u043c\u0435\s*1\u0421|\u0432\s+1c|in\s+(?:the\s+)?1c\s+system|in\s+1c)\s*$/iu, "")
.trim();
}
function pushNormalizedEntityResolutionCandidate(target, value) {
const text = toNonEmptyString(value);
if (!text) {
return;
}
const normalized = canonicalizeEntityResolutionCandidate(text);
if (normalized && !isInvalidEntityCandidate(normalized) && !target.includes(normalized)) {
target.push(normalized);
}
}
function compactLower(value) {
return String(value ?? "")
.toLowerCase()
.replace(/\s+/g, " ")
.trim();
}
function sameScopedName(left, right) {
return Boolean(left && right && compactLower(left) === compactLower(right));
}
function preferredScopedDisplayName(value, candidates) {
const anchor = toNonEmptyString(value);
if (!anchor) {
return null;
}
for (const candidate of candidates) {
const text = candidateValue(candidate);
if (sameScopedName(text, anchor)) {
return text;
}
}
return anchor;
}
function candidateValue(value) {
const direct = toNonEmptyString(value);
if (direct && direct !== "[object Object]") {
return direct;
}
const record = toRecordObject(value);
if (!record) {
return null;
}
return (toNonEmptyString(record.value) ??
toNonEmptyString(record.name) ??
toNonEmptyString(record.ref) ??
toNonEmptyString(record.text));
}
function collectEntityCandidates(value) {
const result = [];
if (Array.isArray(value)) {
for (const item of value) {
const candidate = candidateValue(item);
if (!isInvalidEntityCandidate(candidate)) {
pushUnique(result, candidate);
}
}
return result;
}
const candidate = candidateValue(value);
if (!isInvalidEntityCandidate(candidate)) {
pushUnique(result, candidate);
}
return result;
}
function collectPredecomposeEntities(predecompose) {
const entities = toRecordObject(predecompose?.entities);
const organization = toNonEmptyString(entities?.organization);
return {
counterparty: toNonEmptyString(entities?.counterparty),
organization: isReferentialOrganizationPlaceholder(organization) ? null : organization
};
}
function collectDateScope(predecompose) {
const period = toRecordObject(predecompose?.period);
const asOfDate = toNonEmptyString(period?.as_of_date);
const periodFrom = toNonEmptyString(period?.period_from);
const periodTo = toNonEmptyString(period?.period_to);
if (asOfDate) {
return asOfDate;
}
const yearFrom = periodFrom?.match(/^(\d{4})-01-01$/);
const yearTo = periodTo?.match(/^(\d{4})-12-31$/);
if (yearFrom && yearTo && yearFrom[1] === yearTo[1]) {
return yearFrom[1];
}
if (periodFrom && periodTo) {
return `${periodFrom}..${periodTo}`;
}
return periodFrom ?? periodTo ?? null;
}
function collectDateScopeFromFilters(filters) {
if (!filters) {
return null;
}
const asOfDate = toNonEmptyString(filters.as_of_date);
const periodFrom = toNonEmptyString(filters.period_from);
const periodTo = toNonEmptyString(filters.period_to);
if (asOfDate) {
return asOfDate;
}
const yearFrom = periodFrom?.match(/^(\d{4})-01-01$/);
const yearTo = periodTo?.match(/^(\d{4})-12-31$/);
if (yearFrom && yearTo && yearFrom[1] === yearTo[1]) {
return yearFrom[1];
}
if (periodFrom && periodTo) {
return `${periodFrom}..${periodTo}`;
}
return periodFrom ?? periodTo ?? null;
}
function normalizeMetadataRouteFamily(value) {
const text = toNonEmptyString(value);
if (text === "document_evidence" || text === "movement_evidence" || text === "catalog_drilldown") {
return text;
}
return null;
}
function normalizeMetadataRecommendedPrimitive(value) {
const text = toNonEmptyString(value);
if (text === "query_documents" || text === "query_movements" || text === "drilldown_related_objects") {
return text;
}
return null;
}
function normalizeMetadataRouteFamilySelectionBasis(value) {
const text = toNonEmptyString(value);
return text === "selected_entity_set" || text === "dominant_surface_objects" ? text : null;
}
function mapPilotScopeToFollowupMeaning(pilotScope) {
if (pilotScope === "counterparty_lifecycle_query_documents_v1") {
return {
domain: "counterparty_lifecycle",
action: "activity_duration",
unsupported: "counterparty_lifecycle"
};
}
if (pilotScope === "counterparty_movement_evidence_query_movements_v1") {
return {
domain: "movements",
action: "list_movements",
unsupported: "movement_evidence"
};
}
if (pilotScope === "counterparty_document_evidence_query_documents_v1") {
return {
domain: "documents",
action: "list_documents",
unsupported: "document_evidence"
};
}
if (pilotScope === "counterparty_supplier_payout_query_movements_v1") {
return {
domain: "counterparty_value",
action: "payout",
unsupported: "counterparty_payouts_or_outflow"
};
}
if (pilotScope === "counterparty_value_flow_query_movements_v1") {
return {
domain: "counterparty_value",
action: "turnover",
unsupported: "counterparty_value_or_turnover"
};
}
if (pilotScope === "counterparty_bidirectional_value_flow_query_movements_v1") {
return {
domain: "counterparty_value",
action: "net_value_flow",
unsupported: "counterparty_bidirectional_value_flow_or_netting"
};
}
if (pilotScope === "metadata_inspection_v1") {
return {
domain: "metadata",
action: "inspect_catalog",
unsupported: "1c_metadata_surface"
};
}
if (pilotScope === "business_overview_route_template_v1") {
return {
domain: "business_overview",
action: "broad_evaluation",
unsupported: "broad_business_evaluation"
};
}
return {
domain: null,
action: null,
unsupported: null
};
}
function mapAddressIntentToFollowupMeaning(intent) {
if (intent === "counterparty_activity_lifecycle") {
return {
domain: "counterparty_lifecycle",
action: "activity_duration",
unsupported: "counterparty_lifecycle"
};
}
if (intent === "supplier_payouts_profile") {
return {
domain: "counterparty_value",
action: "payout",
unsupported: "counterparty_payouts_or_outflow"
};
}
if (intent === "customer_revenue_and_payments") {
return {
domain: "counterparty_value",
action: "turnover",
unsupported: "counterparty_value_or_turnover"
};
}
if (intent === "bank_operations_by_counterparty") {
return {
domain: "movements",
action: "list_movements",
unsupported: "movement_evidence"
};
}
return {
domain: null,
action: null,
unsupported: null
};
}
function mapLoopClarificationSeedToFollowupMeaning(input) {
if (input.domain || input.action || input.unsupported) {
return {
domain: input.domain,
action: input.action,
unsupported: input.unsupported
};
}
if (input.selectedChainId === "metadata_lane_clarification") {
return {
domain: "metadata",
action: "resolve_next_lane",
unsupported: "metadata_lane_choice_clarification"
};
}
return {
domain: null,
action: null,
unsupported: null
};
}
function pilotScopeFromLoopClarificationSeed(selectedChainId, action) {
if (!selectedChainId) {
return null;
}
if (selectedChainId === "metadata_inspection" ||
selectedChainId === "metadata_lane_clarification" ||
selectedChainId === "catalog_drilldown") {
return "metadata_inspection_v1";
}
if (selectedChainId === "movement_evidence") {
return "counterparty_movement_evidence_query_movements_v1";
}
if (selectedChainId === "document_evidence") {
return "counterparty_document_evidence_query_documents_v1";
}
if (selectedChainId === "lifecycle") {
return "counterparty_lifecycle_query_documents_v1";
}
if (selectedChainId === "entity_resolution") {
return "entity_resolution_search_v1";
}
if (selectedChainId === "value_flow_comparison") {
return "counterparty_bidirectional_value_flow_query_movements_v1";
}
if (selectedChainId === "value_flow_ranking" || selectedChainId === "value_flow") {
if (action === "payout") {
return "counterparty_supplier_payout_query_movements_v1";
}
if (action === "net_value_flow") {
return "counterparty_bidirectional_value_flow_query_movements_v1";
}
return "counterparty_value_flow_query_movements_v1";
}
return null;
}
function collectFollowupDiscoverySeed(followupContext) {
const previousFilters = toRecordObject(followupContext?.previous_filters);
const rootFilters = toRecordObject(followupContext?.root_filters);
const pilotScope = toNonEmptyString(followupContext?.previous_discovery_pilot_scope);
const loopStatus = toNonEmptyString(followupContext?.previous_discovery_loop_status);
const loopSelectedChainId = toNonEmptyString(followupContext?.previous_discovery_loop_selected_chain_id);
const loopPendingAxes = collectEntityCandidates(followupContext?.previous_discovery_loop_pending_axes);
const loopProvidedAxes = collectEntityCandidates(followupContext?.previous_discovery_loop_provided_axes);
const loopAskedDomainFamily = toNonEmptyString(followupContext?.previous_discovery_loop_asked_domain_family);
const loopAskedActionFamily = toNonEmptyString(followupContext?.previous_discovery_loop_asked_action_family);
const loopUnsupportedFamily = toNonEmptyString(followupContext?.previous_discovery_loop_unsupported_family);
const loopMetadataScopeHint = toNonEmptyString(followupContext?.previous_discovery_loop_metadata_scope_hint);
const loopSubjectResolutionOptional = followupContext?.previous_discovery_loop_subject_resolution_optional === true;
const previousIntent = toNonEmptyString(followupContext?.target_intent) ?? toNonEmptyString(followupContext?.previous_intent);
const loopMapped = loopStatus === "awaiting_clarification"
? mapLoopClarificationSeedToFollowupMeaning({
selectedChainId: loopSelectedChainId,
domain: loopAskedDomainFamily,
action: loopAskedActionFamily,
unsupported: loopUnsupportedFamily
})
: {
domain: null,
action: null,
unsupported: null
};
const effectivePilotScope = pilotScope ?? pilotScopeFromLoopClarificationSeed(loopSelectedChainId, loopMapped.action);
const mapped = loopMapped.domain !== null || loopMapped.action !== null || loopMapped.unsupported !== null
? loopMapped
: mapPilotScopeToFollowupMeaning(effectivePilotScope).domain !== null
? mapPilotScopeToFollowupMeaning(effectivePilotScope)
: mapAddressIntentToFollowupMeaning(previousIntent);
const discoveryEntities = collectEntityCandidates(followupContext?.previous_discovery_entity_candidates);
const entityResolutionStatus = toNonEmptyString(followupContext?.previous_discovery_entity_resolution_status);
const entityResolutionAmbiguityCandidates = collectEntityCandidates(followupContext?.previous_discovery_entity_ambiguity_candidates);
const ambiguityBlocksImplicitGrounding = effectivePilotScope === "entity_resolution_search_v1" && entityResolutionStatus === "ambiguous";
const metadataPilotCarriesScopeOnly = effectivePilotScope === "metadata_inspection_v1" || loopSubjectResolutionOptional;
const normalizedDiscoveryEntities = discoveryEntities
.map((entity) => normalizeFollowupCounterpartyCandidate(entity))
.filter((entity) => Boolean(entity));
const groundedDiscoveryCounterparty = ambiguityBlocksImplicitGrounding || metadataPilotCarriesScopeOnly
? null
: normalizedDiscoveryEntities[0] ?? normalizeFollowupCounterpartyCandidate(loopMetadataScopeHint);
const metadataScopeHint = loopMetadataScopeHint ??
(loopSubjectResolutionOptional ? normalizedDiscoveryEntities[0] ?? null : null);
const previousFiltersCounterparty = normalizeFollowupCounterpartyCandidate(previousFilters?.counterparty);
const rootFiltersCounterparty = normalizeFollowupCounterpartyCandidate(rootFilters?.counterparty);
const previousAnchorCounterparty = toNonEmptyString(followupContext?.previous_anchor_type) === "counterparty"
? normalizeFollowupCounterpartyCandidate(followupContext?.previous_anchor_value)
: null;
const counterparty = groundedDiscoveryCounterparty
? groundedDiscoveryCounterparty
: previousFiltersCounterparty ?? rootFiltersCounterparty ?? previousAnchorCounterparty;
const organization = toNonEmptyString(previousFilters?.organization) ??
toNonEmptyString(rootFilters?.organization) ??
(toNonEmptyString(followupContext?.previous_anchor_type) === "organization"
? toNonEmptyString(followupContext?.previous_anchor_value)
: null);
const dateScope = collectDateScopeFromFilters(previousFilters) ??
collectDateScopeFromFilters(rootFilters);
return {
pilotScope: effectivePilotScope,
domain: mapped.domain,
action: mapped.action,
unsupported: mapped.unsupported,
loopStatus,
loopSelectedChainId,
loopPendingAxes,
loopProvidedAxes,
counterparty,
discoveryEntity: ambiguityBlocksImplicitGrounding || loopSubjectResolutionOptional ? null : normalizedDiscoveryEntities[0] ?? null,
entityResolutionStatus,
entityResolutionAmbiguityCandidates,
rankingNeed: toNonEmptyString(followupContext?.previous_discovery_ranking_need),
organization,
dateScope,
metadataScopeHint,
subjectResolutionOptional: loopSubjectResolutionOptional,
metadataRouteFamily: normalizeMetadataRouteFamily(followupContext?.previous_discovery_metadata_route_family),
metadataRouteFamilySelectionBasis: normalizeMetadataRouteFamilySelectionBasis(followupContext?.previous_discovery_metadata_route_family_selection_basis),
metadataSelectedEntitySet: toNonEmptyString(followupContext?.previous_discovery_metadata_selected_entity_set),
metadataSelectedSurfaceObjects: collectEntityCandidates(followupContext?.previous_discovery_metadata_selected_surface_objects),
metadataRecommendedNextPrimitive: normalizeMetadataRecommendedPrimitive(followupContext?.previous_discovery_metadata_recommended_next_primitive),
metadataAmbiguityDetected: followupContext?.previous_discovery_metadata_ambiguity_detected === true,
metadataAmbiguityEntitySets: collectEntityCandidates(followupContext?.previous_discovery_metadata_ambiguity_entity_sets),
previousBidirectionalValueFlow: toRecordObject(followupContext?.previous_discovery_bidirectional_value_flow),
previousDocumentSummary: toRecordObject(followupContext?.previous_discovery_document_summary)
};
}
function buildMetadataSurfaceRef(followupSeed) {
if (followupSeed.pilotScope !== "metadata_inspection_v1") {
return null;
}
const hasPayload = Boolean(followupSeed.metadataRouteFamily ||
followupSeed.metadataSelectedEntitySet ||
followupSeed.metadataRecommendedNextPrimitive ||
followupSeed.metadataRouteFamilySelectionBasis) ||
followupSeed.metadataSelectedSurfaceObjects.length > 0 ||
followupSeed.metadataAmbiguityDetected ||
followupSeed.metadataAmbiguityEntitySets.length > 0;
if (!hasPayload) {
return null;
}
return {
selected_entity_set: followupSeed.metadataSelectedEntitySet,
selected_surface_objects: followupSeed.metadataSelectedSurfaceObjects,
downstream_route_family: followupSeed.metadataRouteFamily,
route_family_selection_basis: followupSeed.metadataRouteFamilySelectionBasis,
recommended_next_primitive: followupSeed.metadataRecommendedNextPrimitive,
ambiguity_detected: followupSeed.metadataAmbiguityDetected,
ambiguity_entity_sets: followupSeed.metadataAmbiguityEntitySets
};
}
function metadataEntitySetsSuggestDocumentLane(values) {
return values.some((value) => /(?:документ|document|invoice|waybill|накладн|счет[- ]?фактур|акт)/iu.test(value));
}
function metadataEntitySetsSuggestMovementLane(values) {
return values.some((value) => /(?:регистр|register|movement|движени|операц|проводк|bank)/iu.test(value));
}
function metadataAmbiguityCollapsesToDocumentLane(values) {
return values.length > 0 && metadataEntitySetsSuggestDocumentLane(values) && !metadataEntitySetsSuggestMovementLane(values);
}
function metadataAmbiguityCollapsesToMovementLane(values) {
return values.length > 0 && metadataEntitySetsSuggestMovementLane(values) && !metadataEntitySetsSuggestDocumentLane(values);
}
function hasLifecycleSignal(text) {
return /(?:сколько\s+лет|как\s+давно|давно\s+ли|возраст|перв(?:ая|ый)\s+актив|когда\s+начал|когда\s+появ|lifecycle|activity\s+duration|business\s+age|how\s+long)/iu.test(text);
}
function hasExplicitCounterpartyValueObject(text) {
return /(?:\u043a\u043b\u0438\u0435\u043d\u0442|\u043f\u043e\u043a\u0443\u043f\u0430\u0442\u0435\u043b|\u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442|\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a|\u0434\u043e\u0433\u043e\u0432\u043e\u0440|\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442|\u0442\u043e\u0432\u0430\u0440|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442\u0443\u0440|\u0441\u0434\u0435\u043b\u043a|customer|client|counterparty|supplier|vendor|contract|item|product|deal)/iu.test(text);
}
function hasOrganizationLevelEarningsOverviewSignal(text) {
if (!text || hasExplicitCounterpartyValueObject(text)) {
return false;
}
const hasYearRankingCue = /(?:(?:\u043a\u0430\u043a\u043e\u0439|\u043a\u0430\u043a\u0438\u0435|\u043a\u0430\u043a\u0430\u044f|what|which)\s+(?:\u0443\s+\u043d\u0430\u0441\s+)?(?:[\p{L}0-9._-]+\s+){0,4}(?:\u0441\u0430\u043c|\u0441\u0430\u043c\u044b\u0435|best|top|most)[\s\S]{0,80}(?:\u0434\u043e\u0445\u043e\u0434\u043d|\u043f\u0440\u0438\u0431\u044b\u043b|\u0432\u044b\u0440\u0443\u0447\u043a|\u043e\u0431\u043e\u0440\u043e\u0442|revenue|profit|turnover)[\s\S]{0,40}(?:\u0433\u043e\u0434|year)|(?:\u0434\u043e\u0445\u043e\u0434\u043d|\u043f\u0440\u0438\u0431\u044b\u043b|\u0432\u044b\u0440\u0443\u0447\u043a|\u043e\u0431\u043e\u0440\u043e\u0442|revenue|profit|turnover)[\s\S]{0,60}(?:\u0441\u0430\u043c|\u0441\u0430\u043c\u044b\u0435|best|top|most)[\s\S]{0,40}(?:\u0433\u043e\u0434|year))/iu.test(text);
const hasCompanyEarningsCue = /(?:(?:\u0441\u043a\u043e\u043b\u044c\u043a\u043e|\u0441\u043a\u043e\u043a\w*|how\s+much)[\s\S]{0,120}(?:\u0437\u0430\u0440\u0430\u0431\u043e\u0442|\u0432\u044b\u0440\u0443\u0447)|(?:\u0437\u0430\u0440\u0430\u0431\u043e\u0442|\u0432\u044b\u0440\u0443\u0447)[\s\S]{0,80}(?:\u0437\u0430\s+(?:\u0432\u0441\u0435\s+\u0432\u0440\u0435\u043c\u044f|\d{2,4}\s*\u0433\u043e\u0434|(?:19|20)\d{2})|all\s+time|\b(?:19|20)\d{2}\b)|(?:\u043e\u0431\u0449\w*\s+(?:\u043e\u0431\u043e\u0440\u043e\u0442|\u0432\u044b\u0440\u0443\u0447\u043a)|(?:\u043e\u0431\u043e\u0440\u043e\u0442|\u0432\u044b\u0440\u0443\u0447\u043a)[\s\S]{0,40}\u0437\u0430\s+\u0432\u0441\u0435\s+\u0432\u0440\u0435\u043c\u044f))/iu.test(text);
const hasCompanyProfitMarginCue = /(?:\u043f\u0440\u0438\u0431\u044b\u043b\w*|\u043c\u0430\u0440\u0436\w*|\u0440\u0435\u043d\u0442\u0430\u0431\w*|\u0444\u0438\u043d(?:\u0430\u043d\u0441\w*)?\s*[- ]?\s*\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442|p\s*&\s*l|profit(?:ability)?|margin|financial\s+result)/iu.test(text) &&
/(?:\u043a\u0430\u043a\w*|\u0441\u043a\u043e\u043b\u044c\u043a\u043e|\u0441\u043a\u043e\u043a\w*|\u043f\u043e\u043a\u0430\u0436|\u0434\u0430\u0439|\u0443\s+\u043d\u0430\u0441|\u043d\u0430\u0448\w*|\u043c\u044b\b|\u043a\u043e\u043c\u043f\u0430\u043d|\u0431\u0438\u0437\u043d\u0435\u0441|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446|\u0432\s+\u0446\u0435\u043b\u043e\u043c|\u0432\u043e\u043e\u0431\u0449\u0435|(?:19|20)\d{2}|all\s+time|what|which|how\s+much|show|give|company|business|organization|our|we|us)/iu.test(text);
return hasYearRankingCue || hasCompanyEarningsCue || hasCompanyProfitMarginCue;
}
function hasOrganizationLevelProfitMarginBoundaryOverviewSignal(text) {
if (!text) {
return false;
}
const hasProfitMarginCue = /(?:\u043f\u0440\u0438\u0431\u044b\u043b\w*|\u043c\u0430\u0440\u0436\w*|\u0440\u0435\u043d\u0442\u0430\u0431\w*|\u0444\u0438\u043d(?:\u0430\u043d\u0441\w*)?\s*[- ]?\s*\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442|p\s*&\s*l|profit(?:ability)?|margin|financial\s+result)/iu.test(text);
const hasCompanyScopeCue = /(?:\u0443\s+\u043d\u0430\u0441|\u043d\u0430\u0448\w*|\u043c\u044b\b|\u043f\u043e\s+\u043a\u043e\u043c\u043f\u0430\u043d|\u043a\u043e\u043c\u043f\u0430\u043d|\u0431\u0438\u0437\u043d\u0435\u0441|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446|\u0432\s+\u0446\u0435\u043b\u043e\u043c|\b(?:\u043e\u043e\u043e|\u0438\u043f|\u0430\u043e|\u043f\u0430\u043e|\u0437\u0430\u043e|\u043e\u0430\u043e)\b|(?:19|20)\d{2}|company|business|organization|our|we|us)/iu.test(text);
return hasProfitMarginCue && hasCompanyScopeCue;
}
function hasProfitMarginBoundaryFollowupSignal(text) {
if (!text) {
return false;
}
const hasProfitOrResultCue = /(?:\u043f\u0440\u0438\u0431\u044b\u043b\w*|\u0443\u0431\u044b\u0442\w*|\u043c\u0430\u0440\u0436\w*|\u0440\u0435\u043d\u0442\u0430\u0431\w*|\u0444\u0438\u043d(?:\u0430\u043d\u0441\w*)?\s*[- ]?\s*\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442|p\s*&\s*l|profit|loss|margin|financial\s+result)/iu.test(text);
const hasFollowupShape = /(?:\u044d\u0442\u043e|\u0438\u0442\u043e\u0433|\u0438\u0442\u043e\u0433\u043e|\u043f\u043e\u043b\u0443\u0447\w*|\u043a\u043e\u0440\u043e\u0442\w*|\u0432\s+\u0438\u0442\u043e\u0433\u0435|\u043c\u043e\u0436\u043d\u043e\s+(?:\u043b\u0438\s+)?\u0441\u043a\u0430\u0437\u0430\u0442\u044c|is\s+it|result|short|brief)/iu.test(text);
return hasProfitOrResultCue && hasFollowupShape;
}
function hasDebtDueDateBoundaryFollowupSignal(text) {
if (!text) {
return false;
}
const hasDueDateCue = /(?:\u043f\u0440\u043e\u0441\u0440\u043e\u0447\w*|\u0441\u0440\u043e\u043a\w*\s+\u043e\u043f\u043b\u0430\u0442|\u0434\u043e\u043a\u0430\u0437\w*|\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\w*|due[-\s]?date|overdue|debt\s+aging|aging)/iu.test(text);
const hasFollowupShape = /(?:\u0442\u043e\s+\u0435\u0441\u0442\u044c|\u043f\u043e\u0447\u0435\u043c\u0443|\u043a\u043e\u0440\u043e\u0442\w*|\u043d\u0435\u043b\u044c\u0437\u044f|\u043c\u043e\u0436\u043d\u043e\s+\u043b\u0438|\u0437\u043d\u0430\u0447\u0438\u0442|\u0432\u044b\u0445\u043e\u0434\u0438\u0442|why|short|brief|so)/iu.test(text);
return hasDueDateCue && hasFollowupShape;
}
function hasOrganizationLevelDebtDueDateOverviewSignal(text) {
if (!text) {
return false;
}
if (/(?:\u043a\u0442\u043e|\u043a\u043e\u043c\u0443|\u043a\u0430\u043a\u0438\u0435\s+(?:\u043f\u043e\u043a\u0443\u043f\u0430\u0442\u0435\u043b|\u043a\u043b\u0438\u0435\u043d\u0442|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442|\u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a|\u0434\u043e\u043b\u0436\u043d\u0438\u043a)|who\b|which\s+(?:customers|clients|counterparties|debtors))/iu.test(text)) {
return false;
}
const hasDueDateDebtCue = /(?:\u043f\u0440\u043e\u0441\u0440\u043e\u0447\w*|\u0441\u0440\u043e\u043a\w*\s+\u043e\u043f\u043b\u0430\u0442|\u0441\u0440\u043e\u043a\u0438\s+\u0434\u0430\u0432\u043d\u043e\s+\u043f\u0440\u043e\u0448|\u0434\u043e\u043b\u0433\w*\s+aging|\u043a\u0430\u0447\u0435\u0441\u0442\u0432\w*\s+\u0434\u043e\u043b\u0433|\u0434\u043e\u043b\u0433\w*\s+\u043a\u0430\u0447\u0435\u0441\u0442\u0432|due[-\s]?date|overdue|debt\s+aging|debt\s+quality|credit\s+risk)/iu.test(text);
const hasCompanyScopeCue = /(?:\u0443\s+\u043d\u0430\u0441|\u043d\u0430\u0448\w*|\u043f\u043e\s+\u043a\u043e\u043c\u043f\u0430\u043d|\u043a\u043e\u043c\u043f\u0430\u043d|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446|\u0431\u0438\u0437\u043d\u0435\u0441|\u0432\s+\u0446\u0435\u043b\u043e\u043c|\u043e\u0431\u0449\w*|\u043a\u0430\u043a\w*|\u043f\u043e\u043a\u0430\u0436|\u0434\u0430\u0439|\u0441\u0440\u0435\u0437|\u0430\u043d\u0430\u043b\u0438\u0437|(?:19|20)\d{2}|company|business|organization|overall|our|we|us|show|give|analysis)/iu.test(text);
return hasDueDateDebtCue && hasCompanyScopeCue;
}
function hasOrganizationLevelDebtPositionOverviewSignal(text) {
if (!text) {
return false;
}
const hasReceivablesCue = /(?:\u0434\u0435\u0431\u0438\u0442\u043e\u0440\w*|\u043a\u0442\u043e\s+\u043d\u0430\u043c\s+\u0434\u043e\u043b\u0436|\u043d\u0430\u043c\s+\u0434\u043e\u043b\u0436\w*|receivables?|accounts\s+receivable)/iu.test(text);
const hasPayablesCue = /(?:\u043a\u0440\u0435\u0434\u0438\u0442\u043e\u0440\w*|\u043a\u043e\u043c\u0443\s+\u043c\u044b\s+\u0434\u043e\u043b\u0436|\u043c\u044b\s+\u0434\u043e\u043b\u0436\w*|payables?|accounts\s+payable)/iu.test(text);
const hasOverviewCue = /(?:\u0441\u0440\u0435\u0437|\u043f\u043e\u0437\u0438\u0446\w*|\u0431\u0430\u043b\u0430\u043d\u0441|\u0441\u0430\u043b\u044c\u0434\u043e|\u043d\u0435\u0442\u0442\u043e|\u043d\u0430\s+\u0441\u0435\u0433\u043e\u0434\u043d|\u043d\u0430\s+\u0434\u0430\u0442\u0443|\u0443\s+\u043d\u0430\u0441|\u043f\u043e\s+\u043a\u043e\u043c\u043f\u0430\u043d|\u043a\u043e\u043c\u043f\u0430\u043d|\u0431\u0438\u0437\u043d\u0435\u0441|\u043e\u0431\u0437\u043e\u0440|\u0430\u043d\u0430\u043b\u0438\u0437|as\s+of|overview|balance|net|company|business)/iu.test(text);
return hasReceivablesCue && hasPayablesCue && hasOverviewCue;
}
function hasOrganizationLevelInventoryReserveLiquidationOverviewSignal(text) {
if (!text) {
return false;
}
if (/(?:\u043a\u0430\u043a\u0438\u0435\s+(?:\u0442\u043e\u0432\u0430\u0440|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442\u0443\u0440|\u043f\u043e\u0437\u0438\u0446)|\u0447\u0442\u043e\s+(?:\u043b\u0435\u0436\u0438\u0442|\u043d\u0430\s+\u0441\u043a\u043b\u0430\u0434)|which\s+(?:items|products|goods))/iu.test(text)) {
return false;
}
const hasInventoryQualityCue = /(?:\u043d\u0435\u043b\u0438\u043a\u0432\u0438\u0434\w*|\u0440\u0435\u0437\u0435\u0440\u0432\w*|\u0441\u043f\u0438\u0441\u0430\u043d\w*|\u043b\u0438\u043a\u0432\u0438\u0434\u0430\u0446\w*|\u0443\u0441\u0442\u0430\u0440\u0435\u0432\w*|\u043e\u0431\u0435\u0441\u0446\u0435\u043d\w*|obsolete|obsolescence|reserve|write[-\s]?off|liquidation|inventory\s+quality|stock\s+quality)/iu.test(text);
const hasInventoryScopeCue = /(?:\u0441\u043a\u043b\u0430\u0434|\u043e\u0441\u0442\u0430\u0442|\u0437\u0430\u043f\u0430\u0441|\u0442\u043e\u0432\u0430\u0440|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442\u0443\u0440|inventory|stock|warehouse)/iu.test(text);
const hasCompanyScopeCue = /(?:\u0443\s+\u043d\u0430\u0441|\u043d\u0430\u0448\w*|\u043f\u043e\s+\u043a\u043e\u043c\u043f\u0430\u043d|\u043a\u043e\u043c\u043f\u0430\u043d|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446|\u0431\u0438\u0437\u043d\u0435\u0441|\u0432\s+\u0446\u0435\u043b\u043e\u043c|\u043e\u0431\u0449\w*|\u0441\u043a\u043b\u0430\u0434|\u043e\u0441\u0442\u0430\u0442|\u0437\u0430\u043f\u0430\u0441|\u043a\u0430\u043a\w*|\u043f\u043e\u043a\u0430\u0436|\u0434\u0430\u0439|\u0441\u0440\u0435\u0437|\u0430\u043d\u0430\u043b\u0438\u0437|(?:19|20)\d{2}|company|business|organization|overall|warehouse|stock|inventory|our|we|us|show|give|analysis)/iu.test(text);
return hasInventoryQualityCue && hasInventoryScopeCue && hasCompanyScopeCue;
}
function hasOrganizationLevelSupplierQualityOverviewSignal(text) {
if (!text) {
return false;
}
if (/(?:\u0445\u0432\u043e\u0441\u0442|\u0434\u043e\u043b\u0433|\u0437\u0430\u0434\u043e\u043b\u0436|\u0441\u0430\u043b\u044c\u0434\u043e|\u043e\u043f\u043b\u0430\u0442|\u043f\u043b\u0430\u0442[\u0435\u0451]\u0436|\u0430\u043a\u0442|\u043f\u0440\u0438\u0445\u043e\u0434|\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\b60\b|open\s+items?|payable|payment|invoice|bill|settlement|reconciliation)/iu.test(text)) {
return false;
}
const hasSupplierScopeCue = /(?:\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a|\u0432\u0435\u043d\u0434\u043e\u0440|\u0437\u0430\u043a\u0443\u043f|\u0441\u043d\u0430\u0431\u0436|supplier|vendor|procurement|sourcing)/iu.test(text);
const hasSupplierQualityCue = /(?:\u0440\u0438\u0441\u043a\w*|\u043a\u0430\u0447\u0435\u0441\u0442\u0432\w*|\u043f\u0440\u043e\u0431\u043b\u0435\u043c\w*|\u0437\u0430\u0432\u0438\u0441\u0438\w*|\u0437\u0430\u0432\u044f\u0437\u0430\u043d\w*|\u043a\u043e\u043d\u0446\u0435\u043d\u0442\u0440\u0430\u0446\w*|\u043a\u043b\u044e\u0447\u0435\u0432\w*|\u043a\u0440\u0438\u0442\u0438\u0447\w*|risk|quality|problem|dependency|concentration|critical|key\s+supplier)/iu.test(text);
const hasCompanyScopeCue = /(?:\u0443\s+\u043d\u0430\u0441|\u043d\u0430\u0448\w*|\u043f\u043e\s+\u043a\u043e\u043c\u043f\u0430\u043d|\u043a\u043e\u043c\u043f\u0430\u043d|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446|\u0431\u0438\u0437\u043d\u0435\u0441|\u0432\s+\u0446\u0435\u043b\u043e\u043c|\u043e\u0431\u0449\w*|\u043a\u0430\u043a\w*|\u043f\u043e\u043a\u0430\u0436|\u0434\u0430\u0439|\u0441\u0440\u0435\u0437|\u0430\u043d\u0430\u043b\u0438\u0437|(?:19|20)\d{2}|company|business|organization|overall|our|we|us|show|give|analysis)/iu.test(text);
return hasSupplierScopeCue && hasSupplierQualityCue && hasCompanyScopeCue;
}
function hasCrossScopeExecutiveSummarySignal(text) {
return (/(?:\u0441\u043e\u0431\u0435\u0440\p{L}*\s+(?:\u043a\u043e\u0440\u043e\u0442\u043a\p{L}*\s+)?\u0438\u0442\u043e\u0433|\u044d\u043a\u0437\u0435\u043a\u044c\u044e\u0442\u0438\u0432\p{L}*\s+\u0441\u0430\u043c\u043c\u0430\u0440\u0438|executive\s+summary|final\s+summary)/iu.test(text) &&
/(?:\u0447\u0442\u043e\s+(?:\u043c\u044b\s+)?\u043f\u043e\u0434\u0442\u0432\u0435\u0440\p{L}*|\u043f\u043e\s+\u043a\u043e\u043c\u043f\u0430\u043d\p{L}*|\u043f\u043e\s+\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\p{L}*|confirmed|company|organization)/iu.test(text) &&
/(?:\u043e\u0442\u0434\u0435\u043b\u044c\u043d\p{L}*\s+\u043f\u043e|\u043f\u043e\s+\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442\p{L}*|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442\p{L}*|\u0433\u0440\u0443\u043f\u043f\p{L}*\s+\u0441\u0432\u043a|\u0441\u0432\u043a|counterpart(?:y|ies)?)/iu.test(text) &&
/(?:\u0447\u0442\u043e\s+\u043c\u043e\u0436\u043d\p{L}*|\u0447\u0442\u043e\s+\u043d\u0435\u043b\u044c\u0437\p{L}*|\u0432\u044b\u0432\u043e\u0434\p{L}*|allowed|forbidden|cannot|can\s+say)/iu.test(text));
}
function hasPlainBusinessOverviewSignal(text) {
const hasPlainOverviewCue = /(?:\u0432\u0437\u0440\u043e\u0441\u043b\p{L}*[\s\S]{0,40}\u043e\u0431\u0437\u043e\u0440|\u043a\u0440\u0430\u0442\u043a\p{L}*\s+\u043e\u0431\u0437\u043e\u0440|\u043e\u0431\u0437\u043e\u0440[\s\S]{0,100}(?:\u0432\u0445\u043e\u0434\u044f\u0449|\u0438\u0441\u0445\u043e\u0434\u044f\u0449|\u043d\u0435\u0442\u0442\u043e|incoming|outgoing|net))/iu.test(text);
const hasCompanyOrOperatingScopeCue = /(?:\u043e\u043e\u043e|\u0438\u043f|\u0430\u043e|\u043f\u0430\u043e|\u043a\u043e\u043c\u043f\u0430\u043d|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446|\u0431\u0438\u0437\u043d\u0435\u0441|\u0443\s+\u043d\u0430\u0441|\u043d\u0430\u0448\p{L}*|(?:19|20)\d{2}|company|organization|business)/iu.test(text);
return hasPlainOverviewCue && hasCompanyOrOperatingScopeCue;
}
function hasBusinessOverviewSignal(text) {
if (hasCrossScopeExecutiveSummarySignal(text) ||
hasOrganizationLevelEarningsOverviewSignal(text) ||
hasOrganizationLevelDebtPositionOverviewSignal(text) ||
hasOrganizationLevelDebtDueDateOverviewSignal(text) ||
hasOrganizationLevelInventoryReserveLiquidationOverviewSignal(text) ||
hasPlainBusinessOverviewSignal(text) ||
hasOrganizationLevelSupplierQualityOverviewSignal(text)) {
return true;
}
return /(?:\u0431\u0438\u0437\u043d\u0435\u0441[-\s]?\u043e\u0431\u0437\u043e\u0440|\u0431\u0438\u0437\u043d\u0435\u0441[-\s]?\u0430\u0443\u0434\u0438\u0442|\u043f\u043e\u043b\u043d\w*\s+\u0430\u043d\u0430\u043b\u0438\u0437\s+(?:\u043a\u043e\u043c\u043f\u0430\u043d|\u0431\u0438\u0437\u043d\u0435\u0441|\u0434\u0435\u044f\u0442\u0435\u043b)|\u0441\u0432\u043e\u0434\u043d\w*\s+\u0430\u043d\u0430\u043b\u0438\u0437\s+(?:\u043a\u043e\u043c\u043f\u0430\u043d|\u0431\u0438\u0437\u043d\u0435\u0441|\u0434\u0435\u044f\u0442\u0435\u043b)|\u043a\u0430\u043a\s+\u0442\u044b\s+\u043e\u0446\u0435\u043d(?:\u0438\u0448\u044c|\u0438)\s+\u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442|\u043a\u043e\u043c\u043f\u0430\u043d(?:\u0438\u0438|\u0438\u044e|\u0438\u044f)\s+\u0432\s+\u0446\u0435\u043b\u043e\u043c|company\s+(?:analysis|overview)|business\s+(?:overview|audit)|llm[-\s]?audit|бизнес[-\s]?обзор|бизнес[-\s]?аудит)/iu.test(text);
}
function hasBusinessOverviewContinuationSignal(text) {
if (!text) {
return false;
}
const normalized = compactLower(text);
const hasEvidenceContinuationCue = /(?:по\s+этим\s+данн|на\s+базе\s+этих\s+данн|из\s+этого|по\s+итогам|что\s+подтвержден|чего\s+не\s+хватает|что\s+пока\s+нельзя|что\s+можно\s+сказать|какой\s+вывод|итогов|резюм|вывод)/iu.test(normalized);
const hasAnalystContinuationCue = /(?:можно\s+ли|если\s+нет|proxy|прокси|аудит|оцен|что\s+думаешь|нормальн\p{L}*\s+прибыл|прибыл|марж|рентаб|ликвидн|просроч|качество\s+долг|риск|налогов\p{L}*\s+вывод)/iu.test(normalized);
const hasTaxContinuationCue = /(?:ндс|vat)[\s\S]{0,120}(?:позици|период|основан|не\s+хватает|налогов\p{L}*\s+вывод)|(?:позици|налогов\p{L}*\s+вывод)[\s\S]{0,80}(?:ндс|vat)/iu.test(normalized);
const hasFinalSummaryCue = /(?:\u0447\u0442\u043e\s+\u043c\u044b\s+\u0437\u043d\u0430\u0435\u043c|\u0447\u0442\u043e\s+\u043f\u043e\u043d\u044f\u0442\u043d\u043e|\u0447\u0442\u043e\s+\u043f\u0440\u043e\u0432\u0435\u0440\w*\s+\u0434\u0430\u043b\u044c\u0448\u0435|\u0441\u043b\u0435\u0434\u0443\u044e\u0449\w*\s+\u0448\u0430\u0433|\u0438\u0442\u043e\u0433\w*\s+\u0432\u044b\u0432\u043e\u0434|\u043a\u0430\u043a\u043e\u0439\s+\u0432\u044b\u0432\u043e\u0434|\u0447\u0442\u043e\s+\u0441\s+\u044d\u0442\u0438\u043c\s+\u0434\u0435\u043b\u0430\u0442\u044c|what\s+do\s+we\s+know|what\s+is\s+missing|next\s+step|final\s+summary)/iu.test(normalized);
const hasMoneyBreakdownCue = /(?:\u0440\u0430\u0441\u043a\u0440\u043e\p{L}*\s+\u0434\u0435\u043d\p{L}*|\u0441\u043a\u043e\u043b\u044c\u043a\u043e\s+\u0432\u0441\u0435\u0433\u043e\s+\u043f\u043e\u043b\u0443\u0447|\u0441\u043a\u043e\u043b\u044c\u043a\u043e\s+(?:\u0432\u0441\u0435\u0433\u043e\s+)?\u0437\u0430\u043f\u043b\u0430\u0442|\u0447\u0438\u0441\u0442\p{L}*\s+\u0434\u0435\u043d\u0435\u0436\u043d\p{L}*\s+\u043f\u043e\u0442\u043e\u043a|\u0433\u043b\u0430\u0432\u043d\p{L}*\s+(?:\u043a\u043b\u0438\u0435\u043d\u0442|\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a)|top\s+(?:customer|supplier)|cash\s+breakdown)/iu.test(normalized) &&
/(?:\u043f\u043e\u043b\u0443\u0447|\u0437\u0430\u043f\u043b\u0430\u0442|\u043d\u0435\u0442\u0442\u043e|\u0434\u0435\u043d\p{L}*|\u043a\u043b\u0438\u0435\u043d\u0442|\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a|received|paid|net|cash|customer|supplier)/iu.test(normalized);
return (hasEvidenceContinuationCue ||
hasAnalystContinuationCue ||
hasTaxContinuationCue ||
hasFinalSummaryCue ||
hasMoneyBreakdownCue);
}
function hasExplicitVatQuestionSignal(text) {
if (!text) {
return false;
}
return (/(?:\u043d\u0434\u0441|vat)/iu.test(text) &&
/(?:\u0437\u0430|\u043d\u0430|\u043f\u0435\u0440\u0438\u043e\u0434|\u043f\u043e\u0437\u0438\u0446|\u043a\s+\u0443\u043f\u043b\u0430\u0442|\u043a\s+\u0432\u043e\u0437\u043c\u0435\u0449|\u043e\u0441\u043d\u043e\u0432\u0430\u043d|\u043d\u0430\u043b\u043e\u0433\u043e\u0432\p{L}*\s+\u0432\u044b\u0432\u043e\u0434|tax\s+period|tax\s+position)/iu.test(text));
}
function hasExplicitVatMovementEvidenceSignal(text) {
if (!/(?:\u043d\u0434\u0441|vat)/iu.test(text)) {
return false;
}
return hasMovementEvidenceFollowupSignal(text);
}
function hasBusinessOverviewSeparateCounterpartySignal(text) {
if (!text) {
return false;
}
return (/(?:\u043e\u0442\u0434\u0435\u043b\u044c\u043d\p{L}*\s+\u043f\u043e|\u043f\u043e\s+\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442\p{L}*|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442\p{L}*|counterpart(?:y|ies)?)/iu.test(text) &&
/(?:\u043a\u043e\u043c\u043f\u0430\u043d\p{L}*|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\p{L}*|company|organization|\u0438\u0442\u043e\u0433|summary|\u0432\u044b\u0432\u043e\u0434\p{L}*)/iu.test(text));
}
function businessOverviewSeparateCounterpartyCandidateFromText(text) {
const source = (0, addressTextRepair_1.repairAddressMojibakeText)(String(text ?? ""));
const patterns = [
/(?:\u043e\u0442\u0434\u0435\u043b\u044c\u043d\p{L}*\s+\u043f\u043e|\u043f\u043e\s+\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442\p{L}*)\s+(.+?)(?:[,.;:!?]|\s+\u043a\u0430\u043a\u0438\p{L}*\b|\s+\u0447\u0442\u043e\b|$)/iu,
/(?:\u0434\u043b\u044f|for)\s+([\p{L}\d._-]+(?:\s+[\p{L}\d._-]+){0,3})(?:[,.;:!?]|\s+\u043a\u0430\u043a\u0438\p{L}*\b|\s+\u0447\u0442\u043e\b|$)/iu
];
for (const pattern of patterns) {
const candidate = normalizeFollowupCounterpartyCandidate(source.match(pattern)?.[1]);
if (candidate && !isInvalidEntityCandidate(candidate)) {
return candidate;
}
}
return null;
}
function hasExplicitTopicSwitchSignal(text) {
return /(?:^|\s)(?:\u0442\u0435\u043f\u0435\u0440\u044c|\u0430\s+\u0442\u0435\u043f\u0435\u0440\u044c|\u0434\u0430\u043b\u044c\u0448\u0435|\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e|\u043f\u0435\u0440\u0435\u0439\u0434[\u0451\u0435]\u043c|\u0441\u043c\u0435\u043d\u0438\u043c\s+\u0442\u0435\u043c\u0443|\u0432\u0435\u0440\u043d[\u0451\u0435]\u043c\u0441\u044f\s+\u043a|now|next|switch\s+to)(?:\s|$)/iu.test(text);
}
function hasBusinessOverviewFollowupSeed(followupSeed) {
return (followupSeed.pilotScope === "business_overview_route_template_v1" ||
followupSeed.domain === "business_overview" ||
followupSeed.action === "broad_evaluation" ||
followupSeed.unsupported === "broad_business_evaluation" ||
followupSeed.loopSelectedChainId === "business_overview");
}
function hasValueFlowSignal(text) {
return /(?:оборот|выручк|оплат|плат[её]ж|заплат|перечисл|списан|расход|исходящ|входящ|получ(?:ил|ено|ен)|поступил|поступлен|денежн[а-яёa-z0-9_-]*\s+поток|(?<!\p{L})заработ(?:ал|али|ало|аем|ает|ать|ано|ок)(?!\p{L})|supplier|value[-\s]?flow|turnover|revenue|payment|payout|outflow|cash\s+flow|\bearn(?:ed|ing|ings)?\b)/iu.test(text);
}
function hasValueFlowAggregateQuestionSignal(text) {
return /(?:\u0441\u043a\u043e\u043b\u044c\u043a\u043e|\u0441\u0443\u043c\u043c|\u0438\u0442\u043e\u0433|\u0440\u0430\u0441\u0441\u0447\u0438\u0442|\u043d\u0435\u0442\u0442\u043e|\u0441\u0430\u043b\u044c\u0434\u043e|how\s+much|total|sum|net)/iu.test(text);
}
function hasPayoutSignal(text) {
return /(?:\bмы\s+(?:за)?плат|(?:за)?платил|оплатил|перечисл|списан|расход|поставщик|исходящ|supplier|payout|outflow|paid\s+to|payment\s+to)/iu.test(text);
}
function hasBidirectionalValueFlowSignal(text) {
return /(?:нетто|сальдо|баланс\s+(?:плат|денег|денеж)|взаиморасч[её]т|получил[иа]?.*(?:за)?платил|(?:за)?платил[иа]?.*получил|входящ.*исходящ|исходящ.*входящ|дебет.*кредит|кредит.*дебет|net\s+(?:flow|cash|payment)|cash\s+net|incoming\s+and\s+outgoing|received\s+and\s+paid|paid\s+and\s+received)/iu.test(text);
}
function hasValueRankingSignal(text) {
return /(?:кто\s+больше\s+всего.*ден[её]г|больше\s+всего.*ден[её]г|прин[её]с.*ден[её]г|сам(?:ый|ая|ое|ые).*(?:доходн|прибыльн)|most.*money|highest\s+(?:revenue|payment))/iu.test(text);
}
function hasOrganizationScopeSignal(text) {
return /(?:\bооо\b|\bип\b|\bао\b|\bпао\b|\bзао\b|\bllc\b|\binc\b|\bcorp\b|\bcompany\b|\borganization\b|\borganisation\b|организац|компан)/iu.test(text);
}
function hasOrganizationScopeSignalUtf8(text) {
return (/(?<!\p{L})(?:\u043e\u043e\u043e|\u0438\u043f|\u0430\u043e|\u043f\u0430\u043e|\u0437\u0430\u043e)(?!\p{L})/iu.test(text) ||
/\b(?:llc|inc|corp|company|organization|organisation)\b/iu.test(text) ||
/(?:\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446|\u043a\u043e\u043c\u043f\u0430\u043d)/iu.test(text));
}
function extractOrganizationScopeFromRawText(value) {
const text = toNonEmptyString(value);
if (!text) {
return null;
}
const match = text.match(/(?:^|[\s,;:])(?:\u043f\u043e|for|in|within)?\s*((?:\u041e\u041e\u041e|\u0418\u041f|\u0410\u041e|\u041f\u0410\u041e|\u0417\u0410\u041e|LLC|Inc|LTD|Corp)\s+[^\n,.;:!?]+)/u);
if (!match?.[1]) {
return null;
}
return toNonEmptyString(match[1]
.replace(/\s+(?:\u043f\u043e\s+\u0434\u0430\u043d\u043d\u044b\u043c\s+1\u0441|\u0432\s+\u0446\u0435\u043b\u043e\u043c|\u0437\u0430\s+(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{2}|(?:19|20)\d{2})(?:\s+\u0433(?:\u043e\u0434|\.)?)?|\u043d\u0430\s+(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{2}|(?:19|20)\d{2})|\u0437\u0430\s+\u0432\u0441[\u0435\u0451]\s+(?:\u0434\u043e\u0441\u0442\u0443\u043f\p{L}+\s+)?\u0432\u0440\u0435\u043c\u044f|\u0437\u0430\s+\u0432\u0435\u0441\u044c\s+(?:\u0434\u043e\u0441\u0442\u0443\u043f\p{L}+\s+)?\u043f\u0435\u0440\u0438\u043e\u0434|\u0437\u0430\s+\u0432\u0441\u044e\s+\u0438\u0441\u0442\u043e\u0440\u0438(?:\u044e|\u0438)|\u0434\u0430\u0439\s+\u0431\u0438\u0437\u043d\u0435\u0441-?\u043e\u0431\u0437\u043e\u0440|\u0431\u0438\u0437\u043d\u0435\u0441-?\u043e\u0431\u0437\u043e\u0440|\u043d\u043e\s+\u043d\u0435).*$/iu, "")
.trim());
}
function hasMonthlyAggregationSignal(text) {
return /(?:\u043f\u043e\s+\u043c\u0435\u0441\u044f\u0446\u0430\u043c|\u043f\u043e\u043c\u0435\u0441\u044f\u0447\u043d\u043e|\u0435\u0436\u0435\u043c\u0435\u0441\u044f\u0447\u043d\u043e|month\s+by\s+month|by\s+month|monthly)/iu.test(text);
}
function hasAllTimeScopeHint(text) {
return /(?:\u0437\u0430\s+\u0432\u0441[\u0435\u0451]\s+(?:\u0434\u043e\u0441\u0442\u0443\u043f\p{L}+\s+)?\u0432\u0440\u0435\u043c\u044f|\u0437\u0430\s+\u0432\u0435\u0441\u044c\s+(?:\u0434\u043e\u0441\u0442\u0443\u043f\p{L}+\s+)?\u043f\u0435\u0440\u0438\u043e\u0434|\u0437\u0430\s+\u0432\u0441\u044e\s+\u0438\u0441\u0442\u043e\u0440\u0438(?:\u044e|\u0438)|\u0437\u0430\s+\u043b\u044e\u0431\u043e\u0439\s+\u043f\u0435\u0440\u0438\u043e\u0434|for\s+all\s+time|all\s+time|entire\s+period|full\s+history|any\s+period)/iu.test(text);
}
function hasMetadataSignal(text) {
if (/(?:\u043c\u0435\u0442\u0430\u0434\u0430\u043d|schema|catalog|metadata\s+surface|\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440[\u0430\u044b]\s+1\u0441|\u0441\u0445\u0435\u043c[\u0430\u044b]\s+1\u0441)/iu.test(text)) {
return true;
}
return (/(?:\u043e\u0431\u044a\u0435\u043a\u0442(?:\u044b|\u0430|\u043e\u0432)?|\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b|\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b|\u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a\u0438|\u043f\u043e\u043b(?:\u0435|\u044f)|objects?|registers?|documents?|catalogs?|fields?)/iu.test(text) &&
/(?:\u0435\u0441\u0442\u044c|\u043a\u0430\u043a\u0438\u0435|\u0434\u043e\u0441\u0442\u0443\u043f\u043d|\u0432\s+1\u0441|1\u0441|available|exist|which)/iu.test(text));
}
function hasReferentialDocumentExclusionFollowupSignal(text) {
return /(?:\u043a\u0440\u043e\u043c\u0435|\u043f\u043e\u043c\u0438\u043c\u043e)\s+(?:\u044d\u0442\u043e\u0433\u043e|\u044d\u0442\u043e\u0439|\u044d\u0442\u043e\u0442|\u044d\u0442\u0443|\u044d\u0442\u0438\u0445)(?:\s+(?:\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430|\u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0430|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442\u0430))?/iu.test(text);
}
function hasMetadataObjectHint(text) {
return /(?:\u043e\u0431\u044a\u0435\u043a\u0442(?:\u044b|\u0430|\u043e\u0432)?|\u0440\u0435\u0433\u0438\u0441\u0442\u0440(?:\u044b)?|\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u044b)?|\u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a(?:\u0438)?|\u043f\u043e\u043b(?:\u0435|\u044f)|objects?|registers?|documents?|catalogs?|fields?)/iu.test(text);
}
function hasSimpleDocumentLanePivotSignal(text) {
return /(?:^|\s)по\s+документ(?:ам|ы)?(?:\?|$|\s)/iu.test(text);
}
function hasSimpleMovementLanePivotSignal(text) {
return /(?:^|\s)по\s+движени(?:ям|я)?(?:\?|$|\s)/iu.test(text);
}
function hasUtf8DocumentLanePivotSignal(text) {
return /(?:^|\s)по\s+документ(?:ам|ы)?(?:\?|$|\s)/iu.test(text);
}
function hasUtf8MovementLanePivotSignal(text) {
return /(?:^|\s)по\s+движени(?:ям|я)?(?:\?|$|\s)/iu.test(text);
}
function hasDocumentEvidenceFollowupSignal(text) {
return /(?:\u043f\u043e\s+\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u0430\u043c|\u044b)?|\u0434\u0430\u0432\u0430\u0439\s+\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u044b)?|\u0438\u0449\u0438\s+\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u044b)?|\u043f\u043e\u043a\u0430\u0436\u0438\s+\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u044b)?|(?:\u043f\u043e\u043a\u0430\u0436\u0438|\u043a\u0430\u043a\u0438\u0435|\u0441\u043f\u0438\u0441\u043e\u043a|\u0434\u0430\u0439|\u0438\u0449\u0438)\s+(?:\u0441\u0447(?:[еe]т|\u0435\u0442)[-\u2011 ]?\u0444\u0430\u043a\u0442\u0443\u0440(?:\u044b|\u0430)?|\u043d\u0430\u043a\u043b\u0430\u0434\u043d(?:\u044b\u0435|\u0430\u044f)?|\u0430\u043a\u0442(?:\u044b)?|\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446(?:\u0438\u0438|\u0438\u044e)|invoice(?:s)?|bill(?:s)?|waybill(?:s)?)|document(?:s)?\s+(?:then|next)?|(?:then|next)\s+documents?|go\s+to\s+documents?)/iu.test(text);
}
function hasMovementEvidenceFollowupSignal(text) {
return /(?:\u043f\u043e\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f\u043c|\u0438\u044f)?|\u0434\u0430\u0432\u0430\u0439\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f|\u0438\u0435)|\u0438\u0449\u0438\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f|\u0438\u0435)|\u043f\u043e\u043a\u0430\u0436\u0438\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f|\u0438\u0435)|\u0431\u0430\u043d\u043a\u043e\u0432\u0441\u043a(?:\u0438\u0435|\u0438\u0439)\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f|\u0438\u0435)|(?:\u043f\u043e\u043a\u0430\u0436\u0438|\u043a\u0430\u043a\u0438\u0435|\u0441\u043f\u0438\u0441\u043e\u043a|\u0434\u0430\u0439|\u0438\u0449\u0438)\s+(?:\u043f\u043b\u0430\u0442[еe]\u0436(?:\u0438|\u0438)?|\u043e\u043f\u0435\u0440\u0430\u0446(?:\u0438\u0438|\u0438\u044e)|\u043f\u0440\u043e\u0432\u043e\u0434\u043a(?:\u0438|\u0430)|\u0441\u043f\u0438\u0441\u0430\u043d(?:\u0438\u044f|\u0438\u0435)|\u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d(?:\u0438\u044f|\u0438\u0435)|payment(?:s)?|transaction(?:s)?|operation(?:s)?|posting(?:s)?|bank\s+operation(?:s)?)|movement(?:s)?\s+(?:then|next)?|(?:then|next)\s+movements?|go\s+to\s+movements?)/iu.test(text);
}
function hasPronounDocumentEvidenceFollowupSignal(text) {
return /(?:\u043f\u043e\s+(?:\u043d\u0435\u043c\u0443|\u043d\u0435\u0439|\u044d\u0442\u043e\u043c\u0443|\u044d\u0442\u043e\u0439)\s+(?:\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u0430\u043c|\u044b)?|\u0441\u0447(?:[Рµe]С|\u0435\u0442)[-\u2011 ]?\u0444\u0430\u043a\u0442\u0443\u0440(?:\u044b|\u0430)?|\u043d\u0430\u043a\u043b\u0430\u0434\u043d(?:\u044b\u0435|\u0430\u044f)?|\u0430\u043a\u0442(?:\u044b)?))/iu.test(text);
}
function hasPronounMovementEvidenceFollowupSignal(text) {
return /(?:\u043f\u043e\s+(?:\u043d\u0435\u043c\u0443|\u043d\u0435\u0439|\u044d\u0442\u043e\u043c\u0443|\u044d\u0442\u043e\u0439)\s+(?:\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f\u043c|\u0438\u044f)?|\u043f\u043b\u0430\u0442[Рµe]\u0436(?:\u0430\u043c|\u0438)?|\u043e\u043f\u0435\u0440\u0430\u0446(?:\u0438\u044f\u043c|\u0438\u0438|\u0438\u044e)|\u043f\u0440\u043e\u0432\u043e\u0434\u043a(?:\u0430\u043c|\u0438)|\u0441\u043f\u0438\u0441\u0430\u043d(?:\u0438\u044f\u043c|\u0438\u0435)|\u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d(?:\u0438\u044f\u043c|\u0438\u0435)))/iu.test(text);
}
function hasMetadataDownstreamContinuationSignal(text) {
return /(?:\u0434\u0430\u0432\u0430\u0439\s+\u0434\u0430\u043b\u044c\u0448\u0435|\u0438\u0434(?:\u0435|\u0451)\u043c\s+\u0434\u0430\u043b\u044c\u0448\u0435|\u043f\u043e\u0448\u043b(?:\u0438|\u0451\u043c)\s+\u0434\u0430\u043b\u044c\u0448\u0435|\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0439|\u0438\u0449\u0438\s+\u0434\u0430\u043b\u044c\u0448\u0435|\u0438\u0449\u0438\s+\u0434\u0430\u043d\u043d\u044b\u0435|\u043f\u043e\u043a\u0430\u0436\u0438\s+\u0434\u0430\u043d\u043d\u044b\u0435|\u043f\u043e\u043a\u0430\u0436\u0438\s+\u0441\u0442\u0440\u043e\u043a\u0438|\u0433\u043b\u0443\u0431\u0436\u0435|\u0447\u0442\u043e\s+\u0434\u0430\u043b\u044c\u0448\u0435|continue|go\s+ahead|go\s+deeper|look\s+deeper|drill\s+down|show\s+(?:data|rows))/iu.test(text);
}
function hasEntityResolutionSignal(text) {
const hasSearchVerb = /(?:найд(?:и|ите|ем|у)|поищ(?:и|ите|ем)|найти|поиск|search|find|look\s*up)/iu.test(text);
const hasEntityNoun = /(?:контрагент(?:а|ов|у|ом|е)?|поставщик(?:а|ов|у|ом|е)?|клиент(?:а|ов|у|ом|е)?|counterpart(?:y|ies)|supplier(?:s)?|customer(?:s)?)/iu.test(text);
return hasSearchVerb && hasEntityNoun;
}
function normalizeEntityResolutionCandidate(value) {
return value
.replace(/^(?:в\s*1с\s+|в\s+1c\s+|по\s+имени\s+)/iu, "")
.replace(/[?!.]+$/gu, "")
.replace(/^(?:контрагент(?:а|ов|у|ом|е)?|поставщик(?:а|ов|у|ом|е)?|клиент(?:а|ов|у|ом|е)?)\s+/iu, "")
.replace(/^(?:counterpart(?:y|ies)|supplier(?:s)?|customer(?:s)?)\s+/iu, "")
.replace(/^группу\s+/iu, "Группа ")
.replace(/^[«"'\s]+|[»"'\s]+$/gu, "")
.replace(/\s+/g, " ")
.trim();
}
function rawEntityResolutionCandidate(text) {
const patterns = [
/(?:найд(?:и|ите|ем|у)|поищ(?:и|ите|ем)|найти|search|find|look\s*up)\s+(?:в\s*1с\s+|в\s+1c\s+)?(?:контрагент(?:а|ов|у|ом|е)?|поставщик(?:а|ов|у|ом|е)?|клиент(?:а|ов|у|ом|е)?|counterpart(?:y|ies)|supplier(?:s)?|customer(?:s)?)\s+(.+)$/iu,
/(?:найд(?:и|ите|ем|у)|поищ(?:и|ите|ем)|найти|search|find|look\s*up)\s+(?:в\s*1с\s+|в\s+1c\s+)(.+)$/iu,
/(?:контрагент(?:а|ов|у|ом|е)?|поставщик(?:а|ов|у|ом|е)?|клиент(?:а|ов|у|ом|е)?|counterpart(?:y|ies)|supplier(?:s)?|customer(?:s)?)\s+(.+?)\s+(?:найд(?:и|ите|ем|у)|поищ(?:и|ите|ем)|найти|search|find|look\s*up)\b/iu
];
for (const pattern of patterns) {
const match = text.match(pattern);
const candidate = normalizeEntityResolutionCandidate(match?.[1] ?? "");
if (candidate.length >= 2) {
return candidate;
}
}
return null;
}
function rawScopedEntityCandidateFromText(text) {
const source = (0, addressTextRepair_1.repairAddressMojibakeText)(String(text ?? ""));
const patterns = [
/(?:^|[\s,.;:!?])(?:по|у|для|for|by)\s+(.+?)(?=$|[,.;:!?]|\s+(?:за|на|в|во|к|по|сколько|скок|как|какое|какой|какая|какие|получ\p{L}*|заплат\p{L}*|нетто|документ\p{L}*|движени\p{L}*|операц\p{L}*|плат[её]ж\p{L}*)(?=$|[\s,.;:!?]))/iu,
/(?:^|[\s,.;:!?])(?:по|у|для|for|by)\s+([\p{L}\d._-]{2,})(?=$|[\s,.;:!?])/iu,
/(?:документ(?:ам|ы)?|движени(?:ям|я)?|операци(?:ям|и)?|плат[её]ж(?:ам|и)?)\s+([\p{L}\d._-]{2,})(?=$|[\s,.;:!?])/iu
];
for (const pattern of patterns) {
const candidate = normalizeEntityResolutionCandidate(source.match(pattern)?.[1] ?? "");
if (candidate.length >= 2 && !isInvalidEntityCandidate(candidate)) {
return candidate;
}
}
return null;
}
function resolveEntityResolutionAmbiguityChoice(text, candidates) {
const normalizedText = canonicalizeEntityResolutionCandidate(text);
if (!normalizedText || candidates.length <= 0) {
return null;
}
const exactMatch = candidates.find((candidate) => canonicalizeEntityResolutionCandidate(candidate) === normalizedText);
if (exactMatch) {
return exactMatch;
}
const includedMatches = candidates.filter((candidate) => {
const normalizedCandidate = canonicalizeEntityResolutionCandidate(candidate);
return normalizedCandidate.length > 0 && normalizedText.includes(normalizedCandidate);
});
if (includedMatches.length === 1) {
return includedMatches[0];
}
const narrowedMatches = candidates.filter((candidate) => {
const normalizedCandidate = canonicalizeEntityResolutionCandidate(candidate);
return normalizedText.length >= 4 && normalizedCandidate.includes(normalizedText);
});
if (narrowedMatches.length === 1) {
return narrowedMatches[0];
}
const normalizedLowerText = compactLower(text);
const ordinalMatchers = [
{
index: 0,
keywords: ["первый"],
numericPatterns: [
/(?:^|[^\p{L}\p{N}])(?:вариант|номер|№)?\s*1(?:$|[^\p{L}\p{N}])/iu,
/^\s*1\s*$/u
]
},
{
index: 1,
keywords: ["второй"],
numericPatterns: [
/(?:^|[^\p{L}\p{N}])(?:вариант|номер|№)?\s*2(?:$|[^\p{L}\p{N}])/iu,
/^\s*2\s*$/u
]
},
{
index: 2,
keywords: ["третий"],
numericPatterns: [
/(?:^|[^\p{L}\p{N}])(?:вариант|номер|№)?\s*3(?:$|[^\p{L}\p{N}])/iu,
/^\s*3\s*$/u
]
},
{
index: 3,
keywords: ["четвертый", "четвёртый"],
numericPatterns: [
/(?:^|[^\p{L}\p{N}])(?:вариант|номер|№)?\s*4(?:$|[^\p{L}\p{N}])/iu,
/^\s*4\s*$/u
]
},
{
index: 4,
keywords: ["пятый"],
numericPatterns: [
/(?:^|[^\p{L}\p{N}])(?:вариант|номер|№)?\s*5(?:$|[^\p{L}\p{N}])/iu,
/^\s*5\s*$/u
]
},
{
index: 5,
keywords: ["шестой"],
numericPatterns: [
/(?:^|[^\p{L}\p{N}])(?:вариант|номер|№)?\s*6(?:$|[^\p{L}\p{N}])/iu,
/^\s*6\s*$/u
]
}
];
for (const matcher of ordinalMatchers) {
if (matcher.index < candidates.length &&
(matcher.keywords.some((keyword) => normalizedLowerText.includes(keyword)) ||
matcher.numericPatterns.some((pattern) => pattern.test(normalizedLowerText)))) {
return candidates[matcher.index];
}
}
if (candidates.length > 0 &&
(normalizedLowerText.includes("последний") || normalizedLowerText.includes("крайний"))) {
return candidates[candidates.length - 1] ?? null;
}
return null;
}
function metadataActionFromRawText(text) {
if (/(?:\u043e\u0431\u044a\u0435\u043a\u0442(?:\u044b|\u0430|\u043e\u0432)?|objects?)/iu.test(text)) {
return "inspect_surface";
}
if (/(?:\u043f\u043e\u043b(?:\u0435|\u044f)|field)/iu.test(text)) {
return "inspect_fields";
}
if (/(?:\u0440\u0435\u0433\u0438\u0441\u0442\u0440|register)/iu.test(text)) {
return "inspect_registers";
}
if (/(?:\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|document)/iu.test(text)) {
return "inspect_documents";
}
if (/(?:\u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a|directory|catalog)/iu.test(text)) {
return "inspect_catalog";
}
return "inspect_catalog";
}
function metadataScopeHintFromRawText(text) {
if (/(?:\u043d\u0434\u0441|vat)/iu.test(text)) {
return "\u041d\u0414\u0421";
}
if (/(?:\u0441\u043a\u043b\u0430\u0434|inventory|stock|warehouse|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442\u0443\u0440)/iu.test(text)) {
return "\u0441\u043a\u043b\u0430\u0434";
}
if (/(?:\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442|counterparty|customer|client|supplier|vendor)/iu.test(text)) {
return "\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442";
}
return null;
}
function hasExplicitDateScopeLiteral(text) {
return /(?:\b(?:19|20)\d{2}\b|\b\d{4}-\d{2}-\d{2}\b|\b\d{4}-\d{2}\b)/iu.test(text);
}
function stripNegatedTaxDateScopeClauses(text) {
const dateScopeLiteral = String.raw `\b(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{2}|(?:19|20)\d{2})\b`;
const taxToken = String.raw `(?:\u043d\u0434\u0441|vat)`;
const scopeToken = String.raw `(?:\u0437\u0430|\u043d\u0430|\u043f\u043e|for|in)`;
const negatedVerb = String.raw `(?:\u0442\u0430\u0449\u0438(?:\u0442\u044c)?|\u0431\u0435\u0440\u0438|\u0431\u0440\u0430\u0442\u044c|\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439(?:\u0442\u0435)?|\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c|\u0441\u0447\u0438\u0442\u0430\u0439(?:\u0442\u0435)?|\u0441\u0447\u0438\u0442\u0430\u0442\u044c|\u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0439(?:\u0442\u0435)?|\u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0442\u044c|\u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438|\u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442\u044c|pull|reuse|use|carry)`;
const direct = new RegExp(String.raw `(?:^|[\s,;:])(?:\u043d\u0435\s+${negatedVerb}\s+${taxToken}\s+${scopeToken}\s+${dateScopeLiteral}|\u0431\u0435\u0437\s+${taxToken}\s+${scopeToken}\s+${dateScopeLiteral}|do\s+not\s+(?:${negatedVerb}\s+)?${taxToken}\s+${scopeToken}\s+${dateScopeLiteral})`, "giu");
const reversed = new RegExp(String.raw `${taxToken}\s+${scopeToken}\s+${dateScopeLiteral}\s+(?:\u043d\u0435\s+${negatedVerb}|do\s+not\s+(?:${negatedVerb})?)`, "giu");
return text.replace(direct, " ").replace(reversed, " ");
}
function collectDateScopeFromRawText(text) {
const isoDate = text.match(/\b(\d{4}-\d{2}-\d{2})\b/u);
if (isoDate?.[1]) {
return isoDate[1];
}
const yearMonth = text.match(/\b(\d{4}-\d{2})\b/u);
if (yearMonth?.[1]) {
return yearMonth[1];
}
const year = text.match(/\b((?:19|20)\d{2})\b/u);
if (year?.[1]) {
return year[1];
}
return null;
}
function currentIsoDate() {
return new Date().toISOString().slice(0, 10);
}
function hasRelativeCurrentDateHint(text) {
return /(?:\bсегодня\b|\bна\s+сегодня\b|\bсегодняшн(?:ий|его|ем)\b|\btoday\b|\bas\s+of\s+today\b|\bcurrent\s+date\b)/iu.test(text);
}
function isImplicitCurrentDateScope(value) {
return Boolean(value && /^\d{4}-\d{2}-\d{2}$/.test(value) && value === currentIsoDate());
}
function semanticNeedFor(input) {
const combined = compactLower(`${input.domain ?? ""} ${input.action ?? ""} ${input.unsupported ?? ""}`);
if (/(?:broad_business_evaluation|broad_evaluation|business_summary|business_overview|company analysis|business audit)/iu.test(combined)) {
return "business overview evidence with bounded analyst interpretation";
}
if (input.metadataSignal || /(?:metadata|schema|catalog|inspect_(?:catalog|documents|registers|fields))/iu.test(combined)) {
return "1C metadata evidence";
}
if (input.lifecycleSignal || /(?:lifecycle|activity|duration|age)/iu.test(combined)) {
return "counterparty lifecycle evidence";
}
if (input.valueFlowSignal || /(?:turnover|revenue|payment|payout|value|net|netting|balance|cashflow)/iu.test(combined)) {
return "counterparty value-flow evidence";
}
if (input.entityResolutionSignal ||
/(?:entity_resolution|search_business_entity|resolve_entity_reference|entity\s+discovery|counterparty\s+search)/iu.test(combined)) {
return "entity discovery evidence";
}
if (/(?:movement|movements|bank_operations|movement_evidence|list_movements)/iu.test(combined)) {
return "movement evidence";
}
if (/(?:document|documents|list_documents)/iu.test(combined)) {
return "document evidence";
}
if (/(?:inventory|stock|warehouse|purchase_provenance|purchase provenance|supplier provenance|supplier_overlap|supplier overlap|sale_trace|sale trace|purchase_to_sale|purchase-to-sale)/iu.test(combined)) {
if (/(?:sale_trace|sale trace|purchase_to_sale|purchase-to-sale|buyer)/iu.test(combined)) {
return "inventory sale trace evidence";
}
if (/(?:supplier_overlap|supplier overlap|supplier stock|stock by supplier)/iu.test(combined)) {
return "inventory supplier overlap evidence";
}
if (/(?:purchase_provenance|purchase provenance|supplier provenance|purchase document)/iu.test(combined)) {
return "inventory purchase provenance evidence";
}
return "inventory stock snapshot evidence";
}
return null;
}
function shouldRunDiscovery(input) {
if (input.forceDiscoveryOverExplicitIntent && input.semanticDataNeed) {
return true;
}
if (input.lifecycleSignal || input.unsupported) {
return true;
}
if (input.metadataSignal) {
return true;
}
if (input.entityResolutionSignal) {
return true;
}
if (input.valueFlowSignal && !input.explicitIntentCandidate) {
return true;
}
if (input.followupDiscoverySeedApplicable && !input.explicitIntentCandidate && input.semanticDataNeed) {
return true;
}
if (!input.explicitIntentCandidate && input.semanticDataNeed) {
return true;
}
return false;
}
function buildAssistantMcpDiscoveryTurnInput(input) {
const assistantTurnMeaning = toRecordObject(input.assistantTurnMeaning);
const predecomposeContract = toRecordObject(input.predecomposeContract);
const followupContext = toRecordObject(input.followupContext);
const predecomposeEntities = collectPredecomposeEntities(predecomposeContract);
const followupSeed = collectFollowupDiscoverySeed(followupContext);
const metadataSurfaceRef = buildMetadataSurfaceRef(followupSeed);
const reasonCodes = [];
const rawUserText = toNonEmptyString(input.userMessage);
const rawEffectiveText = toNonEmptyString(input.effectiveMessage);
const repairedUserText = rawUserText ? (0, addressTextRepair_1.repairAddressMojibakeText)(rawUserText) : null;
const repairedEffectiveText = rawEffectiveText ? (0, addressTextRepair_1.repairAddressMojibakeText)(rawEffectiveText) : null;
const rawSignalSourceText = `${repairedUserText ?? rawUserText ?? ""} ${repairedEffectiveText ?? rawEffectiveText ?? ""}`.trim();
const rawEntitySourceText = repairedUserText ?? rawUserText ?? repairedEffectiveText ?? rawEffectiveText ?? rawSignalSourceText;
const rawText = compactLower(rawSignalSourceText);
const rawReferentialDocumentExclusionSignal = hasReferentialDocumentExclusionFollowupSignal(repairedUserText ?? rawUserText ?? "");
const rawPrimaryBusinessOverviewSignal = hasBusinessOverviewSignal(rawText);
const explicitVatQuestionSignal = hasExplicitVatQuestionSignal(rawText);
const explicitVatMovementEvidenceSignal = hasExplicitVatMovementEvidenceSignal(rawText);
const explicitVatSuppressesBusinessOverviewContinuation = Boolean(explicitVatQuestionSignal && !rawPrimaryBusinessOverviewSignal);
const businessOverviewContinuationSignal = hasBusinessOverviewFollowupSeed(followupSeed) &&
hasBusinessOverviewContinuationSignal(rawText) &&
!explicitVatSuppressesBusinessOverviewContinuation;
const rawBusinessOverviewSignal = rawPrimaryBusinessOverviewSignal || businessOverviewContinuationSignal;
const rawLifecycleSignal = !rawBusinessOverviewSignal && hasLifecycleSignal(rawText);
const rawBidirectionalValueFlowSignal = !rawBusinessOverviewSignal && !rawLifecycleSignal && hasBidirectionalValueFlowSignal(rawText);
const rawValueFlowSignal = !rawBusinessOverviewSignal &&
!rawLifecycleSignal &&
(hasValueFlowSignal(rawText) || hasValueRankingSignal(rawText) || rawBidirectionalValueFlowSignal);
const rawMetadataSignal = !rawLifecycleSignal &&
!rawValueFlowSignal &&
!explicitVatMovementEvidenceSignal &&
!rawReferentialDocumentExclusionSignal &&
hasMetadataSignal(rawText);
const rawEntityResolutionSignal = !rawLifecycleSignal && !rawValueFlowSignal && !rawMetadataSignal && hasEntityResolutionSignal(rawText);
const rawPayoutSignal = rawValueFlowSignal && !rawBidirectionalValueFlowSignal && hasPayoutSignal(rawText);
const rawValueFlowAggregateQuestionSignal = rawValueFlowSignal && hasValueFlowAggregateQuestionSignal(rawText);
const monthlyAggregationSignal = hasMonthlyAggregationSignal(rawText);
const rawAllTimeScopeSignal = hasAllTimeScopeHint(rawText);
const dateScopeSignalText = stripNegatedTaxDateScopeClauses(rawText);
const negatedTaxDateScopeOnlySignal = dateScopeSignalText !== rawText &&
hasExplicitDateScopeLiteral(rawText) &&
!hasExplicitDateScopeLiteral(dateScopeSignalText);
const explicitDateScopeLiteralDetected = hasExplicitDateScopeLiteral(dateScopeSignalText);
const relativeCurrentDateHintDetected = hasRelativeCurrentDateHint(rawText);
const rawDateScope = collectDateScopeFromRawText(dateScopeSignalText);
const rawMetadataScopeHint = rawMetadataSignal || explicitVatMovementEvidenceSignal ? metadataScopeHintFromRawText(rawText) : null;
const rawTopicSwitchSignal = hasExplicitTopicSwitchSignal(rawText);
const rawEntityCandidate = rawEntityResolutionSignal ? rawEntityResolutionCandidate(rawEntitySourceText) : null;
const rawScopedEntityCandidate = !predecomposeEntities.counterparty &&
!predecomposeEntities.organization &&
(rawValueFlowSignal || rawLifecycleSignal || rawMetadataSignal || rawBusinessOverviewSignal)
? rawScopedEntityCandidateFromText(rawEntitySourceText)
: null;
const entityResolutionClarificationCandidate = followupSeed.pilotScope === "entity_resolution_search_v1" &&
followupSeed.entityResolutionStatus === "ambiguous"
? resolveEntityResolutionAmbiguityChoice(rawEntitySourceText, followupSeed.entityResolutionAmbiguityCandidates)
: null;
const entityResolutionSignal = rawEntityResolutionSignal || Boolean(rawEntityCandidate) || Boolean(entityResolutionClarificationCandidate);
const rawEntitySearchOverridesStaleScope = Boolean(rawEntityCandidate && entityResolutionSignal);
const rawDomain = toNonEmptyString(assistantTurnMeaning?.asked_domain_family);
const rawAction = toNonEmptyString(assistantTurnMeaning?.asked_action_family);
const rawAggregationAxis = toNonEmptyString(assistantTurnMeaning?.asked_aggregation_axis);
const unsupported = toNonEmptyString(assistantTurnMeaning?.unsupported_but_understood_family);
const broadBusinessEvaluationUnsupported = unsupported === "broad_business_evaluation";
const seededBusinessOverviewSignal = broadBusinessEvaluationUnsupported ||
rawDomain === "business_summary" ||
rawDomain === "business_overview" ||
rawAction === "broad_evaluation";
const inventoryReserveBusinessOverviewSignal = (rawBusinessOverviewSignal || seededBusinessOverviewSignal) &&
hasOrganizationLevelInventoryReserveLiquidationOverviewSignal(rawText);
const debtDueDateFollowupBusinessOverviewSignal = businessOverviewContinuationSignal && hasDebtDueDateBoundaryFollowupSignal(rawText);
const debtDueDateBusinessOverviewSignal = ((rawBusinessOverviewSignal || seededBusinessOverviewSignal) &&
hasOrganizationLevelDebtDueDateOverviewSignal(rawText)) ||
debtDueDateFollowupBusinessOverviewSignal;
const supplierQualityBusinessOverviewSignal = (rawBusinessOverviewSignal || seededBusinessOverviewSignal) && hasOrganizationLevelSupplierQualityOverviewSignal(rawText);
const profitMarginFollowupBusinessOverviewSignal = businessOverviewContinuationSignal && hasProfitMarginBoundaryFollowupSignal(rawText);
const profitMarginBusinessOverviewSignal = ((rawBusinessOverviewSignal || seededBusinessOverviewSignal) &&
hasOrganizationLevelProfitMarginBoundaryOverviewSignal(rawText)) ||
profitMarginFollowupBusinessOverviewSignal;
const businessOverviewActionFamily = inventoryReserveBusinessOverviewSignal
? "inventory_reserve_boundary"
: debtDueDateBusinessOverviewSignal
? "debt_due_date_boundary"
: supplierQualityBusinessOverviewSignal
? "vendor_risk_procurement_boundary"
: profitMarginBusinessOverviewSignal
? "profit_margin_boundary"
: "broad_evaluation";
const businessOverviewUnsupportedFamily = inventoryReserveBusinessOverviewSignal
? "inventory_reserve_liquidation_boundary"
: debtDueDateBusinessOverviewSignal
? "debt_due_date_boundary"
: supplierQualityBusinessOverviewSignal
? "vendor_risk_procurement_boundary"
: profitMarginBusinessOverviewSignal
? "profit_margin_boundary"
: "broad_business_evaluation";
const businessOverviewSignal = rawBusinessOverviewSignal ||
seededBusinessOverviewSignal;
const businessOverviewSeparateCounterpartySignal = Boolean(businessOverviewSignal && hasBusinessOverviewSeparateCounterpartySignal(rawText));
const businessOverviewSeparateCounterpartyCandidate = businessOverviewSeparateCounterpartySignal
? businessOverviewSeparateCounterpartyCandidateFromText(rawText)
: null;
const explicitIntentCandidate = toNonEmptyString(assistantTurnMeaning?.explicit_intent_candidate);
const currentTurnDocumentLaneSignal = rawAction === "list_documents";
const currentTurnMovementLaneSignal = rawAction === "list_movements";
const metadataDocumentHintSignal = currentTurnDocumentLaneSignal ||
hasUtf8DocumentLanePivotSignal(rawText) ||
hasSimpleDocumentLanePivotSignal(rawText) ||
hasDocumentEvidenceFollowupSignal(rawText) ||
hasPronounDocumentEvidenceFollowupSignal(rawText);
const metadataMovementHintSignal = currentTurnMovementLaneSignal ||
hasUtf8MovementLanePivotSignal(rawText) ||
hasSimpleMovementLanePivotSignal(rawText) ||
hasMovementEvidenceFollowupSignal(rawText) ||
hasPronounMovementEvidenceFollowupSignal(rawText);
const assistantTurnMeaningDateScope = toNonEmptyString(assistantTurnMeaning?.explicit_date_scope);
const rawAssistantTurnMeaningOrganizationScope = toNonEmptyString(assistantTurnMeaning?.explicit_organization_scope);
const assistantTurnMeaningOrganizationScope = isReferentialOrganizationPlaceholder(rawAssistantTurnMeaningOrganizationScope)
? null
: rawAssistantTurnMeaningOrganizationScope;
const rawOrganizationMentionSignal = hasOrganizationScopeSignalUtf8(rawText);
const rawOrganizationScope = extractOrganizationScopeFromRawText(rawUserText ?? rawEffectiveText ?? rawSignalSourceText);
const currentTurnFreshOrganizationScope = predecomposeEntities.organization ?? rawOrganizationScope;
const currentTurnOrganizationScope = currentTurnFreshOrganizationScope ?? assistantTurnMeaningOrganizationScope;
const followupCounterpartyIsMetadataOrganizationScope = Boolean(followupSeed.subjectResolutionOptional &&
followupSeed.counterparty &&
(followupSeed.metadataScopeHint ||
followupSeed.metadataSelectedEntitySet ||
followupSeed.metadataSelectedSurfaceObjects.length > 0) &&
(isInvalidEntityCandidate(followupSeed.counterparty) ||
sameScopedName(followupSeed.counterparty, followupSeed.organization) ||
sameScopedName(followupSeed.counterparty, currentTurnOrganizationScope)));
const businessOverviewSuppressesFollowupCounterparty = Boolean(businessOverviewSignal &&
!businessOverviewSeparateCounterpartySignal &&
(rawBusinessOverviewSignal ||
businessOverviewContinuationSignal ||
broadBusinessEvaluationUnsupported ||
rawDomain === "business_summary" ||
rawDomain === "business_overview" ||
rawAction === "broad_evaluation"));
const effectiveFollowupCounterparty = followupCounterpartyIsMetadataOrganizationScope
? null
: businessOverviewSuppressesFollowupCounterparty
? null
: followupSeed.counterparty;
const rawMetadataScopeOverridesFollowupEntity = Boolean(rawMetadataSignal &&
rawMetadataScopeHint &&
(effectiveFollowupCounterparty || followupSeed.discoveryEntity) &&
!sameScopedName(rawMetadataScopeHint, effectiveFollowupCounterparty ?? followupSeed.discoveryEntity));
const explicitOrganizationScopeSignal = Boolean(rawOrganizationMentionSignal && currentTurnOrganizationScope);
const organizationClarificationFollowupApplicable = Boolean(followupSeed.domain === "counterparty_value" &&
!effectiveFollowupCounterparty &&
currentTurnOrganizationScope &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal);
const rawOpenScopeValueFlowOrganizationSignal = Boolean(rawValueFlowSignal &&
!rawBidirectionalValueFlowSignal &&
explicitOrganizationScopeSignal);
const predecomposeOrganizationMirrorsCounterparty = sameScopedName(predecomposeEntities.counterparty, predecomposeEntities.organization);
const organizationMirrorsPredecomposeCounterparty = Boolean((rawBidirectionalValueFlowSignal ||
hasValueRankingSignal(rawText) ||
rawOpenScopeValueFlowOrganizationSignal ||
explicitOrganizationScopeSignal) &&
(sameScopedName(predecomposeEntities.counterparty, assistantTurnMeaningOrganizationScope) ||
predecomposeOrganizationMirrorsCounterparty));
const normalizedPredecomposeCounterparty = organizationMirrorsPredecomposeCounterparty
? null
: normalizeFollowupCounterpartyCandidate(predecomposeEntities.counterparty);
const predecomposeDateScope = collectDateScope(predecomposeContract);
const suppressFollowupBusinessOverviewSeed = Boolean(explicitVatSuppressesBusinessOverviewContinuation && hasBusinessOverviewFollowupSeed(followupSeed));
const periodClarificationFollowupApplicable = Boolean(followupSeed.domain &&
!suppressFollowupBusinessOverviewSeed &&
followupSeed.loopStatus === "awaiting_clarification" &&
followupSeed.loopPendingAxes.includes("period") &&
!rawLifecycleSignal &&
!rawMetadataSignal &&
(rawAllTimeScopeSignal ||
explicitDateScopeLiteralDetected ||
rawDateScope ||
relativeCurrentDateHintDetected ||
(predecomposeDateScope && !isImplicitCurrentDateScope(predecomposeDateScope))));
const followupDiscoverySeedApplicable = Boolean(followupSeed.domain &&
!suppressFollowupBusinessOverviewSeed &&
!rawLifecycleSignal &&
!rawMetadataSignal &&
(periodClarificationFollowupApplicable ||
(!rawValueFlowSignal &&
(monthlyAggregationSignal ||
rawAllTimeScopeSignal ||
explicitDateScopeLiteralDetected ||
predecomposeDateScope ||
explicitOrganizationScopeSignal ||
organizationClarificationFollowupApplicable))));
const metadataFollowupSeedApplicable = Boolean(followupSeed.domain === "metadata" &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
hasMetadataObjectHint(rawText));
const metadataLaneCarryoverAvailable = Boolean(effectiveFollowupCounterparty ||
followupSeed.discoveryEntity ||
rawMetadataScopeHint ||
followupSeed.metadataScopeHint ||
followupSeed.metadataSelectedEntitySet ||
followupSeed.metadataSelectedSurfaceObjects.length > 0);
const metadataGroundedDocumentFollowupApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
followupSeed.metadataRouteFamily === "document_evidence" &&
!followupSeed.metadataAmbiguityDetected &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
metadataDocumentHintSignal);
const metadataAmbiguityResolvedDocumentFollowupApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
followupSeed.metadataAmbiguityDetected &&
(followupSeed.metadataAmbiguityEntitySets.length === 0 ||
metadataEntitySetsSuggestDocumentLane(followupSeed.metadataAmbiguityEntitySets)) &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
metadataDocumentHintSignal);
const metadataGroundedMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
followupSeed.metadataRouteFamily === "movement_evidence" &&
!followupSeed.metadataAmbiguityDetected &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
metadataMovementHintSignal);
const metadataAmbiguityResolvedMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
followupSeed.metadataAmbiguityDetected &&
(followupSeed.metadataAmbiguityEntitySets.length === 0 ||
metadataEntitySetsSuggestMovementLane(followupSeed.metadataAmbiguityEntitySets)) &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
metadataMovementHintSignal);
const entityResolutionGroundedDocumentFollowupApplicable = Boolean(followupSeed.pilotScope === "entity_resolution_search_v1" &&
(effectiveFollowupCounterparty || followupSeed.discoveryEntity) &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
metadataDocumentHintSignal);
const entityResolutionClarifiedDocumentFollowupApplicable = Boolean(followupSeed.pilotScope === "entity_resolution_search_v1" &&
followupSeed.entityResolutionStatus === "ambiguous" &&
entityResolutionClarificationCandidate &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
metadataDocumentHintSignal);
const entityResolutionGroundedMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "entity_resolution_search_v1" &&
(effectiveFollowupCounterparty || followupSeed.discoveryEntity) &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
metadataMovementHintSignal);
const entityResolutionClarifiedMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "entity_resolution_search_v1" &&
followupSeed.entityResolutionStatus === "ambiguous" &&
entityResolutionClarificationCandidate &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
metadataMovementHintSignal);
const groundedValueFlowFollowupApplicable = Boolean(rawValueFlowSignal &&
!rawLifecycleSignal &&
!rawMetadataSignal &&
(effectiveFollowupCounterparty || followupSeed.discoveryEntity) &&
(followupSeed.pilotScope === "entity_resolution_search_v1" ||
followupSeed.pilotScope === "counterparty_document_evidence_query_documents_v1" ||
followupSeed.pilotScope === "counterparty_movement_evidence_query_movements_v1" ||
followupSeed.pilotScope === "counterparty_value_flow_query_movements_v1" ||
followupSeed.pilotScope === "counterparty_supplier_payout_query_movements_v1" ||
followupSeed.pilotScope === "counterparty_bidirectional_value_flow_query_movements_v1"));
const groundedValueFlowEvidenceSourceApplicable = Boolean((effectiveFollowupCounterparty || followupSeed.discoveryEntity) &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
(followupSeed.domain === "counterparty_value" ||
followupSeed.action === "turnover" ||
followupSeed.action === "payout" ||
followupSeed.action === "net_value_flow" ||
followupSeed.pilotScope === "counterparty_value_flow_query_movements_v1" ||
followupSeed.pilotScope === "counterparty_supplier_payout_query_movements_v1" ||
followupSeed.pilotScope === "counterparty_bidirectional_value_flow_query_movements_v1"));
const valueFlowGroundedDocumentFollowupApplicable = Boolean(groundedValueFlowEvidenceSourceApplicable && metadataDocumentHintSignal);
const valueFlowGroundedMovementFollowupApplicable = Boolean(groundedValueFlowEvidenceSourceApplicable && metadataMovementHintSignal);
const documentEvidenceGroundedMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "counterparty_document_evidence_query_documents_v1" &&
(effectiveFollowupCounterparty || followupSeed.discoveryEntity) &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
metadataMovementHintSignal);
const movementEvidenceGroundedDocumentFollowupApplicable = Boolean(followupSeed.pilotScope === "counterparty_movement_evidence_query_movements_v1" &&
(effectiveFollowupCounterparty || followupSeed.discoveryEntity) &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
metadataDocumentHintSignal);
const metadataScopedMovementEvidenceToDocumentFollowupApplicable = Boolean(followupSeed.pilotScope === "counterparty_movement_evidence_query_movements_v1" &&
followupSeed.subjectResolutionOptional &&
!effectiveFollowupCounterparty &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
metadataDocumentHintSignal);
const metadataScopedDocumentEvidenceToMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "counterparty_document_evidence_query_documents_v1" &&
followupSeed.subjectResolutionOptional &&
!effectiveFollowupCounterparty &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
metadataMovementHintSignal);
const metadataGroundedLaneContinuationApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
(followupSeed.metadataRouteFamily === "document_evidence" ||
followupSeed.metadataRouteFamily === "movement_evidence") &&
!followupSeed.metadataAmbiguityDetected &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
!metadataDocumentHintSignal &&
!metadataMovementHintSignal &&
hasMetadataDownstreamContinuationSignal(rawText));
const metadataGroundedCatalogLaneContinuationApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
followupSeed.metadataRouteFamily === "catalog_drilldown" &&
!followupSeed.metadataAmbiguityDetected &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
!metadataDocumentHintSignal &&
!metadataMovementHintSignal &&
hasMetadataDownstreamContinuationSignal(rawText));
const metadataAmbiguityCollapsedDocumentLaneContinuationApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
followupSeed.metadataAmbiguityDetected &&
metadataAmbiguityCollapsesToDocumentLane(followupSeed.metadataAmbiguityEntitySets) &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
!metadataDocumentHintSignal &&
!metadataMovementHintSignal &&
hasMetadataDownstreamContinuationSignal(rawText));
const metadataAmbiguityCollapsedMovementLaneContinuationApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
followupSeed.metadataAmbiguityDetected &&
metadataAmbiguityCollapsesToMovementLane(followupSeed.metadataAmbiguityEntitySets) &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
!metadataDocumentHintSignal &&
!metadataMovementHintSignal &&
hasMetadataDownstreamContinuationSignal(rawText));
const metadataAmbiguityLaneClarificationApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
followupSeed.metadataAmbiguityDetected &&
!metadataAmbiguityCollapsesToDocumentLane(followupSeed.metadataAmbiguityEntitySets) &&
!metadataAmbiguityCollapsesToMovementLane(followupSeed.metadataAmbiguityEntitySets) &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
!metadataDocumentHintSignal &&
!metadataMovementHintSignal &&
hasMetadataDownstreamContinuationSignal(rawText));
const metadataGroundedDocumentLaneApplicable = metadataGroundedDocumentFollowupApplicable ||
metadataAmbiguityResolvedDocumentFollowupApplicable ||
(followupSeed.subjectResolutionOptional &&
!effectiveFollowupCounterparty &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!currentTurnMovementLaneSignal &&
(!rawMetadataSignal || currentTurnDocumentLaneSignal) &&
(currentTurnDocumentLaneSignal ||
(followupSeed.domain === "documents" && followupSeed.action === "list_documents"))) ||
entityResolutionGroundedDocumentFollowupApplicable ||
entityResolutionClarifiedDocumentFollowupApplicable ||
valueFlowGroundedDocumentFollowupApplicable ||
movementEvidenceGroundedDocumentFollowupApplicable ||
metadataScopedMovementEvidenceToDocumentFollowupApplicable ||
(metadataGroundedLaneContinuationApplicable && followupSeed.metadataRouteFamily === "document_evidence") ||
metadataAmbiguityCollapsedDocumentLaneContinuationApplicable;
const metadataGroundedMovementLaneApplicable = metadataGroundedMovementFollowupApplicable ||
metadataAmbiguityResolvedMovementFollowupApplicable ||
(followupSeed.subjectResolutionOptional &&
!effectiveFollowupCounterparty &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!currentTurnDocumentLaneSignal &&
(!rawMetadataSignal || currentTurnMovementLaneSignal) &&
(currentTurnMovementLaneSignal ||
(followupSeed.domain === "movements" && followupSeed.action === "list_movements"))) ||
entityResolutionGroundedMovementFollowupApplicable ||
entityResolutionClarifiedMovementFollowupApplicable ||
valueFlowGroundedMovementFollowupApplicable ||
documentEvidenceGroundedMovementFollowupApplicable ||
metadataScopedDocumentEvidenceToMovementFollowupApplicable ||
(metadataGroundedLaneContinuationApplicable && followupSeed.metadataRouteFamily === "movement_evidence") ||
metadataAmbiguityCollapsedMovementLaneContinuationApplicable;
const effectiveMetadataFollowupSeedApplicable = metadataFollowupSeedApplicable &&
!metadataAmbiguityLaneClarificationApplicable &&
!metadataGroundedDocumentLaneApplicable &&
!metadataGroundedMovementLaneApplicable &&
!metadataGroundedCatalogLaneContinuationApplicable;
const seededDomain = metadataAmbiguityLaneClarificationApplicable
? "metadata"
: metadataGroundedDocumentLaneApplicable
? "documents"
: metadataGroundedMovementLaneApplicable
? "movements"
: metadataGroundedCatalogLaneContinuationApplicable
? "metadata"
: followupDiscoverySeedApplicable || effectiveMetadataFollowupSeedApplicable
? followupSeed.domain
: null;
const seededAction = metadataAmbiguityLaneClarificationApplicable
? "resolve_next_lane"
: metadataGroundedDocumentLaneApplicable
? "list_documents"
: metadataGroundedMovementLaneApplicable
? "list_movements"
: metadataGroundedCatalogLaneContinuationApplicable
? "inspect_catalog"
: followupDiscoverySeedApplicable || effectiveMetadataFollowupSeedApplicable
? followupSeed.action
: null;
const seededUnsupported = metadataAmbiguityLaneClarificationApplicable
? "metadata_lane_choice_clarification"
: metadataGroundedDocumentLaneApplicable
? "document_evidence"
: metadataGroundedMovementLaneApplicable
? "movement_evidence"
: metadataGroundedCatalogLaneContinuationApplicable
? "schema_surface"
: followupDiscoverySeedApplicable || effectiveMetadataFollowupSeedApplicable
? followupSeed.unsupported
: null;
const lifecycleSignal = !businessOverviewSignal && (rawLifecycleSignal || seededDomain === "counterparty_lifecycle");
const bidirectionalValueFlowSignal = !businessOverviewSignal &&
!lifecycleSignal &&
(rawBidirectionalValueFlowSignal || seededAction === "net_value_flow");
const valueFlowSignal = !businessOverviewSignal &&
!lifecycleSignal &&
!metadataGroundedMovementLaneApplicable &&
(rawValueFlowSignal || seededDomain === "counterparty_value");
const payoutSignal = valueFlowSignal &&
!bidirectionalValueFlowSignal &&
(rawPayoutSignal || seededAction === "payout");
const semanticDataNeed = metadataAmbiguityLaneClarificationApplicable
? "metadata lane clarification"
: semanticNeedFor({
domain: explicitVatMovementEvidenceSignal
? "movements"
: businessOverviewSignal
? "business_overview"
: rawDomain ?? seededDomain,
action: explicitVatMovementEvidenceSignal
? "list_movements"
: businessOverviewSignal
? businessOverviewActionFamily
: rawAction ?? seededAction,
unsupported: explicitVatMovementEvidenceSignal
? "movement_evidence"
: businessOverviewSignal
? businessOverviewUnsupportedFamily
: unsupported ?? seededUnsupported,
lifecycleSignal,
valueFlowSignal,
metadataSignal: rawMetadataSignal || effectiveMetadataFollowupSeedApplicable,
entityResolutionSignal: entityResolutionSignal &&
!metadataGroundedDocumentLaneApplicable &&
!metadataGroundedMovementLaneApplicable
});
const explicitCurrentCounterpartyCandidate = (normalizedPredecomposeCounterparty ?? rawScopedEntityCandidate) &&
!isReferentialEntityPlaceholder(normalizedPredecomposeCounterparty ?? rawScopedEntityCandidate ?? "")
? normalizedPredecomposeCounterparty ?? rawScopedEntityCandidate
: null;
const explicitCurrentCounterpartyOverridesFollowupEntity = Boolean(explicitCurrentCounterpartyCandidate &&
(effectiveFollowupCounterparty || followupSeed.discoveryEntity) &&
!sameScopedName(explicitCurrentCounterpartyCandidate, effectiveFollowupCounterparty ?? followupSeed.discoveryEntity) &&
(valueFlowSignal ||
lifecycleSignal ||
metadataGroundedDocumentLaneApplicable ||
metadataGroundedMovementLaneApplicable));
const metadataLaneScopeHint = rawEntitySearchOverridesStaleScope
? null
: explicitCurrentCounterpartyOverridesFollowupEntity
? null
: rawMetadataScopeHint ??
followupSeed.metadataScopeHint ??
followupSeed.discoveryEntity ??
followupSeed.metadataSelectedEntitySet ??
null;
const metadataScopedLaneWithoutSubject = Boolean((metadataGroundedMovementLaneApplicable ||
metadataGroundedDocumentLaneApplicable ||
explicitVatMovementEvidenceSignal) &&
!effectiveFollowupCounterparty &&
metadataLaneCarryoverAvailable);
const groundedFollowupEntity = metadataScopedLaneWithoutSubject
? null
: rawEntitySearchOverridesStaleScope
? null
: rawMetadataScopeOverridesFollowupEntity
? null
: explicitCurrentCounterpartyOverridesFollowupEntity
? null
: effectiveFollowupCounterparty ?? followupSeed.discoveryEntity;
const entityCandidates = entityResolutionSignal ? [] : [];
if (entityResolutionSignal) {
pushNormalizedEntityResolutionCandidate(entityCandidates, entityResolutionClarificationCandidate);
pushNormalizedEntityResolutionCandidate(entityCandidates, rawEntityCandidate);
for (const candidate of collectEntityCandidates(assistantTurnMeaning?.explicit_entity_candidates)) {
if (!rawEntitySearchOverridesStaleScope || sameScopedName(candidate, rawEntityCandidate)) {
pushNormalizedEntityResolutionCandidate(entityCandidates, candidate);
}
}
if (!rawEntitySearchOverridesStaleScope || sameScopedName(normalizedPredecomposeCounterparty, rawEntityCandidate)) {
pushNormalizedEntityResolutionCandidate(entityCandidates, normalizedPredecomposeCounterparty);
}
if (!rawEntitySearchOverridesStaleScope) {
pushNormalizedEntityResolutionCandidate(entityCandidates, effectiveFollowupCounterparty);
}
}
else {
if (groundedFollowupEntity) {
pushUnique(entityCandidates, groundedFollowupEntity);
}
for (const candidate of collectEntityCandidates(assistantTurnMeaning?.explicit_entity_candidates)) {
pushScopedEntityCandidate(entityCandidates, candidate, groundedFollowupEntity);
}
pushScopedEntityCandidate(entityCandidates, businessOverviewSeparateCounterpartyCandidate, groundedFollowupEntity);
pushScopedEntityCandidate(entityCandidates, normalizedPredecomposeCounterparty, groundedFollowupEntity);
pushScopedEntityCandidate(entityCandidates, rawScopedEntityCandidate, groundedFollowupEntity);
if (!groundedFollowupEntity) {
if (!rawMetadataScopeOverridesFollowupEntity) {
pushScopedEntityCandidate(entityCandidates, effectiveFollowupCounterparty, null);
}
if (!metadataScopedLaneWithoutSubject && !rawMetadataScopeOverridesFollowupEntity) {
pushScopedEntityCandidate(entityCandidates, followupSeed.discoveryEntity, null);
}
}
pushScopedEntityCandidate(entityCandidates, rawEntityCandidate, groundedFollowupEntity);
}
const businessOverviewSeparateCounterpartyDisplayCandidate = businessOverviewSeparateCounterpartySignal
? preferredScopedDisplayName(businessOverviewSeparateCounterpartyCandidate, [
groundedFollowupEntity,
effectiveFollowupCounterparty,
followupSeed.discoveryEntity,
normalizedPredecomposeCounterparty,
rawScopedEntityCandidate,
rawEntityCandidate,
...entityCandidates
])
: null;
const businessOverviewSeparateEntityCandidates = businessOverviewSeparateCounterpartyDisplayCandidate
? [businessOverviewSeparateCounterpartyDisplayCandidate]
: [];
if ((rawMetadataSignal || metadataFollowupSeedApplicable) &&
!groundedFollowupEntity &&
!metadataScopedLaneWithoutSubject) {
if (!rawMetadataScopeOverridesFollowupEntity) {
pushUnique(entityCandidates, followupSeed.discoveryEntity);
}
pushUnique(entityCandidates, rawMetadataScopeHint);
}
const openScopeValueFlowWithoutCounterparty = valueFlowSignal && !explicitCurrentCounterpartyCandidate && !effectiveFollowupCounterparty;
const valueFlowOrganizationStaysScope = openScopeValueFlowWithoutCounterparty &&
Boolean(bidirectionalValueFlowSignal ||
hasValueRankingSignal(rawText) ||
rawOpenScopeValueFlowOrganizationSignal ||
explicitOrganizationScopeSignal ||
organizationClarificationFollowupApplicable ||
followupSeed.organization);
const openScopeValueFlowWithoutResolvedCounterparty = Boolean(valueFlowSignal && !explicitCurrentCounterpartyCandidate && !effectiveFollowupCounterparty);
if (openScopeValueFlowWithoutCounterparty && !valueFlowOrganizationStaysScope) {
pushUnique(entityCandidates, predecomposeEntities.organization);
pushUnique(entityCandidates, followupSeed.organization);
}
const explicitOrganizationScope = rawEntitySearchOverridesStaleScope && !currentTurnFreshOrganizationScope
? null
: valueFlowOrganizationStaysScope || !openScopeValueFlowWithoutCounterparty
? (rawEntitySearchOverridesStaleScope ? currentTurnFreshOrganizationScope : currentTurnOrganizationScope) ??
followupSeed.organization
: null;
if (explicitCurrentCounterpartyCandidate &&
(valueFlowSignal || lifecycleSignal || metadataGroundedDocumentLaneApplicable || metadataGroundedMovementLaneApplicable)) {
for (let index = entityCandidates.length - 1; index >= 0; index -= 1) {
const candidate = entityCandidates[index];
if (!candidate || sameScopedName(candidate, explicitCurrentCounterpartyCandidate)) {
continue;
}
if ((metadataLaneScopeHint && sameScopedName(candidate, metadataLaneScopeHint)) ||
(explicitOrganizationScope && sameScopedName(candidate, explicitOrganizationScope)) ||
(followupSeed.organization && sameScopedName(candidate, followupSeed.organization)) ||
(effectiveFollowupCounterparty &&
!sameScopedName(effectiveFollowupCounterparty, explicitCurrentCounterpartyCandidate) &&
sameScopedName(candidate, effectiveFollowupCounterparty))) {
entityCandidates.splice(index, 1);
}
}
}
if (valueFlowOrganizationStaysScope && explicitOrganizationScope) {
for (let index = entityCandidates.length - 1; index >= 0; index -= 1) {
if (entityCandidates[index] === explicitOrganizationScope) {
entityCandidates.splice(index, 1);
}
}
}
const clarificationLoopStillNeedsPeriod = Boolean(followupSeed.loopStatus === "awaiting_clarification" && followupSeed.loopPendingAxes.includes("period"));
const businessOverviewRawWithoutDateScope = Boolean(businessOverviewSignal &&
!rawAllTimeScopeSignal &&
!explicitDateScopeLiteralDetected &&
!rawDateScope &&
!relativeCurrentDateHintDetected);
const predecomposeDateScopeCountsAsCurrentTurnPeriod = Boolean(predecomposeDateScope &&
!isImplicitCurrentDateScope(predecomposeDateScope) &&
!businessOverviewRawWithoutDateScope);
const currentTurnCarriesExplicitPeriod = Boolean(explicitDateScopeLiteralDetected ||
rawDateScope ||
relativeCurrentDateHintDetected ||
predecomposeDateScopeCountsAsCurrentTurnPeriod);
const suppressImplicitCurrentDateScope = Boolean(!currentTurnCarriesExplicitPeriod &&
(clarificationLoopStillNeedsPeriod ||
businessOverviewSignal ||
openScopeValueFlowWithoutResolvedCounterparty ||
valueFlowGroundedDocumentFollowupApplicable ||
valueFlowGroundedMovementFollowupApplicable ||
(valueFlowOrganizationStaysScope && (Boolean(followupSeed.rankingNeed) || bidirectionalValueFlowSignal))));
const suppressNegatedTaxOnlyDateScope = Boolean(businessOverviewSignal && negatedTaxDateScopeOnlySignal);
const topicSwitchSuppressesFollowupScope = Boolean(rawTopicSwitchSignal &&
(rawMetadataSignal ||
businessOverviewSignal ||
rawEntitySearchOverridesStaleScope ||
explicitOrganizationScopeSignal ||
rawAllTimeScopeSignal));
const normalizedPredecomposeDateScope = (rawEntitySearchOverridesStaleScope && !currentTurnCarriesExplicitPeriod) ||
suppressNegatedTaxOnlyDateScope ||
businessOverviewRawWithoutDateScope ||
(suppressImplicitCurrentDateScope && isImplicitCurrentDateScope(predecomposeDateScope))
? null
: predecomposeDateScope;
const normalizedAssistantTurnMeaningDateScope = rawEntitySearchOverridesStaleScope ||
suppressNegatedTaxOnlyDateScope ||
(suppressImplicitCurrentDateScope && isImplicitCurrentDateScope(assistantTurnMeaningDateScope))
? null
: assistantTurnMeaningDateScope;
const normalizedFollowupDateScope = rawEntitySearchOverridesStaleScope ||
suppressNegatedTaxOnlyDateScope ||
topicSwitchSuppressesFollowupScope ||
(suppressImplicitCurrentDateScope && isImplicitCurrentDateScope(followupSeed.dateScope))
? null
: followupSeed.dateScope;
const businessOverviewRawYearOverridesPredecomposeAsOf = Boolean(businessOverviewSignal &&
rawDateScope &&
/^\d{4}$/.test(rawDateScope) &&
normalizedPredecomposeDateScope &&
normalizedPredecomposeDateScope.startsWith(`${rawDateScope}-`));
const explicitDateScope = rawAllTimeScopeSignal
? null
: normalizedAssistantTurnMeaningDateScope ??
(businessOverviewRawYearOverridesPredecomposeAsOf ? rawDateScope : normalizedPredecomposeDateScope) ??
rawDateScope ??
normalizedFollowupDateScope;
const followupDateScopeApplied = Boolean(!rawAllTimeScopeSignal &&
!normalizedAssistantTurnMeaningDateScope &&
!normalizedPredecomposeDateScope &&
!rawDateScope &&
normalizedFollowupDateScope);
const clarificationLoopSeedApplied = Boolean(followupSeed.loopStatus === "awaiting_clarification" && followupSeed.loopSelectedChainId);
const turnMeaning = {
raw_message: repairedUserText ?? rawUserText ?? null,
effective_message: repairedEffectiveText ?? rawEffectiveText ?? null,
asked_domain_family: businessOverviewSignal
? "business_overview"
: lifecycleSignal
? "counterparty_lifecycle"
: valueFlowSignal
? "counterparty_value"
: explicitVatMovementEvidenceSignal
? "movements"
: metadataGroundedMovementLaneApplicable
? "movements"
: metadataGroundedDocumentLaneApplicable
? "documents"
: entityResolutionSignal
? "entity_resolution"
: rawMetadataSignal || effectiveMetadataFollowupSeedApplicable
? "metadata"
: rawDomain ?? seededDomain,
asked_action_family: businessOverviewSignal
? businessOverviewActionFamily
: lifecycleSignal
? "activity_duration"
: valueFlowSignal
? bidirectionalValueFlowSignal
? "net_value_flow"
: payoutSignal
? "payout"
: rawAction ?? seededAction ?? "turnover"
: explicitVatMovementEvidenceSignal
? "list_movements"
: metadataGroundedMovementLaneApplicable
? "list_movements"
: metadataGroundedDocumentLaneApplicable
? "list_documents"
: entityResolutionSignal
? "search_business_entity"
: rawMetadataSignal || effectiveMetadataFollowupSeedApplicable
? metadataActionFromRawText(rawText) ?? seededAction
: rawAction ?? seededAction,
asked_aggregation_axis: monthlyAggregationSignal ? "month" : rawAggregationAxis,
seeded_ranking_need: valueFlowSignal && followupSeed.rankingNeed && !rawEntitySearchOverridesStaleScope
? followupSeed.rankingNeed
: undefined,
explicit_entity_candidates: businessOverviewSignal ? [] : entityCandidates,
business_overview_separate_entity_candidates: businessOverviewSeparateEntityCandidates,
previous_counterparty_value_flow_bundle: businessOverviewSignal && followupSeed.previousBidirectionalValueFlow
? followupSeed.previousBidirectionalValueFlow
: undefined,
previous_counterparty_document_bundle: businessOverviewSignal && followupSeed.previousDocumentSummary ? followupSeed.previousDocumentSummary : undefined,
metadata_ambiguity_entity_sets: metadataAmbiguityLaneClarificationApplicable && followupSeed.metadataAmbiguityEntitySets.length > 0
? followupSeed.metadataAmbiguityEntitySets
: undefined,
metadata_scope_hint: metadataLaneScopeHint,
explicit_organization_scope: explicitOrganizationScope,
explicit_date_scope: explicitDateScope,
subject_resolution_optional: metadataScopedLaneWithoutSubject || undefined,
unsupported_but_understood_family: businessOverviewSignal
? businessOverviewUnsupportedFamily
: unsupported ??
(lifecycleSignal
? "counterparty_lifecycle"
: valueFlowSignal
? bidirectionalValueFlowSignal
? "counterparty_bidirectional_value_flow_or_netting"
: payoutSignal
? "counterparty_payouts_or_outflow"
: seededUnsupported ?? "counterparty_value_or_turnover"
: metadataGroundedMovementLaneApplicable
? "movement_evidence"
: metadataGroundedDocumentLaneApplicable
? "document_evidence"
: explicitVatMovementEvidenceSignal
? "movement_evidence"
: metadataAmbiguityLaneClarificationApplicable
? "metadata_lane_choice_clarification"
: entityResolutionSignal
? "entity_resolution"
: rawMetadataSignal || effectiveMetadataFollowupSeedApplicable
? "1c_metadata_surface"
: followupDiscoverySeedApplicable
? seededUnsupported
: null),
stale_replay_forbidden: Boolean(assistantTurnMeaning?.stale_replay_forbidden ||
businessOverviewSignal ||
unsupported ||
lifecycleSignal ||
valueFlowSignal ||
explicitVatMovementEvidenceSignal ||
metadataGroundedMovementLaneApplicable ||
metadataGroundedDocumentLaneApplicable ||
metadataAmbiguityLaneClarificationApplicable ||
entityResolutionSignal ||
rawMetadataSignal ||
effectiveMetadataFollowupSeedApplicable ||
followupDiscoverySeedApplicable)
};
const cleanTurnMeaning = {};
if (toNonEmptyString(turnMeaning.raw_message)) {
cleanTurnMeaning.raw_message = turnMeaning.raw_message;
}
if (toNonEmptyString(turnMeaning.effective_message)) {
cleanTurnMeaning.effective_message = turnMeaning.effective_message;
}
if (toNonEmptyString(turnMeaning.asked_domain_family)) {
cleanTurnMeaning.asked_domain_family = turnMeaning.asked_domain_family;
}
if (toNonEmptyString(turnMeaning.asked_action_family)) {
cleanTurnMeaning.asked_action_family = turnMeaning.asked_action_family;
}
if (toNonEmptyString(turnMeaning.asked_aggregation_axis)) {
cleanTurnMeaning.asked_aggregation_axis = turnMeaning.asked_aggregation_axis;
}
if (toNonEmptyString(turnMeaning.seeded_ranking_need)) {
cleanTurnMeaning.seeded_ranking_need = turnMeaning.seeded_ranking_need;
}
if ((turnMeaning.explicit_entity_candidates?.length ?? 0) > 0) {
cleanTurnMeaning.explicit_entity_candidates = turnMeaning.explicit_entity_candidates;
}
if ((turnMeaning.business_overview_separate_entity_candidates?.length ?? 0) > 0) {
cleanTurnMeaning.business_overview_separate_entity_candidates = turnMeaning.business_overview_separate_entity_candidates;
}
if (toRecordObject(turnMeaning.previous_counterparty_value_flow_bundle)) {
cleanTurnMeaning.previous_counterparty_value_flow_bundle = turnMeaning.previous_counterparty_value_flow_bundle;
}
if (toRecordObject(turnMeaning.previous_counterparty_document_bundle)) {
cleanTurnMeaning.previous_counterparty_document_bundle = turnMeaning.previous_counterparty_document_bundle;
}
if ((turnMeaning.metadata_ambiguity_entity_sets?.length ?? 0) > 0) {
cleanTurnMeaning.metadata_ambiguity_entity_sets = turnMeaning.metadata_ambiguity_entity_sets;
}
if (toNonEmptyString(turnMeaning.metadata_scope_hint)) {
cleanTurnMeaning.metadata_scope_hint = turnMeaning.metadata_scope_hint;
}
if (toNonEmptyString(turnMeaning.explicit_organization_scope)) {
cleanTurnMeaning.explicit_organization_scope = turnMeaning.explicit_organization_scope;
}
if (toNonEmptyString(turnMeaning.explicit_date_scope)) {
cleanTurnMeaning.explicit_date_scope = turnMeaning.explicit_date_scope;
}
if (turnMeaning.subject_resolution_optional) {
cleanTurnMeaning.subject_resolution_optional = true;
}
if (toNonEmptyString(turnMeaning.unsupported_but_understood_family)) {
cleanTurnMeaning.unsupported_but_understood_family = turnMeaning.unsupported_but_understood_family;
}
if (turnMeaning.stale_replay_forbidden) {
cleanTurnMeaning.stale_replay_forbidden = true;
}
const currentTurnValueFlowExactOverrideApplicable = Boolean(valueFlowSignal &&
explicitIntentCandidate &&
(rawValueFlowAggregateQuestionSignal || hasValueRankingSignal(rawText)) &&
semanticDataNeed &&
(entityCandidates.length > 0 || explicitOrganizationScope || openScopeValueFlowWithoutResolvedCounterparty));
const runDiscovery = shouldRunDiscovery({
unsupported: explicitVatMovementEvidenceSignal
? "movement_evidence"
: businessOverviewSignal
? "broad_business_evaluation"
: unsupported ?? seededUnsupported,
lifecycleSignal,
valueFlowSignal,
metadataSignal: rawMetadataSignal || effectiveMetadataFollowupSeedApplicable,
entityResolutionSignal,
semanticDataNeed,
explicitIntentCandidate,
followupDiscoverySeedApplicable: followupDiscoverySeedApplicable ||
Boolean(entityResolutionClarificationCandidate) ||
effectiveMetadataFollowupSeedApplicable ||
metadataAmbiguityLaneClarificationApplicable ||
metadataGroundedMovementLaneApplicable ||
metadataGroundedDocumentLaneApplicable ||
groundedValueFlowFollowupApplicable,
forceDiscoveryOverExplicitIntent: businessOverviewSignal ||
explicitVatMovementEvidenceSignal ||
Boolean(entityResolutionClarificationCandidate) ||
organizationClarificationFollowupApplicable ||
periodClarificationFollowupApplicable ||
metadataAmbiguityLaneClarificationApplicable ||
metadataGroundedMovementLaneApplicable ||
metadataGroundedDocumentLaneApplicable ||
groundedValueFlowFollowupApplicable ||
currentTurnValueFlowExactOverrideApplicable
});
const hasTurnMeaning = Object.keys(cleanTurnMeaning).length > 0;
const sourceSignal = rawEntitySearchOverridesStaleScope
? "raw_text"
: assistantTurnMeaning
? "assistant_turn_meaning"
: followupDiscoverySeedApplicable ||
Boolean(entityResolutionClarificationCandidate) ||
effectiveMetadataFollowupSeedApplicable ||
metadataAmbiguityLaneClarificationApplicable
? "followup_context"
: metadataGroundedMovementLaneApplicable
? "followup_context"
: metadataGroundedDocumentLaneApplicable
? "followup_context"
: explicitVatMovementEvidenceSignal
? "raw_text"
: predecomposeContract
? "predecompose_contract"
: lifecycleSignal
? "raw_text"
: valueFlowSignal
? "raw_text"
: entityResolutionSignal
? "raw_text"
: rawMetadataSignal || effectiveMetadataFollowupSeedApplicable
? "raw_text"
: "none";
if (lifecycleSignal) {
pushReason(reasonCodes, "mcp_discovery_lifecycle_signal_detected");
}
if (valueFlowSignal) {
pushReason(reasonCodes, "mcp_discovery_value_flow_signal_detected");
}
if (rawMetadataSignal) {
pushReason(reasonCodes, "mcp_discovery_metadata_signal_detected");
}
if (explicitVatMovementEvidenceSignal) {
pushReason(reasonCodes, "mcp_discovery_vat_movement_evidence_signal_detected");
}
if (entityResolutionSignal) {
pushReason(reasonCodes, "mcp_discovery_entity_resolution_signal_detected");
}
if (rawMetadataScopeHint) {
pushReason(reasonCodes, "mcp_discovery_metadata_scope_hint_from_raw_text");
}
if (rawMetadataScopeOverridesFollowupEntity) {
pushReason(reasonCodes, "mcp_discovery_raw_metadata_scope_overrides_stale_entity");
}
if (topicSwitchSuppressesFollowupScope) {
pushReason(reasonCodes, "mcp_discovery_topic_switch_suppressed_followup_scope");
}
if (rawEntityCandidate) {
pushReason(reasonCodes, "mcp_discovery_entity_scope_from_raw_entity_search");
}
if (entityResolutionClarificationCandidate) {
pushReason(reasonCodes, "mcp_discovery_entity_resolution_clarification_candidate_selected");
}
if (organizationClarificationFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_organization_clarification_followup_from_followup_context");
}
if (periodClarificationFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_period_clarification_followup_from_followup_context");
}
if (payoutSignal) {
pushReason(reasonCodes, "mcp_discovery_payout_signal_detected");
}
if (bidirectionalValueFlowSignal) {
pushReason(reasonCodes, "mcp_discovery_bidirectional_value_flow_signal_detected");
}
if (monthlyAggregationSignal) {
pushReason(reasonCodes, "mcp_discovery_monthly_aggregation_signal_detected");
}
if (rawAllTimeScopeSignal) {
pushReason(reasonCodes, "mcp_discovery_all_time_scope_signal_detected");
}
if (suppressNegatedTaxOnlyDateScope) {
pushReason(reasonCodes, "mcp_discovery_negated_tax_period_scope_suppressed");
}
if (followupDiscoverySeedApplicable) {
pushReason(reasonCodes, "mcp_discovery_seeded_from_followup_context");
}
if (clarificationLoopSeedApplied) {
pushReason(reasonCodes, "mcp_discovery_resumed_from_saved_loop_state");
}
if (effectiveMetadataFollowupSeedApplicable) {
pushReason(reasonCodes, "mcp_discovery_metadata_seeded_from_followup_context");
}
if (metadataGroundedDocumentFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_metadata_grounded_document_followup");
}
if (metadataAmbiguityResolvedDocumentFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_metadata_ambiguity_resolved_to_document_lane");
}
if (metadataGroundedMovementFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_metadata_grounded_movement_followup");
}
if (metadataAmbiguityResolvedMovementFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_metadata_ambiguity_resolved_to_movement_lane");
}
if (metadataScopedLaneWithoutSubject) {
pushReason(reasonCodes, "mcp_discovery_metadata_scoped_lane_without_subject");
}
if (entityResolutionGroundedDocumentFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_entity_resolution_grounded_document_followup");
}
if (entityResolutionClarifiedDocumentFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_entity_resolution_clarified_document_followup");
}
if (entityResolutionGroundedMovementFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_entity_resolution_grounded_movement_followup");
}
if (entityResolutionClarifiedMovementFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_entity_resolution_clarified_movement_followup");
}
if (valueFlowGroundedDocumentFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_value_flow_grounded_document_followup");
}
if (valueFlowGroundedMovementFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_value_flow_grounded_movement_followup");
}
if (groundedValueFlowFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_grounded_value_flow_followup");
}
if (currentTurnValueFlowExactOverrideApplicable) {
pushReason(reasonCodes, "mcp_discovery_current_turn_value_flow_overrides_supported_exact");
}
if (documentEvidenceGroundedMovementFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_document_evidence_grounded_movement_followup");
}
if (movementEvidenceGroundedDocumentFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_movement_evidence_grounded_document_followup");
}
if (metadataScopedMovementEvidenceToDocumentFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_metadata_scoped_movement_to_document_followup");
}
if (metadataScopedDocumentEvidenceToMovementFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_metadata_scoped_document_to_movement_followup");
}
if (metadataGroundedLaneContinuationApplicable) {
pushReason(reasonCodes, "mcp_discovery_metadata_grounded_lane_continuation");
}
if (metadataGroundedCatalogLaneContinuationApplicable) {
pushReason(reasonCodes, "mcp_discovery_metadata_grounded_catalog_continuation");
}
if (metadataAmbiguityCollapsedDocumentLaneContinuationApplicable) {
pushReason(reasonCodes, "mcp_discovery_metadata_ambiguity_collapsed_to_document_lane");
}
if (metadataAmbiguityCollapsedMovementLaneContinuationApplicable) {
pushReason(reasonCodes, "mcp_discovery_metadata_ambiguity_collapsed_to_movement_lane");
}
if (metadataAmbiguityLaneClarificationApplicable) {
pushReason(reasonCodes, "mcp_discovery_metadata_ambiguity_requires_lane_choice");
}
if (unsupported) {
pushReason(reasonCodes, "mcp_discovery_unsupported_but_understood_turn");
}
if (businessOverviewSignal) {
pushReason(reasonCodes, "mcp_discovery_broad_business_evaluation_route_candidate");
}
if (businessOverviewContinuationSignal) {
pushReason(reasonCodes, "mcp_discovery_business_overview_continuation_from_followup_context");
}
if (profitMarginFollowupBusinessOverviewSignal) {
pushReason(reasonCodes, "mcp_discovery_business_overview_profit_margin_followup_boundary");
}
if (debtDueDateFollowupBusinessOverviewSignal) {
pushReason(reasonCodes, "mcp_discovery_business_overview_debt_due_date_followup_boundary");
}
if (explicitVatSuppressesBusinessOverviewContinuation) {
pushReason(reasonCodes, "mcp_discovery_business_overview_continuation_suppressed_by_explicit_vat_question");
}
if (businessOverviewSuppressesFollowupCounterparty) {
pushReason(reasonCodes, "mcp_discovery_business_overview_suppressed_stale_counterparty");
}
if (businessOverviewSeparateCounterpartySignal) {
pushReason(reasonCodes, "mcp_discovery_business_overview_preserved_explicit_counterparty_summary_scope");
}
if (businessOverviewSeparateCounterpartyCandidate) {
pushReason(reasonCodes, "mcp_discovery_business_overview_counterparty_from_summary_text");
}
if (businessOverviewRawYearOverridesPredecomposeAsOf) {
pushReason(reasonCodes, "mcp_discovery_business_overview_raw_year_overrode_predecompose_as_of_scope");
}
if (!(valueFlowOrganizationStaysScope && normalizedPredecomposeCounterparty === explicitOrganizationScope) &&
normalizedPredecomposeCounterparty) {
pushReason(reasonCodes, "mcp_discovery_counterparty_from_predecompose");
}
if (rawScopedEntityCandidate && !normalizedPredecomposeCounterparty) {
pushReason(reasonCodes, "mcp_discovery_counterparty_from_raw_scope");
}
if (effectiveFollowupCounterparty &&
!rawEntitySearchOverridesStaleScope &&
!rawMetadataScopeOverridesFollowupEntity) {
pushReason(reasonCodes, "mcp_discovery_counterparty_from_followup_context");
}
if (followupDateScopeApplied) {
pushReason(reasonCodes, "mcp_discovery_date_scope_from_followup_context");
}
if (metadataSurfaceRef) {
pushReason(reasonCodes, "mcp_discovery_metadata_surface_ref_from_followup_context");
}
if (metadataSurfaceRef?.recommended_next_primitive) {
pushReason(reasonCodes, "mcp_discovery_metadata_next_primitive_from_followup_context");
}
if (entityCandidates.length > 0) {
pushReason(reasonCodes, "mcp_discovery_entity_scope_available");
}
if (!runDiscovery) {
pushReason(reasonCodes, "mcp_discovery_not_applicable_for_supported_exact_turn");
}
if (runDiscovery && !hasTurnMeaning) {
pushReason(reasonCodes, "mcp_discovery_turn_meaning_missing");
}
const dataNeedGraphTurnMeaning = businessOverviewSeparateCounterpartySignal && cleanTurnMeaning.explicit_entity_candidates
? {
...cleanTurnMeaning,
explicit_entity_candidates: []
}
: cleanTurnMeaning;
const dataNeedGraph = runDiscovery && hasTurnMeaning
? (0, assistantMcpDiscoveryDataNeedGraph_1.buildAssistantMcpDiscoveryDataNeedGraph)({
semanticDataNeed,
rawUtterance: rawSignalSourceText,
turnMeaning: dataNeedGraphTurnMeaning
})
: null;
if (dataNeedGraph) {
pushReason(reasonCodes, "mcp_discovery_data_need_graph_built");
}
return {
schema_version: exports.ASSISTANT_MCP_DISCOVERY_TURN_INPUT_SCHEMA_VERSION,
policy_owner: "assistantMcpDiscoveryTurnInputAdapter",
adapter_status: !runDiscovery ? "not_applicable" : hasTurnMeaning ? "ready" : "needs_more_context",
should_run_discovery: runDiscovery,
semantic_data_need: runDiscovery ? semanticDataNeed : null,
data_need_graph: dataNeedGraph,
metadata_surface_ref: runDiscovery ? metadataSurfaceRef : null,
turn_meaning_ref: runDiscovery && hasTurnMeaning ? cleanTurnMeaning : null,
source_signal: sourceSignal,
reason_codes: reasonCodes
};
}