ARCH: стабилизировать continuity и защитить exact-ответы от discovery
This commit is contained in:
@@ -89,6 +89,56 @@ function isDiscoveryReadyAddressCandidate(input, entryPoint) {
|
||||
turnInput?.should_run_discovery === true &&
|
||||
(source === "address_lane" || source === "address_exact" || source === "address_query_runtime_v1"));
|
||||
}
|
||||
function hasAlignedFactualAddressReply(input, entryPoint) {
|
||||
if (!isDiscoveryReadyAddressCandidate(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (toNonEmptyString(input.currentReplyType) !== "factual") {
|
||||
return false;
|
||||
}
|
||||
const detectedIntent = toNonEmptyString(input.addressRuntimeMeta?.detected_intent);
|
||||
const turnInput = toRecordObject(entryPoint?.turn_input);
|
||||
const turnMeaning = toRecordObject(turnInput?.turn_meaning_ref);
|
||||
const askedDomain = toNonEmptyString(turnMeaning?.asked_domain_family);
|
||||
const askedAction = toNonEmptyString(turnMeaning?.asked_action_family);
|
||||
if (detectedIntent === "counterparty_activity_lifecycle") {
|
||||
return askedDomain === "counterparty_lifecycle" || askedAction === "activity_duration";
|
||||
}
|
||||
if (detectedIntent === "supplier_payouts_profile") {
|
||||
return askedDomain === "counterparty_value" && askedAction === "payout";
|
||||
}
|
||||
if (detectedIntent === "customer_revenue_and_payments") {
|
||||
return askedDomain === "counterparty_value" && askedAction === "turnover";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function hasMatchedFactualAddressContinuationTarget(input) {
|
||||
if (toNonEmptyString(input.currentReplyType) !== "factual") {
|
||||
return false;
|
||||
}
|
||||
const detectedIntent = toNonEmptyString(input.addressRuntimeMeta?.detected_intent);
|
||||
const dialogContinuationContract = toRecordObject(input.addressRuntimeMeta?.dialogContinuationContract);
|
||||
const targetIntent = toNonEmptyString(dialogContinuationContract?.target_intent);
|
||||
return Boolean(detectedIntent && targetIntent && detectedIntent === targetIntent);
|
||||
}
|
||||
function hasFullConfirmedFactualAddressReply(input, entryPoint) {
|
||||
if (!isDiscoveryReadyAddressCandidate(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (toNonEmptyString(input.currentReplyType) !== "factual") {
|
||||
return false;
|
||||
}
|
||||
const truthGateStatus = toNonEmptyString(input.addressRuntimeMeta?.truth_gate_contract_status);
|
||||
if (truthGateStatus === "full_confirmed") {
|
||||
return true;
|
||||
}
|
||||
const truthAnswerPolicy = toRecordObject(input.addressRuntimeMeta?.assistant_truth_answer_policy_v1);
|
||||
const truthGate = toRecordObject(truthAnswerPolicy?.truth_gate);
|
||||
const sourceTruthGateStatus = toNonEmptyString(truthGate?.source_truth_gate_status);
|
||||
const coverageStatus = toNonEmptyString(truthGate?.coverage_status);
|
||||
const groundingStatus = toNonEmptyString(truthGate?.grounding_status);
|
||||
return sourceTruthGateStatus === "full_confirmed" || (coverageStatus === "full" && groundingStatus === "grounded");
|
||||
}
|
||||
function applyAssistantMcpDiscoveryResponsePolicy(input) {
|
||||
const currentReply = String(input.currentReply ?? "");
|
||||
const currentReplySource = toNonEmptyString(input.currentReplySource) ?? toNonEmptyString(input.livingChatSource) ?? "unknown";
|
||||
@@ -99,6 +149,9 @@ function applyAssistantMcpDiscoveryResponsePolicy(input) {
|
||||
const discoveryReadyChatCandidate = isDiscoveryReadyChatCandidate(input, entryPoint);
|
||||
const discoveryReadyDeepCandidate = isDiscoveryReadyDeepCandidate(input, entryPoint);
|
||||
const discoveryReadyAddressCandidate = isDiscoveryReadyAddressCandidate(input, entryPoint);
|
||||
const alignedFactualAddressReply = hasAlignedFactualAddressReply(input, entryPoint);
|
||||
const matchedFactualAddressContinuationTarget = hasMatchedFactualAddressContinuationTarget(input);
|
||||
const fullConfirmedFactualAddressReply = hasFullConfirmedFactualAddressReply(input, entryPoint);
|
||||
if (!entryPoint) {
|
||||
pushReason(reasonCodes, "mcp_discovery_response_policy_no_entry_point");
|
||||
}
|
||||
@@ -114,6 +167,15 @@ function applyAssistantMcpDiscoveryResponsePolicy(input) {
|
||||
if (!discoveryReadyAddressCandidate) {
|
||||
pushReason(reasonCodes, "mcp_discovery_response_policy_not_discovery_ready_address_candidate");
|
||||
}
|
||||
if (alignedFactualAddressReply) {
|
||||
pushReason(reasonCodes, "mcp_discovery_response_policy_keep_aligned_factual_address_reply");
|
||||
}
|
||||
if (matchedFactualAddressContinuationTarget) {
|
||||
pushReason(reasonCodes, "mcp_discovery_response_policy_keep_factual_address_continuation_target");
|
||||
}
|
||||
if (fullConfirmedFactualAddressReply) {
|
||||
pushReason(reasonCodes, "mcp_discovery_response_policy_keep_full_confirmed_factual_address_reply");
|
||||
}
|
||||
if (!ALLOWED_CANDIDATE_STATUSES.has(candidate.candidate_status)) {
|
||||
pushReason(reasonCodes, "mcp_discovery_response_policy_candidate_status_not_allowed");
|
||||
}
|
||||
@@ -128,6 +190,9 @@ function applyAssistantMcpDiscoveryResponsePolicy(input) {
|
||||
}
|
||||
const canApply = Boolean(entryPoint) &&
|
||||
(unsupportedBoundary || discoveryReadyChatCandidate || discoveryReadyDeepCandidate || discoveryReadyAddressCandidate) &&
|
||||
!alignedFactualAddressReply &&
|
||||
!matchedFactualAddressContinuationTarget &&
|
||||
!fullConfirmedFactualAddressReply &&
|
||||
ALLOWED_CANDIDATE_STATUSES.has(candidate.candidate_status) &&
|
||||
candidate.eligible_for_future_hot_runtime &&
|
||||
Boolean(toNonEmptyString(candidate.reply_text)) &&
|
||||
|
||||
@@ -7,7 +7,10 @@ const SUPPORTED_ADDRESS_INTENTS = new Set([
|
||||
"payables_confirmed_as_of_date",
|
||||
"list_documents_by_counterparty",
|
||||
"customer_revenue_and_payments",
|
||||
"inventory_on_hand_as_of_date"
|
||||
"inventory_on_hand_as_of_date",
|
||||
"vat_liability_confirmed_for_tax_period",
|
||||
"vat_payable_confirmed_as_of_date",
|
||||
"vat_payable_forecast"
|
||||
]);
|
||||
function fallbackCompactWhitespace(value) {
|
||||
return String(value ?? "").replace(/\s+/g, " ").trim();
|
||||
@@ -85,8 +88,23 @@ function detectCounterpartyTurnoverFamily(text) {
|
||||
"\u0434\u043e\u0445\u043e\u0434",
|
||||
"\u0431\u044b\u043b",
|
||||
"\u0431\u044b\u043b\u0430",
|
||||
"\u0432\u0440\u0435\u043c\u044f",
|
||||
"\u0432\u0440\u0435\u043c\u0435\u043d\u0438",
|
||||
"\u0433\u043e\u0434",
|
||||
"\u0433\u043e\u0434\u0430",
|
||||
"\u043f\u0435\u0440\u0438\u043e\u0434",
|
||||
"\u043f\u0435\u0440\u0438\u043e\u0434\u0430",
|
||||
"\u043c\u0435\u0441\u044f\u0446",
|
||||
"\u043c\u0435\u0441\u044f\u0446\u0430",
|
||||
"\u043a\u0432\u0430\u0440\u0442\u0430\u043b",
|
||||
"\u043a\u0432\u0430\u0440\u0442\u0430\u043b\u0430",
|
||||
"turnover",
|
||||
"revenue"
|
||||
"revenue",
|
||||
"time",
|
||||
"year",
|
||||
"period",
|
||||
"month",
|
||||
"quarter"
|
||||
]);
|
||||
const entity = rawEntity && !ignored.has(rawEntity) ? rawEntity : null;
|
||||
return {
|
||||
@@ -136,22 +154,30 @@ function createAssistantTurnMeaningPolicy(deps = {}) {
|
||||
? "receivables"
|
||||
: explicitIntentCandidate?.startsWith("payables_")
|
||||
? "payables"
|
||||
: explicitIntentCandidate?.startsWith("inventory_")
|
||||
? "inventory"
|
||||
: explicitIntentCandidate?.includes("counterparty")
|
||||
? "counterparty"
|
||||
: counterpartyTurnover?.family
|
||||
: explicitIntentCandidate?.startsWith("vat_")
|
||||
? "vat"
|
||||
: explicitIntentCandidate?.startsWith("inventory_")
|
||||
? "inventory"
|
||||
: explicitIntentCandidate?.includes("counterparty")
|
||||
? "counterparty"
|
||||
: null;
|
||||
: counterpartyTurnover?.family
|
||||
? "counterparty"
|
||||
: null;
|
||||
const askedActionFamily = explicitIntentCandidate === "receivables_confirmed_as_of_date" ||
|
||||
explicitIntentCandidate === "payables_confirmed_as_of_date" ||
|
||||
explicitIntentCandidate === "inventory_on_hand_as_of_date"
|
||||
? "confirmed_snapshot"
|
||||
: explicitIntentCandidate === "list_documents_by_counterparty"
|
||||
? "list_documents"
|
||||
: counterpartyTurnover?.family
|
||||
? "counterparty_value_or_turnover"
|
||||
: null;
|
||||
: explicitIntentCandidate === "vat_liability_confirmed_for_tax_period"
|
||||
? "confirmed_tax_period"
|
||||
: explicitIntentCandidate === "vat_payable_confirmed_as_of_date"
|
||||
? "confirmed_snapshot"
|
||||
: explicitIntentCandidate === "vat_payable_forecast"
|
||||
? "forecast"
|
||||
: explicitIntentCandidate === "list_documents_by_counterparty"
|
||||
? "list_documents"
|
||||
: counterpartyTurnover?.family
|
||||
? "counterparty_value_or_turnover"
|
||||
: null;
|
||||
const staleReplayForbidden = Boolean(unsupportedFamily || (counterpartyTurnover?.entity && !explicitIntentCandidate));
|
||||
return {
|
||||
schema_version: "assistant_turn_meaning_v1",
|
||||
|
||||
Reference in New Issue
Block a user