Архитектура: стабилизировать organization authority после late company switch и закрыть phase16 multi-company replay
This commit is contained in:
@@ -1200,6 +1200,13 @@ function isImplicitSelfScopeWarehouseAnchor(candidate) {
|
||||
function hasSelectedObjectScopeSignal(text) {
|
||||
return /(?:по\s+выбранному\s+объекту|selected\s+object)/iu.test(String(text ?? ""));
|
||||
}
|
||||
function isReferentialSameDateWarehousePhrase(candidate) {
|
||||
const normalized = cleanupAnchorValue(candidate)
|
||||
.toLowerCase()
|
||||
.replace(/ё/g, "е")
|
||||
.trim();
|
||||
return /^(?:по)\s+(?:этой|той)(?:\s+же)?\s+дат(?:е|у|ой)$/iu.test(normalized);
|
||||
}
|
||||
function extractInventoryWarehouseAnchor(text) {
|
||||
const patterns = [
|
||||
/(?:на|по)\s+склад(?:е|у|ом)?\s+[«"']?([^\r\n,.;:!?]+?)(?:[»"']|(?=\s+(?:на|по|за|с|в)\b|[?]|$))/iu,
|
||||
@@ -1216,6 +1223,7 @@ function extractInventoryWarehouseAnchor(text) {
|
||||
candidate.includes("->") ||
|
||||
candidate.includes("=>") ||
|
||||
isImplicitSelfScopeWarehouseAnchor(candidate) ||
|
||||
isReferentialSameDateWarehousePhrase(candidate) ||
|
||||
isLowQualityWarehouseAnchorValue(candidate) ||
|
||||
normalizedCandidate.startsWith("по состоянию") ||
|
||||
isTemporalWarehousePhrase(candidate) ||
|
||||
|
||||
@@ -1485,6 +1485,32 @@ function stripOrganizationLegalForm(value) {
|
||||
function sameOrganizationEntityReference(left, right) {
|
||||
return (0, assistantOrganizationMatcher_1.organizationsLikelySameEntity)(left, right);
|
||||
}
|
||||
function isReferentialOrganizationScopeValue(value) {
|
||||
const normalized = (0, assistantOrganizationMatcher_1.normalizeOrganizationScopeSearchText)(value ?? "");
|
||||
if (!normalized) {
|
||||
return false;
|
||||
}
|
||||
return /^(?:эта|этой|эту|этой же|эта же|данная|данной|данную)\s+(?:компания|организация|фирма|контора)$/iu.test(normalized) ||
|
||||
/^(?:по|у|для)\s+(?:этой|этой же|данной)\s+(?:компании|организации|фирме|конторе)$/iu.test(normalized) ||
|
||||
/^(?:по|у|для)\s+ней$/iu.test(normalized);
|
||||
}
|
||||
function hasReferentialOrganizationScopeSignal(userMessage) {
|
||||
const normalized = (0, assistantOrganizationMatcher_1.normalizeOrganizationScopeSearchText)(userMessage ?? "");
|
||||
if (!normalized) {
|
||||
return false;
|
||||
}
|
||||
return /(?:^| )(?:по|у|для)\s+(?:этой|этой же|данной)\s+(?:компании|организации|фирме|конторе)(?: |$)/iu.test(normalized) ||
|
||||
/(?:^| )(?:по|у|для)\s+ней(?: |$)/iu.test(normalized) ||
|
||||
/(?:^| )(?:эта|этой|эту|эта же|данная|данной)\s+(?:компания|организация|фирма|контора)(?: |$)/iu.test(normalized);
|
||||
}
|
||||
function isQuestionFragmentPartyAnchor(value) {
|
||||
const normalized = normalizeSearchText(String(value ?? ""));
|
||||
if (!normalized) {
|
||||
return false;
|
||||
}
|
||||
return /(?:^| )(?:что|кто|какие|какой|сколько|сейчас)(?: |$)/iu.test(normalized) ||
|
||||
/(?:на складе|нам должен|кому мы должны|по этой компании|по этой же компании|по ней)/iu.test(normalized);
|
||||
}
|
||||
function applyPreExecutionOrganizationScopeGrounding(input) {
|
||||
const activeOrganization = (0, assistantOrganizationMatcher_1.normalizeOrganizationScopeValue)(input.activeOrganization ?? null);
|
||||
const candidateOrganizations = (0, assistantOrganizationMatcher_1.mergeKnownOrganizations)([
|
||||
@@ -1492,6 +1518,7 @@ function applyPreExecutionOrganizationScopeGrounding(input) {
|
||||
activeOrganization
|
||||
]);
|
||||
const resolvedOrganizationFromMessage = (0, assistantOrganizationMatcher_1.resolveOrganizationSelectionFromMessage)(input.userMessage, candidateOrganizations);
|
||||
const referentialOrganizationScopeDetected = hasReferentialOrganizationScopeSignal(input.userMessage);
|
||||
if (!input.filters.organization &&
|
||||
input.semanticFrame?.scope_kind === "implicit_self_scope" &&
|
||||
activeOrganization) {
|
||||
@@ -1517,6 +1544,35 @@ function applyPreExecutionOrganizationScopeGrounding(input) {
|
||||
input.semanticFrame.anchor_value = resolvedOrganizationFromMessage;
|
||||
}
|
||||
}
|
||||
if (activeOrganization &&
|
||||
((typeof input.filters.organization === "string" &&
|
||||
isReferentialOrganizationScopeValue(input.filters.organization)) ||
|
||||
referentialOrganizationScopeDetected) &&
|
||||
!sameNormalizedOrganizationScope(input.filters.organization ?? null, activeOrganization)) {
|
||||
input.filters.organization = activeOrganization;
|
||||
if (!input.warnings.includes("organization_grounded_from_referential_scope")) {
|
||||
input.warnings.push("organization_grounded_from_referential_scope");
|
||||
}
|
||||
if (!input.baseReasons.includes("organization_grounded_from_referential_scope")) {
|
||||
input.baseReasons.push("organization_grounded_from_referential_scope");
|
||||
}
|
||||
if (input.semanticFrame?.anchor_kind === "organization") {
|
||||
input.semanticFrame.anchor_value = activeOrganization;
|
||||
}
|
||||
}
|
||||
if (activeOrganization &&
|
||||
sameNormalizedOrganizationScope(input.filters.organization ?? null, activeOrganization) &&
|
||||
typeof input.filters.counterparty === "string" &&
|
||||
(isLikelyLowQualityPartyAnchor(input.filters.counterparty) ||
|
||||
isQuestionFragmentPartyAnchor(input.filters.counterparty))) {
|
||||
delete input.filters.counterparty;
|
||||
if (!input.warnings.includes("counterparty_cleared_from_referential_organization_scope")) {
|
||||
input.warnings.push("counterparty_cleared_from_referential_organization_scope");
|
||||
}
|
||||
if (!input.baseReasons.includes("counterparty_cleared_from_referential_organization_scope")) {
|
||||
input.baseReasons.push("counterparty_cleared_from_referential_organization_scope");
|
||||
}
|
||||
}
|
||||
if (!input.filters.organization && !activeOrganization && !resolvedOrganizationFromMessage && candidateOrganizations.length === 1) {
|
||||
input.filters.organization = candidateOrganizations[0];
|
||||
if (!input.warnings.includes("organization_auto_selected_from_single_scope_candidate")) {
|
||||
|
||||
@@ -34,6 +34,9 @@ function hasAllTimeHint(text) {
|
||||
function hasSameDateHint(text) {
|
||||
return /(?:на\s+ту\s+же\s+дат[ауеы]|на\s+эту\s+же\s+дат[ауеы]|на\s+эту\s+дат[ауеы]|эту\s+дат[ауеы]|та\s+же\s+дата|дат[ауеы],?\s+котор(?:ую|ая)\s+(?:до\s+этого|раньше|ранее)\s+(?:рассматривали|смотрели)|дат[ауеы],?\s+которая\s+был[ао]?\s+ранее\s+рассмотрен[ао]?|same\s+date|as\s+of\s+same\s+date|the\s+same\s+date|date\s+we\s+looked\s+at\s+before|previously\s+considered\s+date)/iu.test(String(text ?? ""));
|
||||
}
|
||||
function hasSameDatePrepositionHint(text) {
|
||||
return /(?:по\s+(?:этой|той)\s+же\s+дат(?:е|у|ой))/iu.test(String(text ?? ""));
|
||||
}
|
||||
function hasSamePeriodHint(text) {
|
||||
return /(?:на\s+тот\s+же\s+период|за\s+тот\s+же\s+период|тот\s+же\s+период(?:\s+рассмотрения)?|на\s+этот\s+же\s+период|за\s+этот\s+же\s+период|за\s+этот\s+период|на\s+этот\s+период|за\s+тот\s+период|на\s+тот\s+период|этот\s+период|тот\s+период|аналогичн\w+\s+текущ\w+\s+период\w+|same\s+period|same\s+range|same\s+window)/iu.test(String(text ?? ""));
|
||||
}
|
||||
@@ -628,7 +631,7 @@ function mergeFollowupFilters(current, intent, userMessage, followupContext) {
|
||||
const relativeMonthFromInventoryRoot = resolveRelativeMonthPeriodFromInventoryRoot(userMessage, followupContext);
|
||||
const relativeMonthFromFollowupYear = resolveRelativeMonthPeriodFromFollowupYear(userMessage, followupContext);
|
||||
const allTimeRequested = hasAllTimeHint(userMessage);
|
||||
const sameDateRequested = hasSameDateHint(userMessage);
|
||||
const sameDateRequested = hasSameDateHint(userMessage) || hasSameDatePrepositionHint(userMessage);
|
||||
const samePeriodRequested = hasSamePeriodHint(userMessage);
|
||||
const explicitQuotedItem = extractSelectedObjectItemFromFollowupText(userMessage);
|
||||
if (!toNonEmptyString(merged.organization) && previousOrganization) {
|
||||
@@ -789,6 +792,23 @@ function mergeFollowupFilters(current, intent, userMessage, followupContext) {
|
||||
merged.as_of_date = inheritedAsOfDate;
|
||||
reasons.push("as_of_date_from_followup_context");
|
||||
}
|
||||
if ((intent === "inventory_on_hand_as_of_date" || intent === "inventory_supplier_stock_overlap_as_of_date") &&
|
||||
previousPeriodFrom &&
|
||||
merged.period_from !== previousPeriodFrom) {
|
||||
merged.period_from = previousPeriodFrom;
|
||||
reasons.push("period_from_from_followup_context");
|
||||
}
|
||||
if ((intent === "inventory_on_hand_as_of_date" || intent === "inventory_supplier_stock_overlap_as_of_date") &&
|
||||
previousPeriodTo &&
|
||||
merged.period_to !== previousPeriodTo) {
|
||||
merged.period_to = previousPeriodTo;
|
||||
reasons.push("period_to_from_followup_context");
|
||||
}
|
||||
const currentWarehouse = toNonEmptyString(merged.warehouse);
|
||||
if (currentWarehouse && hasSameDatePrepositionHint(currentWarehouse)) {
|
||||
delete merged.warehouse;
|
||||
reasons.push("warehouse_cleared_from_same_date_followup_noise");
|
||||
}
|
||||
}
|
||||
if (samePeriodRequested &&
|
||||
(intent === "vat_payable_confirmed_as_of_date" ||
|
||||
|
||||
@@ -645,15 +645,15 @@ function resolveAssistantOrganizationAuthority(input) {
|
||||
assistantSignals.lastAssistantActiveOrganization ??
|
||||
continuityActiveOrganization ??
|
||||
(knownOrganizations.length === 1 ? knownOrganizations[0] : null);
|
||||
const organizationClarificationCandidates = Array.isArray(input.lastOrganizationClarificationDebug?.organization_candidates)
|
||||
? mergeKnownOrganizations([
|
||||
...input.lastOrganizationClarificationDebug.organization_candidates,
|
||||
...knownOrganizations,
|
||||
selectedOrganization,
|
||||
activeOrganization,
|
||||
continuityActiveOrganization
|
||||
])
|
||||
: [];
|
||||
const organizationClarificationCandidates = mergeKnownOrganizations([
|
||||
...(Array.isArray(input.lastOrganizationClarificationDebug?.organization_candidates)
|
||||
? input.lastOrganizationClarificationDebug.organization_candidates
|
||||
: []),
|
||||
...knownOrganizations,
|
||||
selectedOrganization,
|
||||
activeOrganization,
|
||||
continuityActiveOrganization
|
||||
]);
|
||||
const organizationClarificationSelectionFromScope = selectedOrganization ?? activeOrganization;
|
||||
return {
|
||||
continuitySnapshot,
|
||||
|
||||
+7
-3
@@ -35,6 +35,7 @@ function resolveSessionOrganizationScopeContextRuntime(input) {
|
||||
const continuityKnownOrganizations = Array.isArray(continuityAuthority.knownOrganizations)
|
||||
? continuityAuthority.knownOrganizations
|
||||
: [];
|
||||
const continuitySelectedOrganization = input.normalizeOrganizationScopeValue(continuityAuthority.selectedOrganization);
|
||||
const continuityActiveOrganization = input.normalizeOrganizationScopeValue(continuityAuthority.activeOrganization);
|
||||
const knownOrganizations = Array.from(new Map([
|
||||
...continuityKnownOrganizations,
|
||||
@@ -44,8 +45,9 @@ function resolveSessionOrganizationScopeContextRuntime(input) {
|
||||
const selectedOrganization = input.resolveOrganizationSelectionFromMessage(input.userMessage, knownOrganizations);
|
||||
const navigationActiveOrganization = resolveActiveOrganizationFromNavigationState(input.addressNavigationState, input.normalizeOrganizationScopeValue);
|
||||
const activeOrganization = selectedOrganization ??
|
||||
navigationActiveOrganization ??
|
||||
continuitySelectedOrganization ??
|
||||
continuityActiveOrganization ??
|
||||
navigationActiveOrganization ??
|
||||
(knownOrganizations.length === 1 ? knownOrganizations[0] : null);
|
||||
return {
|
||||
knownOrganizations,
|
||||
@@ -64,7 +66,8 @@ function mergeFollowupContextWithOrganizationScopeRuntime(input) {
|
||||
const previousFilters = previousFiltersRaw && typeof previousFiltersRaw === "object"
|
||||
? { ...previousFiltersRaw }
|
||||
: {};
|
||||
if (!input.toNonEmptyString(previousFilters.organization)) {
|
||||
const previousOrganization = input.toNonEmptyString(previousFilters.organization);
|
||||
if (!previousOrganization || previousOrganization !== normalizedOrganization) {
|
||||
previousFilters.organization = normalizedOrganization;
|
||||
}
|
||||
base.previous_filters = previousFilters;
|
||||
@@ -72,7 +75,8 @@ function mergeFollowupContextWithOrganizationScopeRuntime(input) {
|
||||
const rootFilters = rootFiltersRaw && typeof rootFiltersRaw === "object"
|
||||
? { ...rootFiltersRaw }
|
||||
: {};
|
||||
if (!input.toNonEmptyString(rootFilters.organization)) {
|
||||
const rootOrganization = input.toNonEmptyString(rootFilters.organization);
|
||||
if (!rootOrganization || rootOrganization !== normalizedOrganization) {
|
||||
rootFilters.organization = normalizedOrganization;
|
||||
}
|
||||
if (Object.keys(rootFilters).length > 0) {
|
||||
|
||||
@@ -143,7 +143,7 @@ function resolveAddressLaneProtectionArbitration(input) {
|
||||
};
|
||||
}
|
||||
function createAssistantRoutePolicy(deps) {
|
||||
const { repairAddressMojibake, findLastGroundedAddressAnswerDebug, findLastOrganizationClarificationAddressDebug, mergeKnownOrganizations, normalizeOrganizationScopeValue, resolveOrganizationSelectionFromMessage, resolveMetaSignalSet, resolveHardMetaMode, isMetaFollowupOverGroundedAnswer, isAnswerInspectionFollowupOverGroundedAnswer, hasDataRetrievalRequestSignal, hasOrganizationFactLookupSignal, hasOrganizationFactFollowupSignal, hasAggregateBusinessAnalyticsSignal, hasStandaloneAddressTopicSignal, hasOpenContractsAddressSignal, detectAddressQuestionMode, resolveAddressIntent, toNonEmptyString, hasStrictDeepInvestigationCue, hasStrongDataIntentSignal, hasAccountingSignal, hasDangerOrCoercionSignal, hasAddressFollowupContextSignal, hasShortDebtMirrorFollowupSignal, isInventorySelectedObjectIntent, hasShortInventoryObjectFollowupSignal, isGroundedInventoryContextDebug, resolveRouteMemorySignals, findLastAddressAssistantItem, resolveAddressToolGateDecision: resolveAddressToolGateDecisionOverride, hasAddressLlmPreDecomposeCandidate, hasSameDateAccountFollowupSignalForPredecompose, hasLooseAllTimeAddressLookupSignal, hasDeepAnalysisPreferenceSignal, hasDirectDeepAnalysisSignal, compactWhitespace, hasDeepSessionContinuationSignal, resolveLivingAssistantModeDecision, resolveProviderExecutionState } = deps;
|
||||
const { repairAddressMojibake, findLastGroundedAddressAnswerDebug, findLastOrganizationClarificationAddressDebug, mergeKnownOrganizations, normalizeOrganizationScopeValue, resolveOrganizationSelectionFromMessage, resolveMetaSignalSet, resolveHardMetaMode, isMetaFollowupOverGroundedAnswer, isAnswerInspectionFollowupOverGroundedAnswer, hasDataRetrievalRequestSignal, hasOrganizationFactLookupSignal, hasOrganizationFactFollowupSignal, hasAggregateBusinessAnalyticsSignal, hasStandaloneAddressTopicSignal, hasOpenContractsAddressSignal, detectAddressQuestionMode, resolveAddressIntent, toNonEmptyString, hasStrictDeepInvestigationCue, hasStrongDataIntentSignal, hasAccountingSignal, hasDangerOrCoercionSignal, hasAddressFollowupContextSignal, hasShortDebtMirrorFollowupSignal, isInventorySelectedObjectIntent, hasShortInventoryObjectFollowupSignal, isGroundedInventoryContextDebug, resolveRouteMemorySignals, findLastAddressAssistantItem, resolveAddressToolGateDecision: resolveAddressToolGateDecisionOverride, hasAddressLlmPreDecomposeCandidate, hasSameDateAccountFollowupSignalForPredecompose, hasLooseAllTimeAddressLookupSignal, hasDeepAnalysisPreferenceSignal, hasDirectDeepAnalysisSignal, shouldEmitOrganizationSelectionReply, compactWhitespace, hasDeepSessionContinuationSignal, resolveLivingAssistantModeDecision, resolveProviderExecutionState } = deps;
|
||||
function resolveBaseAddressToolGateDecision(addressInputMessage, followupContext, llmPreDecomposeMeta = null, rawUserMessage = null) {
|
||||
const repairedInputMessage = repairAddressMojibake(String(addressInputMessage ?? ""));
|
||||
const rawMessageForGate = String(rawUserMessage ?? addressInputMessage ?? "");
|
||||
@@ -447,6 +447,13 @@ function createAssistantRoutePolicy(deps) {
|
||||
!dataScopeMetaQuery &&
|
||||
!capabilityMetaQuery &&
|
||||
!dataRetrievalSignal);
|
||||
const organizationScopeSwitchDetected = Boolean(organizationClarificationSelection &&
|
||||
!dataScopeMetaQuery &&
|
||||
!capabilityMetaQuery &&
|
||||
(shouldEmitOrganizationSelectionReply(rawUserMessage, organizationClarificationSelection) ||
|
||||
shouldEmitOrganizationSelectionReply(repairedRawUserMessage, organizationClarificationSelection) ||
|
||||
shouldEmitOrganizationSelectionReply(effectiveAddressUserMessage, organizationClarificationSelection) ||
|
||||
shouldEmitOrganizationSelectionReply(repairedEffectiveAddressUserMessage, organizationClarificationSelection)));
|
||||
const effectiveAddressFollowupSignal = explicitAddressFollowupSignal && !dangerOrCoercionSignal;
|
||||
const baseToolGate = typeof resolveAddressToolGateDecisionOverride === "function"
|
||||
? resolveAddressToolGateDecisionOverride(effectiveAddressUserMessage, followupContext, llmPreDecomposeMeta, rawUserMessage)
|
||||
@@ -653,6 +660,37 @@ function createAssistantRoutePolicy(deps) {
|
||||
}
|
||||
};
|
||||
}
|
||||
if (organizationScopeSwitchDetected) {
|
||||
return {
|
||||
runAddressLane: false,
|
||||
toolGateDecision: "skip_address_lane",
|
||||
toolGateReason: "organization_scope_switch_detected",
|
||||
livingMode: "chat",
|
||||
livingReason: "organization_scope_switch_detected",
|
||||
orchestrationContract: {
|
||||
schema_version: "assistant_orchestration_contract_v1",
|
||||
hard_meta_mode: null,
|
||||
provider_execution: providerExecution,
|
||||
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 || continuitySnapshot.hasGroundedAddressContext),
|
||||
organization_scope_switch_detected: true,
|
||||
organization_scope_selection: organizationClarificationSelection,
|
||||
unsupported_address_intent_fallback_to_deep: false,
|
||||
final_decision: {
|
||||
run_address_lane: false,
|
||||
tool_gate_decision: "skip_address_lane",
|
||||
tool_gate_reason: "organization_scope_switch_detected",
|
||||
living_mode: "chat",
|
||||
living_reason: "organization_scope_switch_detected"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
const supportedExactInvestigativeAddressBypass = Boolean(llmContractMode === "deep_analysis" &&
|
||||
semanticApplyCanonicalRecommended &&
|
||||
strictDeepInvestigationBypassAllowed &&
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.INVENTORY_CAPABILITY_CONTRACTS = exports.ASSISTANT_TRANSITION_CONTRACTS = void 0;
|
||||
exports.ROOT_EXACT_CAPABILITY_CONTRACTS = exports.INVENTORY_CAPABILITY_CONTRACTS = exports.ASSISTANT_TRANSITION_CONTRACTS = void 0;
|
||||
exports.listAssistantTransitionContracts = listAssistantTransitionContracts;
|
||||
exports.getAssistantTransitionContract = getAssistantTransitionContract;
|
||||
exports.listInventoryCapabilityContracts = listInventoryCapabilityContracts;
|
||||
@@ -139,6 +139,60 @@ const INVENTORY_SELECTED_OBJECT_TESTS = [
|
||||
"new_explicit_selected_object_overrides_old_focus",
|
||||
"full_anchor_not_degraded_by_canonical_rewrite"
|
||||
];
|
||||
const SHARED_ROOT_EXACT_TESTS = [
|
||||
"root_context_survives_domain_pivot_without_object_leak",
|
||||
"limited_mode_remains_truthful"
|
||||
];
|
||||
function rootExactCapability(input) {
|
||||
return {
|
||||
schema_version: assistantRuntimeContracts_1.ASSISTANT_RUNTIME_CONTRACTS_SCHEMA_VERSION,
|
||||
capability_id: input.capability_id,
|
||||
domain_id: input.domainId,
|
||||
runtime_lane: "address_exact",
|
||||
intent_ids: input.intent_ids,
|
||||
entry_modes: ["root_entry", "root_followup", "clarification_resume"],
|
||||
supported_transition_classes: input.transitions,
|
||||
frame_compatibility: {
|
||||
root_frame: "optional",
|
||||
selected_object_frame: "optional",
|
||||
meta_frame: "forbidden"
|
||||
},
|
||||
required_anchors: input.requiredAnchors,
|
||||
optional_anchors: input.optionalAnchors ?? ["organization", "date_scope", "account", "counterparty", "contract"],
|
||||
anchor_source_priority: ["explicit_user_anchor", "root_frame", "semantic_hint"],
|
||||
anchor_admissibility_rules: [
|
||||
"confirmed_root_scope_beats_semantic_hint",
|
||||
"no_low_quality_counterparty_rewrite",
|
||||
"no_conversational_noise_as_entity"
|
||||
],
|
||||
organization_scope_behavior: "reuse_or_clarify",
|
||||
date_scope_behavior: "reuse",
|
||||
temporal_ceiling_policy: "must_not_expand_without_reason_code",
|
||||
root_context_compatibility: "required",
|
||||
requires_focus_object: false,
|
||||
accepted_focus_object_kinds: [],
|
||||
focus_object_override_policy: "not_applicable",
|
||||
bundle_reuse_policy: "none",
|
||||
resolver_owner: "addressIntentResolver",
|
||||
recipe_owner: "addressRecipeCatalog",
|
||||
execution_adapter: "AddressQueryService",
|
||||
result_shape: input.resultShape,
|
||||
answer_object_shape: input.answerObjectShape,
|
||||
minimum_evidence_policy: "route_specific_threshold",
|
||||
coverage_gate_behavior: "partial_or_blocked_if_evidence_insufficient",
|
||||
truth_mode_fallbacks: ["limited", "clarification_required", "unsupported"],
|
||||
blocked_reason_codes: ["missing_anchor", "route_expectation_failure", "execution_error", "insufficient_evidence"],
|
||||
clarification_triggers: ["ambiguous_organization_scope", "ambiguous_date_scope"],
|
||||
clarification_questions: ["Уточните организацию, счёт или дату, чтобы не подставлять неподтверждённый контур."],
|
||||
resume_policy: "resume_original_route_with_resolved_anchors",
|
||||
empty_match_behavior: "truthful_empty_match",
|
||||
route_expectation_failure_behavior: "blocked_route_expectation_failure",
|
||||
execution_error_behavior: "blocked_execution_error",
|
||||
required_unit_tests: [...SHARED_ROOT_EXACT_TESTS],
|
||||
required_transition_tests: input.transitions.map((transitionId) => `transition_${transitionId}`),
|
||||
required_scenario_families: input.scenarioFamilies ?? ["canonical", "colloquial", "followup_date_carryover"]
|
||||
};
|
||||
}
|
||||
function inventoryExactCapability(input) {
|
||||
return {
|
||||
schema_version: assistantRuntimeContracts_1.ASSISTANT_RUNTIME_CONTRACTS_SCHEMA_VERSION,
|
||||
@@ -269,6 +323,69 @@ exports.INVENTORY_CAPABILITY_CONTRACTS = [
|
||||
scenarioFamilies: ["canonical", "colloquial", "followup_date_carryover"]
|
||||
})
|
||||
];
|
||||
exports.ROOT_EXACT_CAPABILITY_CONTRACTS = [
|
||||
rootExactCapability({
|
||||
capability_id: "confirmed_payables_as_of_date",
|
||||
domainId: "counterparty_debt",
|
||||
intent_ids: ["payables_confirmed_as_of_date"],
|
||||
transitions: ["T1", "T2", "T6", "T7"],
|
||||
requiredAnchors: [],
|
||||
resultShape: "counterparty_payables_snapshot",
|
||||
answerObjectShape: "payables_snapshot"
|
||||
}),
|
||||
rootExactCapability({
|
||||
capability_id: "confirmed_receivables_as_of_date",
|
||||
domainId: "counterparty_debt",
|
||||
intent_ids: ["receivables_confirmed_as_of_date"],
|
||||
transitions: ["T1", "T2", "T6", "T7"],
|
||||
requiredAnchors: [],
|
||||
resultShape: "counterparty_receivables_snapshot",
|
||||
answerObjectShape: "receivables_snapshot"
|
||||
}),
|
||||
rootExactCapability({
|
||||
capability_id: "confirmed_open_contracts_as_of_date",
|
||||
domainId: "contracts",
|
||||
intent_ids: ["open_contracts_confirmed_as_of_date"],
|
||||
transitions: ["T1", "T2", "T6", "T7"],
|
||||
requiredAnchors: [],
|
||||
resultShape: "open_contracts_snapshot",
|
||||
answerObjectShape: "open_contracts_snapshot"
|
||||
}),
|
||||
rootExactCapability({
|
||||
capability_id: "confirmed_vat_payable_as_of_date",
|
||||
domainId: "vat",
|
||||
intent_ids: ["vat_payable_confirmed_as_of_date"],
|
||||
transitions: ["T1", "T2", "T6", "T7"],
|
||||
requiredAnchors: [],
|
||||
resultShape: "vat_payable_snapshot",
|
||||
answerObjectShape: "vat_payable_snapshot"
|
||||
}),
|
||||
rootExactCapability({
|
||||
capability_id: "confirmed_vat_liability_for_tax_period",
|
||||
domainId: "vat",
|
||||
intent_ids: ["vat_liability_confirmed_for_tax_period"],
|
||||
transitions: ["T1", "T2", "T6", "T7"],
|
||||
requiredAnchors: [],
|
||||
resultShape: "vat_tax_period_liability_snapshot",
|
||||
answerObjectShape: "vat_tax_period_liability_snapshot",
|
||||
scenarioFamilies: ["canonical", "colloquial", "followup_date_carryover", "tax_period_followup"]
|
||||
}),
|
||||
rootExactCapability({
|
||||
capability_id: "account_balance_exact",
|
||||
domainId: "accounting_balance",
|
||||
intent_ids: ["account_balance_snapshot", "documents_forming_balance"],
|
||||
transitions: ["T1", "T2", "T6", "T7"],
|
||||
requiredAnchors: ["account"],
|
||||
optionalAnchors: ["organization", "date_scope", "account"],
|
||||
resultShape: "account_balance_snapshot_or_supporting_documents",
|
||||
answerObjectShape: "account_balance_context",
|
||||
scenarioFamilies: ["canonical", "colloquial", "followup_date_carryover", "same_date_account_followup"]
|
||||
})
|
||||
];
|
||||
const ALL_CAPABILITY_CONTRACTS = [
|
||||
...exports.INVENTORY_CAPABILITY_CONTRACTS,
|
||||
...exports.ROOT_EXACT_CAPABILITY_CONTRACTS
|
||||
];
|
||||
function listAssistantTransitionContracts() {
|
||||
return exports.ASSISTANT_TRANSITION_CONTRACTS;
|
||||
}
|
||||
@@ -279,8 +396,8 @@ function listInventoryCapabilityContracts() {
|
||||
return exports.INVENTORY_CAPABILITY_CONTRACTS;
|
||||
}
|
||||
function getAssistantCapabilityContract(capabilityId) {
|
||||
return exports.INVENTORY_CAPABILITY_CONTRACTS.find((contract) => contract.capability_id === capabilityId) ?? null;
|
||||
return ALL_CAPABILITY_CONTRACTS.find((contract) => contract.capability_id === capabilityId) ?? null;
|
||||
}
|
||||
function getAssistantCapabilityContractByIntent(intent) {
|
||||
return exports.INVENTORY_CAPABILITY_CONTRACTS.find((contract) => contract.intent_ids.includes(intent)) ?? null;
|
||||
return ALL_CAPABILITY_CONTRACTS.find((contract) => contract.intent_ids.includes(intent)) ?? null;
|
||||
}
|
||||
|
||||
@@ -4092,6 +4092,7 @@ const assistantRoutePolicy = (0, assistantRoutePolicy_1.createAssistantRoutePoli
|
||||
hasLooseAllTimeAddressLookupSignal,
|
||||
hasDeepAnalysisPreferenceSignal,
|
||||
hasDirectDeepAnalysisSignal,
|
||||
shouldEmitOrganizationSelectionReply: assistantLivingModePolicy.shouldEmitOrganizationSelectionReply,
|
||||
compactWhitespace,
|
||||
hasDeepSessionContinuationSignal,
|
||||
resolveLivingAssistantModeDecision: assistantLivingModePolicy.resolveLivingAssistantModeDecision,
|
||||
|
||||
Reference in New Issue
Block a user