АРЧ АП11 - Вынести provider runtime policy из оркестрации и закрыть Phase 6 агентным прогоном

This commit is contained in:
2026-04-17 12:02:38 +03:00
parent 15fa643fc8
commit f5ff844105
16 changed files with 647 additions and 52 deletions
@@ -2,7 +2,7 @@
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAssistantLivingModePolicy = createAssistantLivingModePolicy;
function createAssistantLivingModePolicy(deps) {
const { featureAssistantLivingChatRouterV1, compactWhitespace, repairAddressMojibake, toNonEmptyString, normalizeOrganizationScopeValue, hasReferentialPointer, hasSmallTalkSignal, hasAssistantCapabilityQuestionSignal, hasOperationalAdminActionRequestSignal } = deps;
const { featureAssistantLivingChatRouterV1, compactWhitespace, repairAddressMojibake, toNonEmptyString, normalizeOrganizationScopeValue, hasReferentialPointer, hasSmallTalkSignal, hasAssistantCapabilityQuestionSignal, hasOperationalAdminActionRequestSignal, resolveProviderExecutionState } = deps;
function hasStrongDataIntentSignal(text) {
const lower = String(text ?? "").toLowerCase();
return /(база|док|документ|проводк|контрагент|договор|контракт|счет|сч[её]т|остат|сальдо|хвост|платеж|плат[её]ж|операц|поставщик|клиент|заказчик|дебитор|кредитор|оборот|баланс|период|месяц|год|инн|аванс|предоплат|отгруз|задолж|долг|склад|товар|номенклат|материал|mcp|bank|counterparty|contract|document|ledger|posting|account|organization|company|advance|prepay|shipment|receivab|payab|warehouse|inventory|stock|item|организац|компан|контор|фирм)/i.test(lower);
@@ -267,10 +267,14 @@ function createAssistantLivingModePolicy(deps) {
reason: "living_chat_router_disabled"
};
}
if (Boolean(input?.useMock)) {
const providerExecution = resolveProviderExecutionState({
llmProvider: input?.llmProvider,
useMock: input?.useMock
});
if (providerExecution.living_mode_forced_deep) {
return {
mode: "deep_analysis",
reason: "mock_mode_keeps_deep_pipeline"
reason: providerExecution.living_mode_forced_reason ?? "mock_mode_keeps_deep_pipeline"
};
}
if (hasAssistantDataScopeMetaQuestionSignal(userMessage)) {
@@ -0,0 +1,59 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ASSISTANT_PROVIDER_EXECUTION_CONTRACT_SCHEMA_VERSION = void 0;
exports.createAssistantProviderExecutionPolicy = createAssistantProviderExecutionPolicy;
exports.ASSISTANT_PROVIDER_EXECUTION_CONTRACT_SCHEMA_VERSION = "assistant_provider_execution_contract_v1";
function createAssistantProviderExecutionPolicy() {
function normalizeProvider(value) {
return value === "local" ? "local" : value === "openai" ? "openai" : null;
}
function detectLlmRuntimeUnavailable(reason) {
const source = String(reason ?? "").trim();
if (!source) {
return false;
}
return /(?:openai\s+api\s+key\s+is\s+missing|api\s+key\s+is\s+missing|missing\s+api\s+key|authentication|unauthoriz(?:ed|ation)|401\b)/iu.test(source);
}
function resolveProviderExecutionState(input) {
const normalizedProvider = normalizeProvider(input?.llmProvider);
const useMock = Boolean(input?.useMock);
const baseUrlConfigured = String(input?.baseUrl ?? "").trim().length > 0;
const llmRuntimeUnavailableDetected = detectLlmRuntimeUnavailable(input?.llmPreDecomposeReason);
const reasonCodes = [];
if (useMock) {
reasonCodes.push("mock_mode_enabled");
}
if (normalizedProvider === "local") {
reasonCodes.push("provider_local");
}
else if (normalizedProvider === "openai") {
reasonCodes.push("provider_openai");
}
else {
reasonCodes.push("provider_unknown");
}
if (baseUrlConfigured) {
reasonCodes.push("base_url_configured");
}
if (llmRuntimeUnavailableDetected) {
reasonCodes.push("llm_runtime_unavailable");
}
return {
schema_version: exports.ASSISTANT_PROVIDER_EXECUTION_CONTRACT_SCHEMA_VERSION,
policy_owner: "assistantProviderExecutionPolicy",
provider_mode: useMock ? "mock" : normalizedProvider ?? "unknown",
normalized_provider: normalizedProvider,
use_mock: useMock,
base_url_configured: baseUrlConfigured,
llm_runtime_unavailable_detected: llmRuntimeUnavailableDetected,
living_mode_forced_deep: useMock,
living_mode_forced_reason: useMock ? "mock_mode_keeps_deep_pipeline" : null,
reason_codes: reasonCodes
};
}
return {
normalizeProvider,
detectLlmRuntimeUnavailable,
resolveProviderExecutionState
};
}
@@ -46,7 +46,7 @@ function shouldBypassStrictDeepInvestigationCueForAddressIntent(intent) {
return Boolean(intent && ADDRESS_INTENTS_ALLOW_STRICT_DEEP_INVESTIGATION_BYPASS.has(intent));
}
function createAssistantRoutePolicy(deps) {
const { repairAddressMojibake, findLastGroundedAddressAnswerDebug, findLastOrganizationClarificationAddressDebug, mergeKnownOrganizations, normalizeOrganizationScopeValue, resolveOrganizationSelectionFromMessage, resolveMetaSignalSet, resolveHardMetaMode, isMetaFollowupOverGroundedAnswer, hasDataRetrievalRequestSignal, hasAggregateBusinessAnalyticsSignal, hasStandaloneAddressTopicSignal, hasOpenContractsAddressSignal, detectAddressQuestionMode, resolveAddressIntent, toNonEmptyString, hasStrictDeepInvestigationCue, hasStrongDataIntentSignal, hasAccountingSignal, hasDangerOrCoercionSignal, hasAddressFollowupContextSignal, hasShortDebtMirrorFollowupSignal, isInventorySelectedObjectIntent, hasShortInventoryObjectFollowupSignal, isGroundedInventoryContextDebug, resolveRouteMemorySignals, findLastAddressAssistantItem, resolveAddressToolGateDecision, hasSameDateAccountFollowupSignalForPredecompose, hasLooseAllTimeAddressLookupSignal, hasDeepAnalysisPreferenceSignal, hasDirectDeepAnalysisSignal, compactWhitespace, hasDeepSessionContinuationSignal, resolveLivingAssistantModeDecision } = deps;
const { repairAddressMojibake, findLastGroundedAddressAnswerDebug, findLastOrganizationClarificationAddressDebug, mergeKnownOrganizations, normalizeOrganizationScopeValue, resolveOrganizationSelectionFromMessage, resolveMetaSignalSet, resolveHardMetaMode, isMetaFollowupOverGroundedAnswer, hasDataRetrievalRequestSignal, hasAggregateBusinessAnalyticsSignal, hasStandaloneAddressTopicSignal, hasOpenContractsAddressSignal, detectAddressQuestionMode, resolveAddressIntent, toNonEmptyString, hasStrictDeepInvestigationCue, hasStrongDataIntentSignal, hasAccountingSignal, hasDangerOrCoercionSignal, hasAddressFollowupContextSignal, hasShortDebtMirrorFollowupSignal, isInventorySelectedObjectIntent, hasShortInventoryObjectFollowupSignal, isGroundedInventoryContextDebug, resolveRouteMemorySignals, findLastAddressAssistantItem, resolveAddressToolGateDecision, hasSameDateAccountFollowupSignalForPredecompose, hasLooseAllTimeAddressLookupSignal, hasDeepAnalysisPreferenceSignal, hasDirectDeepAnalysisSignal, compactWhitespace, hasDeepSessionContinuationSignal, resolveLivingAssistantModeDecision, resolveProviderExecutionState } = deps;
function resolveAssistantOrchestrationDecision(input) {
const rawUserMessage = String(input?.rawUserMessage ?? input?.userMessage ?? "");
const effectiveAddressUserMessage = String(input?.effectiveAddressUserMessage ?? rawUserMessage);
@@ -111,8 +111,11 @@ function createAssistantRoutePolicy(deps) {
const resolvedIntentResolution = intentResolution.intent !== "unknown" ? intentResolution : intentResolutionRaw;
const llmContractIntent = toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.intent);
const llmPreDecomposeReason = toNonEmptyString(llmPreDecomposeMeta?.reason);
const llmRuntimeUnavailableDetected = Boolean(llmPreDecomposeReason &&
/(?:openai\s+api\s+key\s+is\s+missing|api\s+key\s+is\s+missing|missing\s+api\s+key|authentication)/iu.test(llmPreDecomposeReason));
const providerExecution = resolveProviderExecutionState({
useMock,
llmPreDecomposeReason
});
const llmRuntimeUnavailableDetected = providerExecution.llm_runtime_unavailable_detected === true;
const semanticExtractionContract = llmPreDecomposeMeta?.semanticExtractionContract &&
typeof llmPreDecomposeMeta.semanticExtractionContract === "object"
? llmPreDecomposeMeta.semanticExtractionContract
@@ -224,6 +227,7 @@ function createAssistantRoutePolicy(deps) {
orchestrationContract: {
schema_version: "assistant_orchestration_contract_v1",
hard_meta_mode: "data_scope",
provider_execution: providerExecution,
address_mode: resolvedModeDetection.mode,
address_mode_confidence: resolvedModeDetection.confidence,
address_intent: resolvedIntentResolution.intent,
@@ -253,6 +257,7 @@ function createAssistantRoutePolicy(deps) {
orchestrationContract: {
schema_version: "assistant_orchestration_contract_v1",
hard_meta_mode: "capability",
provider_execution: providerExecution,
address_mode: resolvedModeDetection.mode,
address_mode_confidence: resolvedModeDetection.confidence,
address_intent: resolvedIntentResolution.intent,
@@ -280,6 +285,7 @@ function createAssistantRoutePolicy(deps) {
orchestrationContract: {
schema_version: "assistant_orchestration_contract_v1",
hard_meta_mode: "capability",
provider_execution: providerExecution,
address_mode: resolvedModeDetection.mode,
address_mode_confidence: resolvedModeDetection.confidence,
address_intent: resolvedIntentResolution.intent,
@@ -309,6 +315,7 @@ function createAssistantRoutePolicy(deps) {
orchestrationContract: {
schema_version: "assistant_orchestration_contract_v1",
hard_meta_mode: "non_domain",
provider_execution: providerExecution,
address_mode: resolvedModeDetection.mode,
address_mode_confidence: resolvedModeDetection.confidence,
address_intent: resolvedIntentResolution.intent,
@@ -336,6 +343,7 @@ function createAssistantRoutePolicy(deps) {
orchestrationContract: {
schema_version: "assistant_orchestration_contract_v1",
hard_meta_mode: "non_domain",
provider_execution: providerExecution,
address_mode: resolvedModeDetection.mode,
address_mode_confidence: resolvedModeDetection.confidence,
address_intent: resolvedIntentResolution.intent,
@@ -507,6 +515,7 @@ function createAssistantRoutePolicy(deps) {
let livingDecision = resolveLivingAssistantModeDecision({
userMessage: rawUserMessage,
addressLaneTriggered: runAddressLane,
llmProvider: providerExecution.normalized_provider,
useMock,
predecomposeMode: llmPreDecomposeMeta?.predecomposeContract?.mode ?? null,
predecomposeModeConfidence: llmPreDecomposeMeta?.predecomposeContract?.mode_confidence ?? null
@@ -552,6 +561,7 @@ function createAssistantRoutePolicy(deps) {
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,
+24 -4
View File
@@ -70,6 +70,7 @@ const assistantBoundaryPolicy_1 = __importStar(require("./assistantBoundaryPolic
const assistantLivingModePolicy_1 = __importStar(require("./assistantLivingModePolicy"));
const assistantMetaFollowupPolicy_1 = __importStar(require("./assistantMetaFollowupPolicy"));
const assistantMemoryRecapPolicy_1 = __importStar(require("./assistantMemoryRecapPolicy"));
const assistantProviderExecutionPolicy_1 = __importStar(require("./assistantProviderExecutionPolicy"));
const assistantRoutePolicy_1 = __importStar(require("./assistantRoutePolicy"));
const assistantTransitionPolicy_1 = __importStar(require("./assistantTransitionPolicy"));
const assistantOrganizationScopeRuntimeAdapter_1 = __importStar(require("./assistantOrganizationScopeRuntimeAdapter"));
@@ -3822,6 +3823,8 @@ function hasPredecomposeDiagnosticUncertaintyLead(text) {
return /^(?:неясно|не\s+ясно|непонятно|не\s+понятно|unclear|not\s+clear|ambiguous|unknown)(?=$|[\s,.;:!?])/iu.test(normalized);
}
function attachAddressPredecomposeContract(meta, sourceMessage) {
const sourceMeta = meta && typeof meta === "object" ? meta : {};
const { providerExecutionInput, providerExecutionContract: providerExecutionContractInput, ...restMeta } = sourceMeta;
const canonicalMessage = toNonEmptyString(meta?.effectiveMessage) ?? String(sourceMessage ?? "");
const predecomposeContract = (0, predecomposeContract_1.buildAddressLlmPredecomposeContractV1)({
sourceMessage: String(sourceMessage ?? ""),
@@ -3833,20 +3836,34 @@ function attachAddressPredecomposeContract(meta, sourceMessage) {
canonicalMessage,
predecomposeContract
});
const providerExecutionContract = providerExecutionContractInput && typeof providerExecutionContractInput === "object"
? providerExecutionContractInput
: assistantProviderExecutionPolicy.resolveProviderExecutionState({
llmProvider: providerExecutionInput?.llmProvider,
useMock: providerExecutionInput?.useMock,
baseUrl: providerExecutionInput?.baseUrl,
llmPreDecomposeReason: restMeta?.reason
});
return {
...meta,
...restMeta,
providerExecutionContract,
predecomposeContract,
semanticExtractionContract
};
}
async function runAddressLlmPreDecompose(normalizerService, payload, userMessage) {
const provider = payload?.llmProvider === "local" ? "local" : payload?.llmProvider === "openai" ? "openai" : null;
const provider = assistantProviderExecutionPolicy.normalizeProvider(payload?.llmProvider);
const sanitizedUserMessage = sanitizeAddressMessageForFallback(userMessage);
const fallbackCandidate = resolveAddressDeterministicFallback(userMessage, sanitizedUserMessage);
const baseMeta = {
attempted: false,
applied: false,
provider,
providerExecutionInput: {
llmProvider: payload?.llmProvider,
useMock: payload?.useMock,
baseUrl: payload?.baseUrl
},
traceId: null,
effectiveMessage: userMessage,
reason: "not_attempted",
@@ -4744,6 +4761,7 @@ function normalizeOrganizationScopeValue(value) {
.trim();
return unwrapped ? unwrapped : null;
}
const assistantProviderExecutionPolicy = (0, assistantProviderExecutionPolicy_1.createAssistantProviderExecutionPolicy)();
const assistantLivingModePolicy = (0, assistantLivingModePolicy_1.createAssistantLivingModePolicy)({
featureAssistantLivingChatRouterV1: config_1.FEATURE_ASSISTANT_LIVING_CHAT_ROUTER_V1,
compactWhitespace,
@@ -4753,7 +4771,8 @@ const assistantLivingModePolicy = (0, assistantLivingModePolicy_1.createAssistan
hasReferentialPointer,
hasSmallTalkSignal,
hasAssistantCapabilityQuestionSignal,
hasOperationalAdminActionRequestSignal
hasOperationalAdminActionRequestSignal,
resolveProviderExecutionState: assistantProviderExecutionPolicy.resolveProviderExecutionState
});
const assistantMetaFollowupPolicy = (0, assistantMetaFollowupPolicy_1.createAssistantMetaFollowupPolicy)({
hasAssistantDataScopeMetaQuestionSignal: assistantLivingModePolicy.hasAssistantDataScopeMetaQuestionSignal,
@@ -4799,7 +4818,8 @@ const assistantRoutePolicy = (0, assistantRoutePolicy_1.createAssistantRoutePoli
hasDirectDeepAnalysisSignal,
compactWhitespace,
hasDeepSessionContinuationSignal,
resolveLivingAssistantModeDecision: assistantLivingModePolicy.resolveLivingAssistantModeDecision
resolveLivingAssistantModeDecision: assistantLivingModePolicy.resolveLivingAssistantModeDecision,
resolveProviderExecutionState: assistantProviderExecutionPolicy.resolveProviderExecutionState
});
const assistantTransitionPolicy = (0, assistantTransitionPolicy_1.createAssistantTransitionPolicy)({
compactWhitespace,