АРЧ - Ассистент: отделить meta-followup по прошлому ответу от повторного запуска address lane
This commit is contained in:
@@ -2453,6 +2453,62 @@ function findRecentAddressFilterValue(items, key) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function isInventoryRootFrameIntent(intent) {
|
||||
return intent === "inventory_on_hand_as_of_date";
|
||||
}
|
||||
function isInventoryDrilldownFrameIntent(intent) {
|
||||
return intent === "inventory_purchase_provenance_for_item" ||
|
||||
intent === "inventory_purchase_documents_for_item" ||
|
||||
intent === "inventory_sale_trace_for_item" ||
|
||||
intent === "inventory_purchase_to_sale_chain" ||
|
||||
intent === "inventory_aging_by_purchase_date";
|
||||
}
|
||||
function extractAddressCarryoverAnchor(addressDebug) {
|
||||
if (!isAddressLaneDebugPayload(addressDebug)) {
|
||||
return {
|
||||
anchorType: null,
|
||||
anchorValue: null
|
||||
};
|
||||
}
|
||||
return {
|
||||
anchorType: toNonEmptyString(addressDebug.anchor_type),
|
||||
anchorValue: toNonEmptyString(addressDebug.anchor_value_resolved) ??
|
||||
toNonEmptyString(addressDebug.anchor_value_raw) ??
|
||||
readAddressInventoryItemFilter(addressDebug) ??
|
||||
readAddressFilterString(addressDebug, "counterparty") ??
|
||||
readAddressFilterString(addressDebug, "contract") ??
|
||||
readAddressFilterString(addressDebug, "account")
|
||||
};
|
||||
}
|
||||
function findRecentInventoryRootFrame(items) {
|
||||
for (let index = items.length - 1; index >= 0; index -= 1) {
|
||||
const item = items[index];
|
||||
if (!item || item.role !== "assistant" || !item.debug) {
|
||||
continue;
|
||||
}
|
||||
const debug = item.debug;
|
||||
if (!isAddressLaneDebugPayload(debug)) {
|
||||
continue;
|
||||
}
|
||||
const detectedIntent = toNonEmptyString(debug.detected_intent);
|
||||
if (!isInventoryRootFrameIntent(detectedIntent)) {
|
||||
continue;
|
||||
}
|
||||
const anchor = extractAddressCarryoverAnchor(debug);
|
||||
const filtersRaw = debug.extracted_filters;
|
||||
const filters = filtersRaw && typeof filtersRaw === "object"
|
||||
? { ...filtersRaw }
|
||||
: {};
|
||||
return {
|
||||
intent: detectedIntent,
|
||||
filters,
|
||||
anchorType: anchor.anchorType,
|
||||
anchorValue: anchor.anchorValue,
|
||||
messageId: toNonEmptyString(item.message_id)
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const ADDRESS_FOLLOWUP_OFFER_BY_INTENT = {
|
||||
list_documents_by_counterparty: ["bank_operations_by_counterparty", "list_contracts_by_counterparty"],
|
||||
bank_operations_by_counterparty: ["list_documents_by_counterparty", "list_contracts_by_counterparty"],
|
||||
@@ -2755,6 +2811,14 @@ function resolveAddressFollowupCarryoverContext(userMessage, items, alternateMes
|
||||
readAddressFilterString(previousAddressDebug, "counterparty") ??
|
||||
readAddressFilterString(previousAddressDebug, "account") ??
|
||||
readAddressFilterString(previousAddressDebug, "contract");
|
||||
const inventoryRootFrame = findRecentInventoryRootFrame(items);
|
||||
const currentFrameKind = inventoryRootFrame
|
||||
? isInventoryDrilldownFrameIntent(sourceIntent)
|
||||
? "inventory_drilldown"
|
||||
: isInventoryRootFrameIntent(sourceIntent)
|
||||
? "inventory_root"
|
||||
: "generic"
|
||||
: null;
|
||||
let resolvedCounterpartyFromDisplay = false;
|
||||
const previousFiltersRaw = previousAddressDebug.extracted_filters;
|
||||
const previousFilters = previousFiltersRaw && typeof previousFiltersRaw === "object"
|
||||
@@ -2814,7 +2878,12 @@ function resolveAddressFollowupCarryoverContext(userMessage, items, alternateMes
|
||||
previous_filters: previousFilters,
|
||||
previous_anchor_type: previousAnchorType ?? undefined,
|
||||
previous_anchor_value: previousAnchor,
|
||||
resolved_counterparty_from_display: resolvedCounterpartyFromDisplay || undefined
|
||||
resolved_counterparty_from_display: resolvedCounterpartyFromDisplay || undefined,
|
||||
root_intent: inventoryRootFrame?.intent ?? undefined,
|
||||
root_filters: inventoryRootFrame?.filters ?? undefined,
|
||||
root_anchor_type: inventoryRootFrame?.anchorType ?? undefined,
|
||||
root_anchor_value: inventoryRootFrame?.anchorValue ?? undefined,
|
||||
current_frame_kind: currentFrameKind ?? undefined
|
||||
},
|
||||
previousAddressIntent: previousIntent,
|
||||
previousAddressAnchor: previousAnchor,
|
||||
@@ -2890,19 +2959,32 @@ function isAddressLlmPreDecomposeCandidate(userMessage) {
|
||||
}
|
||||
return /(?:\bдок\b|доки|документ|контрагент|договор|остаток|сч(?:е|ё)т|сальдо|банк|выписк|платеж|оплат|поступлен|поступлени|списан|реализац|сверк|взаиморасч|кто\s+должен|show|list|documents?|counterparty|contract|account|balance|bank\s+operations?|doki|dokument(?:y|ov|am|a)?|platezh|oplata|schet|saldo)/i.test(text);
|
||||
}
|
||||
function extractAddressQuestionFromNormalized(normalized) {
|
||||
if (!normalized || typeof normalized !== "object") {
|
||||
function normalizeAddressSemanticHintsFromFragment(fragment) {
|
||||
if (!fragment || typeof fragment !== "object") {
|
||||
return null;
|
||||
}
|
||||
const source = normalized;
|
||||
const fragments = Array.isArray(source.fragments) ? source.fragments : [];
|
||||
for (const item of fragments) {
|
||||
const hints = fragment.semantic_hints;
|
||||
if (!hints || typeof hints !== "object") {
|
||||
return null;
|
||||
}
|
||||
const scopeTargetKind = toNonEmptyString(hints.scope_target_kind);
|
||||
const dateScopeKind = toNonEmptyString(hints.date_scope_kind);
|
||||
return {
|
||||
scope_target_kind: scopeTargetKind ?? "none",
|
||||
scope_target_text: toNonEmptyString(hints.scope_target_text),
|
||||
date_scope_kind: dateScopeKind ?? "missing",
|
||||
self_scope_detected: hints.self_scope_detected === true || scopeTargetKind === "self_scope",
|
||||
selected_object_scope_detected: hints.selected_object_scope_detected === true || scopeTargetKind === "selected_object"
|
||||
};
|
||||
}
|
||||
function extractAddressPredecomposeCandidateFromFragments(fragments) {
|
||||
for (const item of Array.isArray(fragments) ? fragments : []) {
|
||||
if (!item || typeof item !== "object") {
|
||||
continue;
|
||||
}
|
||||
const fragment = item;
|
||||
const domainRelevance = String(fragment.domain_relevance ?? "").trim().toLowerCase();
|
||||
if (domainRelevance === "out_of_scope") {
|
||||
if (domainRelevance === "out_of_scope" || domainRelevance === "offtopic") {
|
||||
continue;
|
||||
}
|
||||
const normalizedText = toNonEmptyString(fragment.normalized_fragment_text);
|
||||
@@ -2912,11 +2994,20 @@ function extractAddressQuestionFromNormalized(normalized) {
|
||||
continue;
|
||||
}
|
||||
if (candidate.length >= 3 && candidate.length <= 500) {
|
||||
return candidate;
|
||||
return {
|
||||
candidate,
|
||||
semanticHints: normalizeAddressSemanticHintsFromFragment(fragment)
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function extractAddressPredecomposeCandidateFromNormalized(normalized) {
|
||||
if (!normalized || typeof normalized !== "object") {
|
||||
return null;
|
||||
}
|
||||
return extractAddressPredecomposeCandidateFromFragments(normalized.fragments);
|
||||
}
|
||||
function stripMarkdownJsonFence(text) {
|
||||
return String(text ?? "")
|
||||
.trim()
|
||||
@@ -2994,7 +3085,7 @@ function extractOutputTextFromRawNormalizerOutput(raw) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function extractAddressQuestionFromRawNormalizerOutput(rawModelOutput) {
|
||||
function extractAddressPredecomposeCandidateFromRawNormalizerOutput(rawModelOutput) {
|
||||
const outputText = extractOutputTextFromRawNormalizerOutput(rawModelOutput);
|
||||
if (!outputText) {
|
||||
return null;
|
||||
@@ -3003,31 +3094,7 @@ function extractAddressQuestionFromRawNormalizerOutput(rawModelOutput) {
|
||||
if (!parsed || typeof parsed !== "object") {
|
||||
return null;
|
||||
}
|
||||
const source = parsed;
|
||||
const fragments = Array.isArray(source.fragments) ? source.fragments : [];
|
||||
for (const item of fragments) {
|
||||
if (!item || typeof item !== "object") {
|
||||
continue;
|
||||
}
|
||||
const fragment = item;
|
||||
const domainRelevance = fragment.domain_relevance;
|
||||
if (typeof domainRelevance === "string" && domainRelevance.trim().toLowerCase() === "out_of_scope") {
|
||||
continue;
|
||||
}
|
||||
if (domainRelevance === false) {
|
||||
continue;
|
||||
}
|
||||
const normalizedText = toNonEmptyString(fragment.normalized_fragment_text);
|
||||
const rawText = toNonEmptyString(fragment.raw_fragment_text);
|
||||
const candidate = selectPreferredAddressFragmentCandidate(rawText ?? "", normalizedText ?? "");
|
||||
if (!candidate) {
|
||||
continue;
|
||||
}
|
||||
if (candidate.length >= 3 && candidate.length <= 500) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return extractAddressPredecomposeCandidateFromFragments(parsed.fragments);
|
||||
}
|
||||
const ADDRESS_PREDECOMPOSE_LOW_QUALITY_COUNTERPARTY_TOKENS = new Set([
|
||||
"есть",
|
||||
@@ -3267,7 +3334,8 @@ function attachAddressPredecomposeContract(meta, sourceMessage) {
|
||||
const canonicalMessage = toNonEmptyString(meta?.effectiveMessage) ?? String(sourceMessage ?? "");
|
||||
const predecomposeContract = (0, predecomposeContract_1.buildAddressLlmPredecomposeContractV1)({
|
||||
sourceMessage: String(sourceMessage ?? ""),
|
||||
canonicalMessage
|
||||
canonicalMessage,
|
||||
semanticHints: meta?.semanticHints ?? null
|
||||
});
|
||||
const semanticExtractionContract = (0, predecomposeContract_1.buildAddressSemanticExtractionContractV1)({
|
||||
sourceMessage: String(sourceMessage ?? ""),
|
||||
@@ -3332,31 +3400,34 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
|
||||
};
|
||||
try {
|
||||
const normalized = await normalizerService.normalize(normalizePayload);
|
||||
const candidateFromNormalized = extractAddressQuestionFromNormalized(normalized?.normalized);
|
||||
const candidateFromRaw = candidateFromNormalized ? null : extractAddressQuestionFromRawNormalizerOutput(normalized?.raw_model_output);
|
||||
const candidate = candidateFromNormalized ?? candidateFromRaw;
|
||||
const candidateFromNormalized = extractAddressPredecomposeCandidateFromNormalized(normalized?.normalized);
|
||||
const candidateFromRaw = candidateFromNormalized ? null : extractAddressPredecomposeCandidateFromRawNormalizerOutput(normalized?.raw_model_output);
|
||||
const candidateMeta = candidateFromNormalized ?? candidateFromRaw;
|
||||
const candidate = candidateMeta?.candidate ?? null;
|
||||
if (!candidate) {
|
||||
if (fallbackCandidate) {
|
||||
const fallbackCompact = compactWhitespace(String(fallbackCandidate.candidate ?? "").toLowerCase());
|
||||
const sourceCompact = compactWhitespace(String(userMessage ?? "").toLowerCase());
|
||||
const fallbackApplied = fallbackCompact.length > 0 && fallbackCompact !== sourceCompact;
|
||||
if (fallbackApplied) {
|
||||
return attachAddressPredecomposeContract({
|
||||
...baseMeta,
|
||||
attempted: true,
|
||||
applied: true,
|
||||
traceId: normalized?.trace_id ?? null,
|
||||
effectiveMessage: fallbackCandidate.candidate,
|
||||
reason: "fallback_rule_applied_after_llm",
|
||||
fallbackRuleHit: fallbackCandidate.rule
|
||||
}, userMessage);
|
||||
}
|
||||
return attachAddressPredecomposeContract({
|
||||
...baseMeta,
|
||||
attempted: true,
|
||||
applied: true,
|
||||
traceId: normalized?.trace_id ?? null,
|
||||
effectiveMessage: fallbackCandidate.candidate,
|
||||
reason: "fallback_rule_applied_after_llm",
|
||||
fallbackRuleHit: fallbackCandidate.rule,
|
||||
semanticHints: null
|
||||
}, userMessage);
|
||||
}
|
||||
}
|
||||
return attachAddressPredecomposeContract({
|
||||
...baseMeta,
|
||||
attempted: true,
|
||||
traceId: normalized?.trace_id ?? null,
|
||||
reason: normalized?.ok ? "no_usable_fragment" : "normalize_failed"
|
||||
reason: normalized?.ok ? "no_usable_fragment" : "normalize_failed",
|
||||
semanticHints: null
|
||||
}, userMessage);
|
||||
}
|
||||
const repairedSourceMessage = repairAddressMojibake(userMessage);
|
||||
@@ -3375,7 +3446,8 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
|
||||
effectiveMessage: userMessage,
|
||||
reason: "normalized_fragment_rejected_diagnostic_rewrite",
|
||||
fallbackRuleHit: null,
|
||||
sanitizedUserMessage
|
||||
sanitizedUserMessage,
|
||||
semanticHints: candidateMeta?.semanticHints ?? null
|
||||
}, userMessage);
|
||||
}
|
||||
const intentConflict = sourceIntentKnown &&
|
||||
@@ -3397,7 +3469,8 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
|
||||
? "normalized_fragment_rejected_intent_drop"
|
||||
: "normalized_fragment_rejected_intent_conflict",
|
||||
fallbackRuleHit: null,
|
||||
sanitizedUserMessage
|
||||
sanitizedUserMessage,
|
||||
semanticHints: candidateMeta?.semanticHints ?? null
|
||||
}, userMessage);
|
||||
}
|
||||
const sourceHasExplicitDrilldownSignal = hasPredecomposeExplicitDrilldownSignal(repairedSourceMessage || userMessage);
|
||||
@@ -3418,7 +3491,8 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
|
||||
effectiveMessage: userMessage,
|
||||
reason: "normalized_fragment_rejected_followup_intent_injection",
|
||||
fallbackRuleHit: null,
|
||||
sanitizedUserMessage
|
||||
sanitizedUserMessage,
|
||||
semanticHints: candidateMeta?.semanticHints ?? null
|
||||
}, userMessage);
|
||||
}
|
||||
const sourceHasSelectedObjectInventoryFollowup = hasSelectedObjectInventoryFollowupSignalForPredecompose(repairedSourceMessage || userMessage);
|
||||
@@ -3438,7 +3512,8 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
|
||||
effectiveMessage: userMessage,
|
||||
reason: "normalized_fragment_rejected_selected_object_context_loss",
|
||||
fallbackRuleHit: null,
|
||||
sanitizedUserMessage
|
||||
sanitizedUserMessage,
|
||||
semanticHints: candidateMeta?.semanticHints ?? null
|
||||
}, userMessage);
|
||||
}
|
||||
const sourceAnchorQuality = evaluateAddressAnchorQuality(repairedSourceMessage || userMessage);
|
||||
@@ -3464,7 +3539,8 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
|
||||
effectiveMessage: userMessage,
|
||||
reason: "normalized_fragment_rejected_anchor_substitution",
|
||||
fallbackRuleHit: null,
|
||||
sanitizedUserMessage
|
||||
sanitizedUserMessage,
|
||||
semanticHints: candidateMeta?.semanticHints ?? null
|
||||
}, userMessage);
|
||||
}
|
||||
const anchorDegradedByCandidate = sameIntentForAnchorSafety &&
|
||||
@@ -3481,7 +3557,8 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
|
||||
effectiveMessage: userMessage,
|
||||
reason: "normalized_fragment_rejected_anchor_degradation",
|
||||
fallbackRuleHit: null,
|
||||
sanitizedUserMessage
|
||||
sanitizedUserMessage,
|
||||
semanticHints: candidateMeta?.semanticHints ?? null
|
||||
}, userMessage);
|
||||
}
|
||||
if (fallbackCandidate) {
|
||||
@@ -3500,19 +3577,25 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
|
||||
effectiveMessage: fallbackCandidate.candidate,
|
||||
reason: "fallback_rule_preferred_over_llm_candidate_anchor_quality",
|
||||
fallbackRuleHit: fallbackCandidate.rule,
|
||||
sanitizedUserMessage
|
||||
sanitizedUserMessage,
|
||||
semanticHints: candidateMeta?.semanticHints ?? null
|
||||
}, userMessage);
|
||||
}
|
||||
}
|
||||
const semanticContractForCandidate = (0, predecomposeContract_1.buildAddressSemanticExtractionContractV1)({
|
||||
sourceMessage: String(userMessage ?? ""),
|
||||
canonicalMessage: candidate
|
||||
canonicalMessage: candidate,
|
||||
predecomposeContract: (0, predecomposeContract_1.buildAddressLlmPredecomposeContractV1)({
|
||||
sourceMessage: String(userMessage ?? ""),
|
||||
canonicalMessage: candidate,
|
||||
semanticHints: candidateMeta?.semanticHints ?? null
|
||||
})
|
||||
});
|
||||
if (!semanticContractForCandidate.apply_canonical_recommended) {
|
||||
const sourceDataSignalDetected = Boolean(semanticContractForCandidate?.guard_hints?.source_data_signal_detected);
|
||||
const rawFragmentCandidatePreferred = Boolean(sourceDataSignalDetected &&
|
||||
candidateFromNormalized &&
|
||||
candidateFromNormalized === candidate &&
|
||||
candidateFromNormalized.candidate === candidate &&
|
||||
toNonEmptyString(candidate));
|
||||
if (rawFragmentCandidatePreferred) {
|
||||
return attachAddressPredecomposeContract({
|
||||
@@ -3524,7 +3607,8 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
|
||||
effectiveMessage: candidate,
|
||||
reason: "normalized_fragment_semantic_guard_raw_fragment_preferred",
|
||||
fallbackRuleHit: null,
|
||||
sanitizedUserMessage
|
||||
sanitizedUserMessage,
|
||||
semanticHints: candidateMeta?.semanticHints ?? null
|
||||
}, userMessage);
|
||||
}
|
||||
if (fallbackCandidate) {
|
||||
@@ -3545,7 +3629,8 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
|
||||
effectiveMessage: String(fallbackCandidate.candidate ?? ""),
|
||||
reason: "fallback_rule_preferred_over_llm_candidate_semantic_guard",
|
||||
fallbackRuleHit: fallbackCandidate.rule,
|
||||
sanitizedUserMessage
|
||||
sanitizedUserMessage,
|
||||
semanticHints: candidateMeta?.semanticHints ?? null
|
||||
}, userMessage);
|
||||
}
|
||||
}
|
||||
@@ -3558,7 +3643,8 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
|
||||
effectiveMessage: userMessage,
|
||||
reason: "normalized_fragment_rejected_semantic_guard",
|
||||
fallbackRuleHit: null,
|
||||
sanitizedUserMessage
|
||||
sanitizedUserMessage,
|
||||
semanticHints: candidateMeta?.semanticHints ?? null
|
||||
}, userMessage);
|
||||
}
|
||||
const sourceCompact = compactWhitespace(String(userMessage ?? "").toLowerCase());
|
||||
@@ -3585,7 +3671,8 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
|
||||
reason,
|
||||
llmCanonicalCandidateDetected: true,
|
||||
fallbackRuleHit: null,
|
||||
sanitizedUserMessage
|
||||
sanitizedUserMessage,
|
||||
semanticHints: candidateMeta?.semanticHints ?? null
|
||||
}, userMessage);
|
||||
}
|
||||
catch (error) {
|
||||
@@ -3933,7 +4020,11 @@ export function resolveAssistantOrchestrationDecision(input) {
|
||||
hasOpenContractsAddressSignal(repairedEffectiveAddressUserMessage);
|
||||
const modeSample = repairedEffectiveAddressUserMessage || effectiveAddressUserMessage;
|
||||
const modeDetection = (0, addressQueryClassifier_1.detectAddressQuestionMode)(modeSample);
|
||||
const modeDetectionRaw = (0, addressQueryClassifier_1.detectAddressQuestionMode)(repairedRawUserMessage || rawUserMessage);
|
||||
const resolvedModeDetection = modeDetection.mode === "address_query" ? modeDetection : modeDetectionRaw;
|
||||
const intentResolution = (0, addressIntentResolver_1.resolveAddressIntent)(modeSample);
|
||||
const intentResolutionRaw = (0, addressIntentResolver_1.resolveAddressIntent)(repairedRawUserMessage || rawUserMessage);
|
||||
const resolvedIntentResolution = intentResolution.intent !== "unknown" ? intentResolution : intentResolutionRaw;
|
||||
const llmContractIntent = toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.intent);
|
||||
const llmPreDecomposeReason = toNonEmptyString(llmPreDecomposeMeta?.reason);
|
||||
const llmRuntimeUnavailableDetected = Boolean(llmPreDecomposeReason &&
|
||||
@@ -3951,10 +4042,10 @@ export function resolveAssistantOrchestrationDecision(input) {
|
||||
hasStrictDeepInvestigationCue(repairedRawUserMessage) ||
|
||||
hasStrictDeepInvestigationCue(effectiveAddressUserMessage) ||
|
||||
hasStrictDeepInvestigationCue(repairedEffectiveAddressUserMessage);
|
||||
const strictDeepInvestigationBypassAllowed = shouldBypassStrictDeepInvestigationCueForAddressIntent(intentResolution.intent) ||
|
||||
const strictDeepInvestigationBypassAllowed = shouldBypassStrictDeepInvestigationCueForAddressIntent(resolvedIntentResolution.intent) ||
|
||||
shouldBypassStrictDeepInvestigationCueForAddressIntent(llmContractIntent);
|
||||
const keepAddressLaneByIntent = semanticApplyCanonicalRecommended &&
|
||||
Boolean((intentResolution.intent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(intentResolution.intent)) ||
|
||||
Boolean((resolvedIntentResolution.intent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(resolvedIntentResolution.intent)) ||
|
||||
(llmContractIntent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(llmContractIntent)) ||
|
||||
openContractsAddressSignal) &&
|
||||
(!strictDeepInvestigationCueDetected || strictDeepInvestigationBypassAllowed);
|
||||
@@ -3995,8 +4086,8 @@ export function resolveAssistantOrchestrationDecision(input) {
|
||||
!capabilityMetaQuery &&
|
||||
!dataRetrievalSignal &&
|
||||
!effectiveAddressFollowupSignal &&
|
||||
modeDetection.mode === "unsupported" &&
|
||||
intentResolution.intent === "unknown");
|
||||
resolvedModeDetection.mode === "unsupported" &&
|
||||
resolvedIntentResolution.intent === "unknown");
|
||||
const nonDomainQueryIndexed = Boolean(!llmFirstAddressCandidate &&
|
||||
deterministicNonDomainGuard &&
|
||||
(llmFirstUnsupportedCandidate || llmContractMode === null) &&
|
||||
@@ -4016,10 +4107,10 @@ export function resolveAssistantOrchestrationDecision(input) {
|
||||
orchestrationContract: {
|
||||
schema_version: "assistant_orchestration_contract_v1",
|
||||
hard_meta_mode: "data_scope",
|
||||
address_mode: modeDetection.mode,
|
||||
address_mode_confidence: modeDetection.confidence,
|
||||
address_intent: intentResolution.intent,
|
||||
address_intent_confidence: intentResolution.confidence,
|
||||
address_mode: resolvedModeDetection.mode,
|
||||
address_mode_confidence: resolvedModeDetection.confidence,
|
||||
address_intent: resolvedIntentResolution.intent,
|
||||
address_intent_confidence: resolvedIntentResolution.confidence,
|
||||
strong_data_signal_detected: strongDataSignal,
|
||||
data_retrieval_signal_detected: dataRetrievalSignal,
|
||||
followup_context_detected: Boolean(followupContext),
|
||||
@@ -4044,10 +4135,10 @@ export function resolveAssistantOrchestrationDecision(input) {
|
||||
orchestrationContract: {
|
||||
schema_version: "assistant_orchestration_contract_v1",
|
||||
hard_meta_mode: "capability",
|
||||
address_mode: modeDetection.mode,
|
||||
address_mode_confidence: modeDetection.confidence,
|
||||
address_intent: intentResolution.intent,
|
||||
address_intent_confidence: intentResolution.confidence,
|
||||
address_mode: resolvedModeDetection.mode,
|
||||
address_mode_confidence: resolvedModeDetection.confidence,
|
||||
address_intent: resolvedIntentResolution.intent,
|
||||
address_intent_confidence: resolvedIntentResolution.confidence,
|
||||
strong_data_signal_detected: strongDataSignal,
|
||||
data_retrieval_signal_detected: dataRetrievalSignal,
|
||||
followup_context_detected: Boolean(followupContext),
|
||||
@@ -4072,10 +4163,10 @@ export function resolveAssistantOrchestrationDecision(input) {
|
||||
orchestrationContract: {
|
||||
schema_version: "assistant_orchestration_contract_v1",
|
||||
hard_meta_mode: "non_domain",
|
||||
address_mode: modeDetection.mode,
|
||||
address_mode_confidence: modeDetection.confidence,
|
||||
address_intent: intentResolution.intent,
|
||||
address_intent_confidence: intentResolution.confidence,
|
||||
address_mode: resolvedModeDetection.mode,
|
||||
address_mode_confidence: resolvedModeDetection.confidence,
|
||||
address_intent: resolvedIntentResolution.intent,
|
||||
address_intent_confidence: resolvedIntentResolution.confidence,
|
||||
strong_data_signal_detected: strongDataSignal,
|
||||
data_retrieval_signal_detected: dataRetrievalSignal,
|
||||
followup_context_detected: Boolean(followupContext),
|
||||
@@ -4111,7 +4202,7 @@ export function resolveAssistantOrchestrationDecision(input) {
|
||||
hasShortDebtMirrorFollowupSignal(repairedRawUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(repairedEffectiveAddressUserMessage));
|
||||
const supportedAddressIntentDetected = (!strictDeepInvestigationCueDetected || strictDeepInvestigationBypassAllowed) &&
|
||||
Boolean((intentResolution.intent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(intentResolution.intent)) ||
|
||||
Boolean((resolvedIntentResolution.intent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(resolvedIntentResolution.intent)) ||
|
||||
(llmContractIntent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(llmContractIntent)) ||
|
||||
openContractsAddressSignal);
|
||||
const semanticGuardHints = semanticExtractionContract?.guard_hints &&
|
||||
@@ -4131,7 +4222,7 @@ export function resolveAssistantOrchestrationDecision(input) {
|
||||
semanticAggregateShapeDetected ||
|
||||
semanticDeepInvestigationHintDetected ||
|
||||
!semanticApplyCanonicalRecommended));
|
||||
const unsupportedIntentOrMode = (modeDetection.mode !== "address_query" && intentResolution.intent === "unknown") ||
|
||||
const unsupportedIntentOrMode = (resolvedModeDetection.mode !== "address_query" && resolvedIntentResolution.intent === "unknown") ||
|
||||
llmContractMode === "unsupported";
|
||||
const unsupportedAddressIntentFallbackToDeep = Boolean(baseToolGate?.runAddressLane &&
|
||||
!llmRuntimeUnavailableDetected &&
|
||||
@@ -4251,10 +4342,10 @@ export function resolveAssistantOrchestrationDecision(input) {
|
||||
orchestrationContract: {
|
||||
schema_version: "assistant_orchestration_contract_v1",
|
||||
hard_meta_mode: null,
|
||||
address_mode: modeDetection.mode,
|
||||
address_mode_confidence: modeDetection.confidence,
|
||||
address_intent: intentResolution.intent,
|
||||
address_intent_confidence: intentResolution.confidence,
|
||||
address_mode: resolvedModeDetection.mode,
|
||||
address_mode_confidence: resolvedModeDetection.confidence,
|
||||
address_intent: resolvedIntentResolution.intent,
|
||||
address_intent_confidence: resolvedIntentResolution.confidence,
|
||||
strong_data_signal_detected: strongDataSignal,
|
||||
data_retrieval_signal_detected: dataRetrievalSignal,
|
||||
semantic_contract_valid: semanticContractValid,
|
||||
|
||||
Reference in New Issue
Block a user