Укрепить debt-boundary ответы MCP discovery
This commit is contained in:
@@ -4317,11 +4317,10 @@ class AddressQueryService {
|
||||
rowsMatched: expandedFilteredRows.length
|
||||
});
|
||||
const expandedFactual = (0, composeStage_1.composeFactualReply)(intent.intent, expandedFilteredRows, composeRuntimeOptions(expandedLimitFilters));
|
||||
const expandedPrefix = `Период сохранен. Глубина live-выборки автоматически расширена до ${expandedPlan.limit} строк.`;
|
||||
const expandedLimitations = [...filters.warnings, "query_limit_auto_expanded_for_anchor_recovery"];
|
||||
const expandedReasons = [...baseReasons, "query_limit_auto_expanded_for_anchor_recovery"];
|
||||
return buildFactualExecutionResult({
|
||||
replyText: `${expandedPrefix}\n${expandedFactual.text}`,
|
||||
replyText: expandedFactual.text,
|
||||
responseType: expandedFactual.responseType,
|
||||
responseSemantics: expandedFactual.semantics,
|
||||
selectedRecipe: expandedSelection.selected_recipe.recipe_id,
|
||||
|
||||
+2
-1
@@ -582,7 +582,8 @@ function runAssistantAddressLaneResponseRuntime(input) {
|
||||
mcp_discovery_response_candidate_v1: mcpDiscoveryResponsePolicy.candidate,
|
||||
mcp_discovery_response_applied: mcpDiscoveryResponsePolicy.applied,
|
||||
comparison_scope_response_augmentation_v1: comparisonScopeProofReply?.audit ?? null,
|
||||
...buildAppliedMcpDiscoveryRoutePatch(debugWithResponseGuard, mcpDiscoveryResponsePolicy.applied)
|
||||
...buildAppliedMcpDiscoveryRoutePatch(debugWithResponseGuard, mcpDiscoveryResponsePolicy.applied),
|
||||
...(0, assistantMcpDiscoveryResponsePolicy_1.buildAppliedMcpDiscoveryTruthPatch)(mcpDiscoveryResponsePolicy, debugWithResponseGuard)
|
||||
};
|
||||
const finalization = finalizeAddressTurnSafe({
|
||||
sessionId: input.sessionId,
|
||||
|
||||
+2
-1
@@ -142,7 +142,8 @@ function runAssistantDeepTurnResponseRuntime(input) {
|
||||
...packagingRuntime.debug,
|
||||
mcp_discovery_response_policy_v1: mcpDiscoveryResponsePolicy,
|
||||
mcp_discovery_response_candidate_v1: mcpDiscoveryResponsePolicy.candidate,
|
||||
mcp_discovery_response_applied: mcpDiscoveryResponsePolicy.applied
|
||||
mcp_discovery_response_applied: mcpDiscoveryResponsePolicy.applied,
|
||||
...(0, assistantMcpDiscoveryResponsePolicy_1.buildAppliedMcpDiscoveryTruthPatch)(mcpDiscoveryResponsePolicy, packagingRuntime.debug)
|
||||
};
|
||||
const assistantItem = mcpDiscoveryResponsePolicy.applied
|
||||
? {
|
||||
|
||||
@@ -362,6 +362,7 @@ async function runAssistantLivingChatRuntime(input) {
|
||||
mcp_discovery_response_policy_v1: mcpDiscoveryResponsePolicy,
|
||||
mcp_discovery_response_candidate_v1: mcpDiscoveryResponsePolicy.candidate,
|
||||
mcp_discovery_response_applied: mcpDiscoveryResponsePolicy.applied,
|
||||
...(0, assistantMcpDiscoveryResponsePolicy_1.buildAppliedMcpDiscoveryTruthPatch)(mcpDiscoveryResponsePolicy, addressRuntimeMeta),
|
||||
living_chat_script_guard_applied: livingChatScriptGuardApplied,
|
||||
living_chat_script_guard_reason: livingChatScriptGuardReason,
|
||||
living_chat_grounding_guard_applied: livingChatGroundingGuardApplied,
|
||||
|
||||
+20
-6
@@ -73,6 +73,18 @@ function requestsBusinessOverviewNextChecks(turnMeaning, graph) {
|
||||
const text = normalizedTurnAndGraphText(turnMeaning, graph);
|
||||
return /(?:что\s+(?:дальше\s+)?провер\w*|что\s+провер\w*\s+дальше|следующ\w*\s+шаг|в\s+первую\s+очередь\s+провер\w*|next\s+checks?|next\s+steps?)/iu.test(text);
|
||||
}
|
||||
function requestsShortDebtBoundaryFollowup(turnMeaning, graph) {
|
||||
const text = normalizeQuestionText([
|
||||
turnMeaning?.raw_message,
|
||||
turnMeaning?.effective_message,
|
||||
graph?.source_message,
|
||||
graph?.question
|
||||
].join(" "));
|
||||
if (!/\u043f\u0440\u043e\u0441\u0440\u043e\u0447/iu.test(text)) {
|
||||
return false;
|
||||
}
|
||||
return /(?:\u043a\u043e\u0440\u043e\u0442\u043a|\u043f\u043e\u0447\u0435\u043c\u0443|\u0434\u043e\u043a\u0430\u0437\p{L}*)/iu.test(text);
|
||||
}
|
||||
function requestsCompactCashflowAnswer(turnMeaning, graph) {
|
||||
const text = normalizeQuestionText([
|
||||
turnMeaning?.raw_message,
|
||||
@@ -902,6 +914,7 @@ function buildCompactBusinessOverviewReply(entryPoint, draft) {
|
||||
const debtDueDateBoundary = actionFamily === "debt_due_date_boundary" || unsupportedFamily === "debt_due_date_boundary";
|
||||
const vendorRiskBoundary = actionFamily === "vendor_risk_procurement_boundary" || unsupportedFamily === "vendor_risk_procurement_boundary";
|
||||
const inventoryReserveBoundary = actionFamily === "inventory_reserve_boundary" || unsupportedFamily === "inventory_reserve_liquidation_boundary";
|
||||
const shortDebtBoundaryFollowup = debtDueDateBoundary && requestsShortDebtBoundaryFollowup(turnMeaning, graph);
|
||||
const compactCashflowRequested = directMoneyOnlyAnswer && requestsCompactCashflowAnswer(turnMeaning, graph);
|
||||
const cashflowPolarityRequested = compactCashflowRequested && requestsCashflowPolarityAnswer(turnMeaning, graph);
|
||||
const directAccountingProfitRequested = requestsDirectAccountingProfitAnswer(turnMeaning, graph);
|
||||
@@ -1035,19 +1048,20 @@ function buildCompactBusinessOverviewReply(entryPoint, draft) {
|
||||
const rowsWithPaymentTerms = typeof dueDateAging.rows_with_payment_terms === "number" && Number.isFinite(dueDateAging.rows_with_payment_terms)
|
||||
? dueDateAging.rows_with_payment_terms
|
||||
: null;
|
||||
const rowsWithAmount = typeof dueDateAging.rows_with_amount === "number" && Number.isFinite(dueDateAging.rows_with_amount)
|
||||
? dueDateAging.rows_with_amount
|
||||
: null;
|
||||
const dueDateScopePrefix = organizationScope ? `по компании ${organizationScope} ` : "";
|
||||
if (status === "confirmed_overdue") {
|
||||
lines.push(`Коротко: ${dueDateScopePrefix}на ${asOfDate} подтвержденная просрочка есть: ${overdueAmount ?? "сумма не распознана"} по ${dueDateAging.overdue_rows ?? "найденным"} строкам.`);
|
||||
lines.push("Основа ответа: открытые расчеты 60/62/76, договорный срок оплаты и дата расчетного документа; это проверка просрочки по срокам оплаты, а не просто возраст договора.");
|
||||
}
|
||||
else if (status === "no_payment_terms_configured") {
|
||||
if (shortDebtBoundaryFollowup) {
|
||||
lines.push(`Коротко: да, доказать просрочку ${dueDateScopePrefix}на ${asOfDate} нельзя, потому что в подтвержденных данных не установлен срок оплаты.`);
|
||||
lines.push(`Открытый долг${grossAmount ? ` на ${grossAmount}` : ""} виден, но без due date это задолженность без доказанной договорной просрочки.`);
|
||||
return joinBusinessReplyLines(lines);
|
||||
}
|
||||
lines.push(`Коротко: ${dueDateScopePrefix}на ${asOfDate} подтвержденной просрочки нет: открытые расчеты проверены${grossAmount ? ` на ${grossAmount}` : ""}, но в найденных договорах срок оплаты не установлен.`);
|
||||
lines.push(rowsWithAmount !== null
|
||||
? `Проверено строк с суммой: ${rowsWithAmount}. Без установленного срока оплаты нельзя честно назвать эти остатки просрочкой.`
|
||||
: "Без установленного срока оплаты нельзя честно назвать эти остатки просрочкой.");
|
||||
lines.push("Без установленного срока оплаты нельзя честно назвать эти остатки просрочкой.");
|
||||
lines.push("Что проверить дальше: сроки оплаты и даты документов-оснований в договорах/расчетах; без них просрочку доказать нельзя.");
|
||||
}
|
||||
else if (status === "insufficient_due_date_basis") {
|
||||
lines.push(`Коротко: ${dueDateScopePrefix}на ${asOfDate} просрочка не подтверждена: по строкам с установленным сроком оплаты не хватило даты расчетного документа.`);
|
||||
|
||||
@@ -1,9 +1,111 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ASSISTANT_MCP_DISCOVERY_RESPONSE_POLICY_SCHEMA_VERSION = void 0;
|
||||
exports.buildAppliedMcpDiscoveryTruthPatch = buildAppliedMcpDiscoveryTruthPatch;
|
||||
exports.applyAssistantMcpDiscoveryResponsePolicy = applyAssistantMcpDiscoveryResponsePolicy;
|
||||
const assistantMcpDiscoveryResponseCandidate_1 = require("./assistantMcpDiscoveryResponseCandidate");
|
||||
const assistantRuntimeContracts_1 = require("../types/assistantRuntimeContracts");
|
||||
exports.ASSISTANT_MCP_DISCOVERY_RESPONSE_POLICY_SCHEMA_VERSION = "assistant_mcp_discovery_response_policy_v1";
|
||||
function uniqueReasonCodes(values) {
|
||||
const result = [];
|
||||
values.forEach((value) => {
|
||||
const text = toNonEmptyString(value);
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
const normalized = normalizeReasonCode(text);
|
||||
if (normalized && !result.includes(normalized)) {
|
||||
result.push(normalized);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
function patchCoverageGateState(value, gate) {
|
||||
const source = toRecordObject(value);
|
||||
if (!source) {
|
||||
return value;
|
||||
}
|
||||
const currentGate = toRecordObject(source.coverage_gate_state);
|
||||
return {
|
||||
...source,
|
||||
coverage_gate_state: {
|
||||
...(currentGate ?? {}),
|
||||
coverage_status: gate.coverage_status,
|
||||
evidence_grade: gate.evidence_grade,
|
||||
grounding_status: gate.grounding_status,
|
||||
truth_mode: gate.truth_mode,
|
||||
carryover_eligibility: gate.carryover_eligibility,
|
||||
reason_codes: gate.reason_codes
|
||||
}
|
||||
};
|
||||
}
|
||||
function buildAppliedMcpDiscoveryTruthPatch(policy, currentDebug) {
|
||||
if (!policy.applied || !ALLOWED_CANDIDATE_STATUSES.has(policy.candidate.candidate_status)) {
|
||||
return {};
|
||||
}
|
||||
const reasonCodes = uniqueReasonCodes([
|
||||
...policy.reason_codes,
|
||||
"mcp_discovery_response_policy_candidate_applied",
|
||||
"mcp_discovery_response_candidate_guarded_truth_patch"
|
||||
]);
|
||||
const truthGate = {
|
||||
schema_version: assistantRuntimeContracts_1.ASSISTANT_TRUTH_ANSWER_POLICY_RUNTIME_SCHEMA_VERSION,
|
||||
policy_owner: "assistantTruthAnswerPolicyRuntimeAdapter",
|
||||
coverage_status: "partial",
|
||||
evidence_grade: "medium",
|
||||
grounding_status: "partial",
|
||||
truth_mode: "limited",
|
||||
carryover_eligibility: "root_only",
|
||||
reason_codes: reasonCodes,
|
||||
source_truth_gate_status: "partial_supported",
|
||||
blocked_or_limited_explanation: "mcp_discovery_guarded_bounded_answer"
|
||||
};
|
||||
const answerShape = {
|
||||
schema_version: assistantRuntimeContracts_1.ASSISTANT_TRUTH_ANSWER_POLICY_RUNTIME_SCHEMA_VERSION,
|
||||
policy_owner: "assistantTruthAnswerPolicyRuntimeAdapter",
|
||||
answer_shape: "limited_with_reason",
|
||||
reply_type: "partial_coverage",
|
||||
capability_contract_id: null,
|
||||
transition_contract_id: null,
|
||||
may_state_confirmed_facts: true,
|
||||
must_include_limitation: true,
|
||||
may_power_followup: true,
|
||||
required_sections: ["direct_answer", "evidence_window", "limitations"],
|
||||
downgrade_only: true
|
||||
};
|
||||
const truthPolicy = {
|
||||
schema_version: assistantRuntimeContracts_1.ASSISTANT_TRUTH_ANSWER_POLICY_RUNTIME_SCHEMA_VERSION,
|
||||
policy_owner: "assistantTruthAnswerPolicyRuntimeAdapter",
|
||||
truth_gate: truthGate,
|
||||
answer_shape: answerShape
|
||||
};
|
||||
const debug = currentDebug ?? {};
|
||||
const patch = {
|
||||
assistant_truth_answer_policy_v1: truthPolicy,
|
||||
coverage_gate_contract: truthGate,
|
||||
answer_shape_contract: answerShape,
|
||||
truth_gate_contract_status: "partial_supported",
|
||||
truth_mode: "limited",
|
||||
carryover_eligibility: "root_only",
|
||||
answer_shape: "limited_with_reason"
|
||||
};
|
||||
const stateTransition = patchCoverageGateState(debug.assistant_state_transition_v1, truthGate);
|
||||
if (stateTransition !== debug.assistant_state_transition_v1) {
|
||||
patch.assistant_state_transition_v1 = stateTransition;
|
||||
}
|
||||
const stateTransitionContract = patchCoverageGateState(debug.state_transition_contract, truthGate);
|
||||
if (stateTransitionContract !== debug.state_transition_contract) {
|
||||
patch.state_transition_contract = stateTransitionContract;
|
||||
}
|
||||
const runtimeContract = toRecordObject(debug.assistant_runtime_contract_v1);
|
||||
if (runtimeContract) {
|
||||
patch.assistant_runtime_contract_v1 = {
|
||||
...runtimeContract,
|
||||
truth_gate_contract_status: "partial_supported"
|
||||
};
|
||||
}
|
||||
return patch;
|
||||
}
|
||||
const ALLOWED_CANDIDATE_STATUSES = new Set([
|
||||
"ready_for_guarded_use",
|
||||
"checked_sources_only_candidate",
|
||||
|
||||
Reference in New Issue
Block a user