АРЧ АП11 - Архитектура после регресса: Архитектура: централизовать organization authority в continuity policy для route, living-chat и data-scope

This commit is contained in:
2026-04-18 16:53:04 +03:00
parent 53e9151d5a
commit 9710d81676
16 changed files with 575 additions and 366 deletions
@@ -8,6 +8,8 @@ exports.readAddressDebugScopedDate = readAddressDebugScopedDate;
exports.buildInventoryRootFrameFromAddressDebug = buildInventoryRootFrameFromAddressDebug;
exports.isGroundedAddressDebug = isGroundedAddressDebug;
exports.resolveAssistantContinuitySnapshot = resolveAssistantContinuitySnapshot;
exports.resolveAssistantOrganizationAuthority = resolveAssistantOrganizationAuthority;
const assistantOrganizationMatcher_1 = require("./assistantOrganizationMatcher");
function fallbackToNonEmptyString(value) {
if (value === null || value === undefined) {
return null;
@@ -21,6 +23,12 @@ function toRecordObject(value) {
}
return value;
}
function mergeKnownOrganizationsDefault(values) {
return (0, assistantOrganizationMatcher_1.mergeKnownOrganizations)(values);
}
function normalizeOrganizationScopeDefault(value) {
return (0, assistantOrganizationMatcher_1.normalizeOrganizationScopeValue)(value);
}
function formatIsoDateForReply(value) {
const source = String(value ?? "").trim();
const match = source.match(/^(\d{4})-(\d{2})-(\d{2})$/);
@@ -166,3 +174,87 @@ function resolveAssistantContinuitySnapshot(input) {
hasGroundedInventoryContext: Boolean(lastGroundedInventoryAddressDebug)
};
}
function collectAssistantOrganizationSignals(sessionItems, normalizeOrganizationScopeValue) {
let lastAssistantSelectedOrganization = null;
let lastAssistantActiveOrganization = null;
const knownOrganizationsFromAssistantHistory = [];
for (let index = sessionItems.length - 1; index >= 0; index -= 1) {
const item = sessionItems[index];
if (!item || item.role !== "assistant" || !item.debug || typeof item.debug !== "object") {
continue;
}
const debug = item.debug;
if (!lastAssistantActiveOrganization) {
lastAssistantActiveOrganization = normalizeOrganizationScopeValue(debug.assistant_active_organization);
}
if (!lastAssistantSelectedOrganization) {
lastAssistantSelectedOrganization = normalizeOrganizationScopeValue(debug.living_chat_selected_organization);
}
const directKnownOrganizations = Array.isArray(debug.assistant_known_organizations)
? debug.assistant_known_organizations
: [];
const probeOrganizations = Array.isArray(debug.living_chat_data_scope_probe_organizations)
? debug.living_chat_data_scope_probe_organizations
: [];
const organizationCandidates = Array.isArray(debug.organization_candidates) ? debug.organization_candidates : [];
const directResolvedOrganizations = [
debug.assistant_active_organization,
debug.living_chat_selected_organization,
readAddressDebugOrganization(debug, normalizeOrganizationScopeValue)
];
knownOrganizationsFromAssistantHistory.push(...directKnownOrganizations, ...probeOrganizations, ...organizationCandidates, ...directResolvedOrganizations);
}
return {
lastAssistantSelectedOrganization,
lastAssistantActiveOrganization,
knownOrganizationsFromAssistantHistory: mergeKnownOrganizationsDefault(knownOrganizationsFromAssistantHistory)
};
}
function resolveAssistantOrganizationAuthority(input) {
const normalizeOrganizationScopeValue = input.normalizeOrganizationScopeValue ?? normalizeOrganizationScopeDefault;
const mergeKnownOrganizations = input.mergeKnownOrganizations ?? mergeKnownOrganizationsDefault;
const sessionItems = Array.isArray(input.sessionItems) ? input.sessionItems : [];
const continuitySnapshot = resolveAssistantContinuitySnapshot({
sessionItems,
toNonEmptyString: input.toNonEmptyString ?? normalizeOrganizationScopeValue
});
const assistantSignals = collectAssistantOrganizationSignals(sessionItems, normalizeOrganizationScopeValue);
const continuityActiveOrganization = normalizeOrganizationScopeValue(input.sessionActiveOrganization) ??
assistantSignals.lastAssistantActiveOrganization ??
normalizeOrganizationScopeValue(continuitySnapshot.activeOrganization);
const knownOrganizations = mergeKnownOrganizations([
...(Array.isArray(input.sessionKnownOrganizations) ? input.sessionKnownOrganizations : []),
...assistantSignals.knownOrganizationsFromAssistantHistory,
input.sessionSelectedOrganization,
input.sessionActiveOrganization,
continuityActiveOrganization
]);
const selectedOrganization = normalizeOrganizationScopeValue(input.sessionSelectedOrganization) ??
assistantSignals.lastAssistantSelectedOrganization;
const activeOrganization = normalizeOrganizationScopeValue(input.sessionActiveOrganization) ??
selectedOrganization ??
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 organizationClarificationSelectionFromScope = selectedOrganization ?? activeOrganization;
return {
continuitySnapshot,
continuityActiveOrganization,
lastAssistantSelectedOrganization: assistantSignals.lastAssistantSelectedOrganization,
lastAssistantActiveOrganization: assistantSignals.lastAssistantActiveOrganization,
knownOrganizations,
selectedOrganization,
activeOrganization,
organizationClarificationCandidates,
organizationClarificationSelectionFromScope
};
}
@@ -219,36 +219,13 @@ function createAssistantDataScopePolicy(deps) {
return (0, assistantOrganizationMatcher_1.mergeKnownOrganizations)(collected, 20);
}
function findLastAssistantActiveOrganization(items) {
const continuitySnapshot = (0, assistantContinuityPolicy_1.resolveAssistantContinuitySnapshot)({
const authority = (0, assistantContinuityPolicy_1.resolveAssistantOrganizationAuthority)({
sessionItems: items,
toNonEmptyString: assistantOrganizationMatcher_1.normalizeOrganizationScopeValue
toNonEmptyString: assistantOrganizationMatcher_1.normalizeOrganizationScopeValue,
normalizeOrganizationScopeValue: assistantOrganizationMatcher_1.normalizeOrganizationScopeValue,
mergeKnownOrganizations: assistantOrganizationMatcher_1.mergeKnownOrganizations
});
const continuityOrganization = (0, assistantOrganizationMatcher_1.normalizeOrganizationScopeValue)(continuitySnapshot.activeOrganization);
for (let index = (Array.isArray(items) ? items.length : 0) - 1; index >= 0; index -= 1) {
const item = Array.isArray(items) ? items[index] : null;
if (!item || typeof item !== "object" || item.role !== "assistant") {
continue;
}
const debug = item.debug;
if (!debug || typeof debug !== "object") {
continue;
}
const direct = (0, assistantOrganizationMatcher_1.normalizeOrganizationScopeValue)(debug.assistant_active_organization);
if (direct) {
return direct;
}
const selected = (0, assistantOrganizationMatcher_1.normalizeOrganizationScopeValue)(debug.living_chat_selected_organization);
if (selected) {
return selected;
}
if ((0, assistantContinuityPolicy_1.isGroundedAddressDebug)(debug)) {
const groundedOrganization = (0, assistantOrganizationMatcher_1.normalizeOrganizationScopeValue)((0, assistantContinuityPolicy_1.readAddressDebugOrganization)(debug));
if (groundedOrganization) {
return groundedOrganization;
}
}
}
return continuityOrganization;
return (0, assistantOrganizationMatcher_1.normalizeOrganizationScopeValue)(authority.activeOrganization);
}
function extractOrganizationFactsFromRows(rows) {
const names = [];
@@ -152,10 +152,18 @@ function buildAddressMemoryRecapReply(input) {
}
async function runAssistantLivingChatRuntime(input) {
const userMessage = String(input.userMessage ?? "");
const continuitySnapshot = (0, assistantContinuityPolicy_1.resolveAssistantContinuitySnapshot)({
const organizationAuthority = (0, assistantContinuityPolicy_1.resolveAssistantOrganizationAuthority)({
sessionItems: input.sessionItems,
toNonEmptyString: input.toNonEmptyString
sessionKnownOrganizations: Array.isArray(input.sessionScope.knownOrganizations)
? input.sessionScope.knownOrganizations
: [],
sessionSelectedOrganization: input.sessionScope.selectedOrganization,
sessionActiveOrganization: input.sessionScope.activeOrganization,
toNonEmptyString: input.toNonEmptyString,
normalizeOrganizationScopeValue: input.toNonEmptyString,
mergeKnownOrganizations: input.mergeKnownOrganizations
});
const continuitySnapshot = organizationAuthority.continuitySnapshot;
const dataScopeMetaQuery = input.hasAssistantDataScopeMetaQuestionSignal(userMessage);
const capabilityMetaQuery = input.shouldHandleAsAssistantCapabilityMetaQuery(userMessage);
const destructiveSignal = input.hasDestructiveDataActionSignal(userMessage);
@@ -169,13 +177,10 @@ async function runAssistantLivingChatRuntime(input) {
let livingChatGroundingGuardApplied = false;
let livingChatGroundingGuardReason = null;
let livingChatProactiveScopeOfferApplied = false;
const continuityActiveOrganization = input.toNonEmptyString(continuitySnapshot.activeOrganization);
let knownOrganizations = input.mergeKnownOrganizations([
...(Array.isArray(input.sessionScope.knownOrganizations) ? input.sessionScope.knownOrganizations : []),
continuityActiveOrganization
]);
let selectedOrganization = input.toNonEmptyString(input.sessionScope.selectedOrganization);
let activeOrganization = input.toNonEmptyString(input.sessionScope.activeOrganization) ?? continuityActiveOrganization;
const continuityActiveOrganization = organizationAuthority.continuityActiveOrganization;
let knownOrganizations = [...organizationAuthority.knownOrganizations];
let selectedOrganization = organizationAuthority.selectedOrganization;
let activeOrganization = organizationAuthority.activeOrganization;
const memoryRecapContext = (0, assistantMemoryRecapPolicy_1.resolveAssistantLivingChatMemoryContext)({
modeDecisionReason: input.modeDecision?.reason ?? null,
sessionItems: input.sessionItems
+14 -15
View File
@@ -72,26 +72,25 @@ function createAssistantRoutePolicy(deps) {
const sessionOrganizationScope = input?.sessionOrganizationScope && typeof input.sessionOrganizationScope === "object"
? input.sessionOrganizationScope
: null;
const continuitySnapshot = (0, assistantContinuityPolicy_1.resolveAssistantContinuitySnapshot)({
const organizationAuthority = (0, assistantContinuityPolicy_1.resolveAssistantOrganizationAuthority)({
sessionItems,
toNonEmptyString
sessionKnownOrganizations: Array.isArray(sessionOrganizationScope?.knownOrganizations)
? sessionOrganizationScope.knownOrganizations
: [],
sessionSelectedOrganization: sessionOrganizationScope?.selectedOrganization,
sessionActiveOrganization: sessionOrganizationScope?.activeOrganization,
lastOrganizationClarificationDebug: findLastOrganizationClarificationAddressDebug(sessionItems),
toNonEmptyString,
normalizeOrganizationScopeValue,
mergeKnownOrganizations
});
const continuityActiveOrganization = normalizeOrganizationScopeValue(sessionOrganizationScope?.activeOrganization) ??
normalizeOrganizationScopeValue(continuitySnapshot.activeOrganization);
const continuitySnapshot = organizationAuthority.continuitySnapshot;
const continuityActiveOrganization = organizationAuthority.continuityActiveOrganization;
const lastGroundedAddressDebug = findLastGroundedAddressAnswerDebug(sessionItems) ??
continuitySnapshot.lastGroundedAddressDebug;
const lastOrganizationClarificationDebug = findLastOrganizationClarificationAddressDebug(sessionItems);
const organizationClarificationCandidates = Array.isArray(lastOrganizationClarificationDebug?.organization_candidates)
? mergeKnownOrganizations([
...lastOrganizationClarificationDebug.organization_candidates,
...((Array.isArray(sessionOrganizationScope?.knownOrganizations)
? sessionOrganizationScope.knownOrganizations
: [])),
continuityActiveOrganization
])
: [];
const organizationClarificationSelectionFromScope = normalizeOrganizationScopeValue(sessionOrganizationScope?.selectedOrganization) ??
continuityActiveOrganization;
const organizationClarificationCandidates = organizationAuthority.organizationClarificationCandidates;
const organizationClarificationSelectionFromScope = organizationAuthority.organizationClarificationSelectionFromScope;
const organizationClarificationSelection = resolveOrganizationSelectionFromMessage(rawUserMessage, organizationClarificationCandidates) ??
resolveOrganizationSelectionFromMessage(repairedRawUserMessage, organizationClarificationCandidates) ??
resolveOrganizationSelectionFromMessage(effectiveAddressUserMessage, organizationClarificationCandidates) ??