133 lines
5.4 KiB
TypeScript
133 lines
5.4 KiB
TypeScript
import type { AddressNavigationState } from "../types/addressNavigation";
|
|
import { resolveAssistantOrganizationAuthority } from "./assistantContinuityPolicy";
|
|
|
|
export interface AssistantSessionOrganizationScopeContext {
|
|
knownOrganizations: string[];
|
|
selectedOrganization: string | null;
|
|
activeOrganization: string | null;
|
|
}
|
|
|
|
export interface ResolveSessionOrganizationScopeContextRuntimeInput<ItemType = unknown> {
|
|
userMessage: string;
|
|
items: ItemType[];
|
|
addressNavigationState?: AddressNavigationState | null;
|
|
extractKnownOrganizationsFromHistory: (items: ItemType[]) => string[];
|
|
resolveOrganizationSelectionFromMessage: (userMessage: string, knownOrganizations: string[]) => string | null;
|
|
normalizeOrganizationScopeValue: (value: unknown) => string | null;
|
|
}
|
|
|
|
export interface MergeFollowupContextWithOrganizationScopeRuntimeInput {
|
|
followupContext: unknown;
|
|
organization: unknown;
|
|
normalizeOrganizationScopeValue: (value: unknown) => string | null;
|
|
toNonEmptyString: (value: unknown) => string | null;
|
|
}
|
|
|
|
function extractOrganizationsFromNavigationState(
|
|
addressNavigationState: AddressNavigationState | null | undefined,
|
|
normalizeOrganizationScopeValue: ResolveSessionOrganizationScopeContextRuntimeInput["normalizeOrganizationScopeValue"]
|
|
): string[] {
|
|
if (!addressNavigationState || typeof addressNavigationState !== "object") {
|
|
return [];
|
|
}
|
|
const collected: string[] = [];
|
|
const directOrganization = normalizeOrganizationScopeValue(addressNavigationState.session_context?.organization_scope);
|
|
if (directOrganization) {
|
|
collected.push(directOrganization);
|
|
}
|
|
for (const resultSet of Array.isArray(addressNavigationState.result_sets) ? addressNavigationState.result_sets : []) {
|
|
const scopedOrganization = normalizeOrganizationScopeValue(resultSet?.filters?.organization);
|
|
if (scopedOrganization) {
|
|
collected.push(scopedOrganization);
|
|
}
|
|
}
|
|
return Array.from(new Map(collected.map((value) => [value.toLowerCase(), value])).values());
|
|
}
|
|
|
|
function resolveActiveOrganizationFromNavigationState(
|
|
addressNavigationState: AddressNavigationState | null | undefined,
|
|
normalizeOrganizationScopeValue: ResolveSessionOrganizationScopeContextRuntimeInput["normalizeOrganizationScopeValue"]
|
|
): string | null {
|
|
if (!addressNavigationState || typeof addressNavigationState !== "object") {
|
|
return null;
|
|
}
|
|
return normalizeOrganizationScopeValue(addressNavigationState.session_context?.organization_scope);
|
|
}
|
|
|
|
export function resolveSessionOrganizationScopeContextRuntime<ItemType = unknown>(
|
|
input: ResolveSessionOrganizationScopeContextRuntimeInput<ItemType>
|
|
): AssistantSessionOrganizationScopeContext {
|
|
const continuityAuthority = resolveAssistantOrganizationAuthority({
|
|
sessionItems: Array.isArray(input.items) ? input.items : [],
|
|
toNonEmptyString: input.normalizeOrganizationScopeValue,
|
|
normalizeOrganizationScopeValue: input.normalizeOrganizationScopeValue
|
|
});
|
|
const continuityKnownOrganizations = Array.isArray(continuityAuthority.knownOrganizations)
|
|
? continuityAuthority.knownOrganizations
|
|
: [];
|
|
const continuityActiveOrganization = input.normalizeOrganizationScopeValue(
|
|
continuityAuthority.activeOrganization
|
|
);
|
|
const knownOrganizations = Array.from(
|
|
new Map(
|
|
[
|
|
...continuityKnownOrganizations,
|
|
...extractOrganizationsFromNavigationState(input.addressNavigationState, input.normalizeOrganizationScopeValue),
|
|
...input.extractKnownOrganizationsFromHistory(input.items)
|
|
].map((value) => [String(value).toLowerCase(), value])
|
|
).values()
|
|
);
|
|
const selectedOrganization = input.resolveOrganizationSelectionFromMessage(
|
|
input.userMessage,
|
|
knownOrganizations
|
|
);
|
|
const navigationActiveOrganization = resolveActiveOrganizationFromNavigationState(
|
|
input.addressNavigationState,
|
|
input.normalizeOrganizationScopeValue
|
|
);
|
|
const activeOrganization =
|
|
selectedOrganization ??
|
|
navigationActiveOrganization ??
|
|
continuityActiveOrganization ??
|
|
(knownOrganizations.length === 1 ? knownOrganizations[0] : null);
|
|
|
|
return {
|
|
knownOrganizations,
|
|
selectedOrganization,
|
|
activeOrganization
|
|
};
|
|
}
|
|
|
|
export function mergeFollowupContextWithOrganizationScopeRuntime(
|
|
input: MergeFollowupContextWithOrganizationScopeRuntimeInput
|
|
): Record<string, unknown> | null {
|
|
const normalizedOrganization = input.normalizeOrganizationScopeValue(input.organization);
|
|
const hasBase = input.followupContext && typeof input.followupContext === "object";
|
|
const base = hasBase ? { ...(input.followupContext as Record<string, unknown>) } : {};
|
|
if (!normalizedOrganization) {
|
|
return hasBase ? base : null;
|
|
}
|
|
|
|
const previousFiltersRaw = base.previous_filters;
|
|
const previousFilters =
|
|
previousFiltersRaw && typeof previousFiltersRaw === "object"
|
|
? { ...(previousFiltersRaw as Record<string, unknown>) }
|
|
: {};
|
|
if (!input.toNonEmptyString(previousFilters.organization)) {
|
|
previousFilters.organization = normalizedOrganization;
|
|
}
|
|
base.previous_filters = previousFilters;
|
|
const rootFiltersRaw = base.root_filters;
|
|
const rootFilters =
|
|
rootFiltersRaw && typeof rootFiltersRaw === "object"
|
|
? { ...(rootFiltersRaw as Record<string, unknown>) }
|
|
: {};
|
|
if (!input.toNonEmptyString(rootFilters.organization)) {
|
|
rootFilters.organization = normalizedOrganization;
|
|
}
|
|
if (Object.keys(rootFilters).length > 0) {
|
|
base.root_filters = rootFilters;
|
|
}
|
|
return base;
|
|
}
|