Этап 4 / Волна 11: объектный трейс по бизнес-якорям, доменное заземление, cleanup утечки дебага

This commit is contained in:
2026-03-28 13:12:09 +03:00
parent 553a5c407a
commit 8b84f5e989
34 changed files with 5517 additions and 173 deletions
@@ -8,6 +8,8 @@ import * as assistantDataLayer_1 from "./assistantDataLayer";
import * as assistantSessionLogger_1 from "./assistantSessionLogger";
import * as investigationState_1 from "./investigationState";
import * as retrievalResultNormalizer_1 from "./retrievalResultNormalizer";
import * as questionTypeResolver_1 from "./questionTypeResolver";
import * as companyAnchorResolver_1 from "./companyAnchorResolver";
function retrievalSummaryForRoute(route) {
if (route === "store_canonical")
return "Canonical accounting data path selected.";
@@ -832,6 +834,26 @@ function extractFollowupAccountAnchorsLoose(text) {
}
return Array.from(new Set(anchors));
}
function inferP0DomainFromMessage(text) {
const lower = String(text ?? "").toLowerCase();
const accountTokens = extractAccountTokens(lower);
const hasVatAccount = accountTokens.some((token) => /^(?:19|68)(?:\.|$)/.test(token));
const hasSettlementAccount = accountTokens.some((token) => /^(?:51|60|62|76)(?:\.|$)/.test(token));
const hasMonthCloseAccount = accountTokens.some((token) => /^(?:97|2\d|3\d|4[0-4])(?:\.|$)/.test(token));
const vatLexical = /(?:ндс|vat|счет[\s-]?фактур|сч[её]т[\s-]?фактур|книг[аи]\s+(?:покуп|продаж)|налогов)/i.test(lower);
const settlementLexical = /(?:долг|аванс|зач[её]т|взаимозач|расч[её]т|оплат|платеж|платёж|постав|покупател)/i.test(lower);
const monthCloseLexical = /(?:закрыти[ея]\s+месяц|закрытие счетов|регламентн|косвенн|затрат|распределени|рбп|амортиз|финансовых результат)/i.test(lower);
if (hasVatAccount || vatLexical) {
return "vat_document_register_book";
}
if (monthCloseLexical || hasMonthCloseAccount) {
return "month_close_costs_20_44";
}
if (hasSettlementAccount || settlementLexical) {
return "settlements_60_62";
}
return null;
}
function hasStrongFollowupAnchors(userMessage, state) {
const explicitPeriod = extractNormalizedPeriodLiteral(userMessage);
if (explicitPeriod && state.focus.period && explicitPeriod !== state.focus.period) {
@@ -840,6 +862,14 @@ function hasStrongFollowupAnchors(userMessage, state) {
return true;
}
}
const inferredDomain = inferP0DomainFromMessage(userMessage);
const activeDomain = compactWhitespace(state.followup_context?.active_domain ?? state.focus.domain ?? "");
if (inferredDomain && activeDomain && inferredDomain !== activeDomain) {
const domainLooksLikeFollowupRefinement = hasFollowupMarker(userMessage) && hasReferentialPointer(userMessage);
if (!domainLooksLikeFollowupRefinement) {
return true;
}
}
const explicitAccounts = extractAccountTokens(userMessage);
const followupAccounts = explicitAccounts.length > 0 ? explicitAccounts : extractFollowupAccountAnchorsLoose(userMessage);
if (followupAccounts.length > 0) {
@@ -1155,6 +1185,8 @@ export class AssistantService {
const focusDomainHint = followupBinding.usage?.applied
? session.investigation_state?.followup_context?.active_domain ?? session.investigation_state?.focus.domain ?? null
: null;
const questionTypeClass = (0, questionTypeResolver_1.resolveQuestionType)(userMessage);
const companyAnchors = (0, companyAnchorResolver_1.resolveCompanyAnchors)(userMessage);
const composition = (0, answerComposer_1.composeAssistantAnswer)({
userMessage,
routeSummary: normalized.route_hint_summary,
@@ -1163,6 +1195,8 @@ export class AssistantService {
coverageReport: coverageEvaluation.coverage,
groundingCheck,
focusDomainHint,
questionTypeHint: questionTypeClass,
companyAnchors,
enableAnswerPolicyV11: config_1.FEATURE_ASSISTANT_ANSWER_POLICY_V11,
enableProblemCentricAnswerV1: config_1.FEATURE_ASSISTANT_PROBLEM_CENTRIC_ANSWER_V1,
enableLifecycleAnswerV1: config_1.FEATURE_ASSISTANT_LIFECYCLE_ANSWER_V1
@@ -1213,6 +1247,8 @@ export class AssistantService {
retrieval_results: retrievalResults,
answer_grounding_check: groundingCheck,
dropped_intent_segments: extractDiscardedIntentSegments(normalized.normalized),
question_type_class: questionTypeClass,
company_anchors: companyAnchors,
...(followupBinding.usage ? { followup_state_usage: followupBinding.usage } : {}),
problem_centric_answer_applied: composition.problem_centric_answer_applied ?? false,
problem_units_used_count: composition.problem_units_used_count ?? 0,
@@ -1276,6 +1312,8 @@ export class AssistantService {
route_subject_match: groundingCheck.route_subject_match,
clarification_target: coverageEvaluation.coverage.clarification_needed_for,
dropped_intent_segments: extractDiscardedIntentSegments(normalized.normalized),
question_type_class: questionTypeClass,
company_anchors: companyAnchors,
...(followupBinding.usage ? { followup_state_usage: followupBinding.usage } : {}),
problem_centric_answer_applied: composition.problem_centric_answer_applied ?? false,
problem_units_used_count: composition.problem_units_used_count ?? 0,