Архитектура: убрать legacy active-organization callback из session-scope bootstrap и упростить organization authority path
This commit is contained in:
parent
59656a44a0
commit
8111586d8d
|
|
@ -357,6 +357,11 @@ Still open after the accepted phase12 replay:
|
||||||
- this matters because data-scope probing, organization selection bootstrap, and the broader continuity layer are now closer to one canonical organization merge order instead of keeping a separate debug-field collector inside the scope policy;
|
- this matters because data-scope probing, organization selection bootstrap, and the broader continuity layer are now closer to one canonical organization merge order instead of keeping a separate debug-field collector inside the scope policy;
|
||||||
- targeted data-scope and organization-scope tests now protect that known organizations still include assistant-side authority, grounded address context, and free-text fallback organizations;
|
- targeted data-scope and organization-scope tests now protect that known organizations still include assistant-side authority, grounded address context, and free-text fallback organizations;
|
||||||
- wide saved-session replay `address_truth_harness_phase12_wider_saved_session_pool_live_20260418_rerun8` remains accepted `20/20`, which is the critical proof that this data-scope convergence did not reopen the flagship saved-session path.
|
- wide saved-session replay `address_truth_harness_phase12_wider_saved_session_pool_live_20260418_rerun8` remains accepted `20/20`, which is the critical proof that this data-scope convergence did not reopen the flagship saved-session path.
|
||||||
|
- the next session-bootstrap pass now removes one more legacy callback seam from the organization scope adapter:
|
||||||
|
- `assistantOrganizationScopeRuntimeAdapter` no longer depends on a separate `findLastAssistantActiveOrganization(...)` callback even though it already computes shared continuity-backed organization authority internally;
|
||||||
|
- active organization bootstrap now flows through selected organization, navigation organization, and shared continuity authority in one place instead of keeping a second callback-shaped fallback branch beside the authority object;
|
||||||
|
- `assistantService.resolveSessionOrganizationScopeContext(...)` no longer passes that legacy callback into the runtime adapter, which reduces one more orchestration seam where old and new organization owners could drift;
|
||||||
|
- targeted organization-scope, data-scope, and route regressions remain green after the change, and wide saved-session replay `address_truth_harness_phase12_wider_saved_session_pool_live_20260418_rerun9` remains accepted `20/20`, which is the critical proof that this bootstrap convergence did not reopen the flagship continuity path.
|
||||||
|
|
||||||
## Next Execution Slice (2026-04-18)
|
## Next Execution Slice (2026-04-18)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,12 +42,10 @@ function resolveSessionOrganizationScopeContextRuntime(input) {
|
||||||
...input.extractKnownOrganizationsFromHistory(input.items)
|
...input.extractKnownOrganizationsFromHistory(input.items)
|
||||||
].map((value) => [String(value).toLowerCase(), value])).values());
|
].map((value) => [String(value).toLowerCase(), value])).values());
|
||||||
const selectedOrganization = input.resolveOrganizationSelectionFromMessage(input.userMessage, knownOrganizations);
|
const selectedOrganization = input.resolveOrganizationSelectionFromMessage(input.userMessage, knownOrganizations);
|
||||||
const lastActiveOrganization = input.findLastAssistantActiveOrganization(input.items);
|
|
||||||
const navigationActiveOrganization = resolveActiveOrganizationFromNavigationState(input.addressNavigationState, input.normalizeOrganizationScopeValue);
|
const navigationActiveOrganization = resolveActiveOrganizationFromNavigationState(input.addressNavigationState, input.normalizeOrganizationScopeValue);
|
||||||
const activeOrganization = selectedOrganization ??
|
const activeOrganization = selectedOrganization ??
|
||||||
navigationActiveOrganization ??
|
navigationActiveOrganization ??
|
||||||
continuityActiveOrganization ??
|
continuityActiveOrganization ??
|
||||||
input.normalizeOrganizationScopeValue(lastActiveOrganization) ??
|
|
||||||
(knownOrganizations.length === 1 ? knownOrganizations[0] : null);
|
(knownOrganizations.length === 1 ? knownOrganizations[0] : null);
|
||||||
return {
|
return {
|
||||||
knownOrganizations,
|
knownOrganizations,
|
||||||
|
|
|
||||||
|
|
@ -4539,74 +4539,6 @@ function extractKnownOrganizationsFromNavigationState(addressNavigationState) {
|
||||||
}
|
}
|
||||||
return mergeKnownOrganizations(collected);
|
return mergeKnownOrganizations(collected);
|
||||||
}
|
}
|
||||||
function extractKnownOrganizationsFromHistory(items, addressNavigationState = null) {
|
|
||||||
const collected = [];
|
|
||||||
const navigationOrganizations = extractKnownOrganizationsFromNavigationState(addressNavigationState);
|
|
||||||
if (navigationOrganizations.length > 0) {
|
|
||||||
collected.push(...navigationOrganizations);
|
|
||||||
}
|
|
||||||
for (let index = (Array.isArray(items) ? items.length : 0) - 1; index >= 0; index -= 1) {
|
|
||||||
const item = items[index];
|
|
||||||
if (!item || item.role !== "assistant") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const debug = item.debug && typeof item.debug === "object" ? item.debug : null;
|
|
||||||
if (debug) {
|
|
||||||
const directFromProbe = Array.isArray(debug.living_chat_data_scope_probe_organizations)
|
|
||||||
? debug.living_chat_data_scope_probe_organizations
|
|
||||||
: [];
|
|
||||||
const knownFromDebug = Array.isArray(debug.assistant_known_organizations)
|
|
||||||
? debug.assistant_known_organizations
|
|
||||||
: [];
|
|
||||||
const directFromCandidates = Array.isArray(debug.organization_candidates)
|
|
||||||
? debug.organization_candidates
|
|
||||||
: [];
|
|
||||||
const directFromResolved = [
|
|
||||||
normalizeOrganizationScopeValue(debug.assistant_active_organization),
|
|
||||||
normalizeOrganizationScopeValue(debug.living_chat_selected_organization),
|
|
||||||
normalizeOrganizationScopeValue(debug.extracted_filters?.organization),
|
|
||||||
normalizeOrganizationScopeValue(debug.address_root_frame_context?.organization)
|
|
||||||
].filter(Boolean);
|
|
||||||
if (directFromProbe.length > 0 || knownFromDebug.length > 0 || directFromCandidates.length > 0 || directFromResolved.length > 0) {
|
|
||||||
collected.push(...directFromProbe, ...knownFromDebug, ...directFromCandidates, ...directFromResolved);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const parsedFromText = parseOrganizationsFromDataScopeAssistantText(item.text);
|
|
||||||
if (parsedFromText.length > 0) {
|
|
||||||
collected.push(...parsedFromText);
|
|
||||||
}
|
|
||||||
if (collected.length >= 20) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mergeKnownOrganizations(collected);
|
|
||||||
}
|
|
||||||
function findLastAssistantActiveOrganization(items, addressNavigationState = null) {
|
|
||||||
const sessionContext = addressNavigationState && typeof addressNavigationState === "object"
|
|
||||||
? (addressNavigationState.session_context && typeof addressNavigationState.session_context === "object"
|
|
||||||
? addressNavigationState.session_context
|
|
||||||
: null)
|
|
||||||
: null;
|
|
||||||
const navigationOrganization = normalizeOrganizationScopeValue(sessionContext?.organization_scope);
|
|
||||||
if (navigationOrganization) {
|
|
||||||
return navigationOrganization;
|
|
||||||
}
|
|
||||||
for (let index = (Array.isArray(items) ? items.length : 0) - 1; index >= 0; index -= 1) {
|
|
||||||
const item = items[index];
|
|
||||||
if (!item || item.role !== "assistant" || !item.debug || typeof item.debug !== "object") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const direct = normalizeOrganizationScopeValue(item.debug.assistant_active_organization);
|
|
||||||
if (direct) {
|
|
||||||
return direct;
|
|
||||||
}
|
|
||||||
const selected = normalizeOrganizationScopeValue(item.debug.living_chat_selected_organization);
|
|
||||||
if (selected) {
|
|
||||||
return selected;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
function resolveOrganizationSelectionFromMessage(userMessage, knownOrganizations) {
|
function resolveOrganizationSelectionFromMessage(userMessage, knownOrganizations) {
|
||||||
const known = mergeKnownOrganizations(knownOrganizations);
|
const known = mergeKnownOrganizations(knownOrganizations);
|
||||||
if (!userMessage || known.length === 0) {
|
if (!userMessage || known.length === 0) {
|
||||||
|
|
@ -4643,7 +4575,6 @@ function resolveSessionOrganizationScopeContext(userMessage, items, addressNavig
|
||||||
addressNavigationState,
|
addressNavigationState,
|
||||||
extractKnownOrganizationsFromHistory: assistantDataScopePolicy.extractKnownOrganizationsFromHistory,
|
extractKnownOrganizationsFromHistory: assistantDataScopePolicy.extractKnownOrganizationsFromHistory,
|
||||||
resolveOrganizationSelectionFromMessage,
|
resolveOrganizationSelectionFromMessage,
|
||||||
findLastAssistantActiveOrganization: assistantDataScopePolicy.findLastAssistantActiveOrganization,
|
|
||||||
normalizeOrganizationScopeValue
|
normalizeOrganizationScopeValue
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ export interface ResolveSessionOrganizationScopeContextRuntimeInput<ItemType = u
|
||||||
addressNavigationState?: AddressNavigationState | null;
|
addressNavigationState?: AddressNavigationState | null;
|
||||||
extractKnownOrganizationsFromHistory: (items: ItemType[]) => string[];
|
extractKnownOrganizationsFromHistory: (items: ItemType[]) => string[];
|
||||||
resolveOrganizationSelectionFromMessage: (userMessage: string, knownOrganizations: string[]) => string | null;
|
resolveOrganizationSelectionFromMessage: (userMessage: string, knownOrganizations: string[]) => string | null;
|
||||||
findLastAssistantActiveOrganization: (items: ItemType[]) => string | null;
|
|
||||||
normalizeOrganizationScopeValue: (value: unknown) => string | null;
|
normalizeOrganizationScopeValue: (value: unknown) => string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,7 +81,6 @@ export function resolveSessionOrganizationScopeContextRuntime<ItemType = unknown
|
||||||
input.userMessage,
|
input.userMessage,
|
||||||
knownOrganizations
|
knownOrganizations
|
||||||
);
|
);
|
||||||
const lastActiveOrganization = input.findLastAssistantActiveOrganization(input.items);
|
|
||||||
const navigationActiveOrganization = resolveActiveOrganizationFromNavigationState(
|
const navigationActiveOrganization = resolveActiveOrganizationFromNavigationState(
|
||||||
input.addressNavigationState,
|
input.addressNavigationState,
|
||||||
input.normalizeOrganizationScopeValue
|
input.normalizeOrganizationScopeValue
|
||||||
|
|
@ -91,7 +89,6 @@ export function resolveSessionOrganizationScopeContextRuntime<ItemType = unknown
|
||||||
selectedOrganization ??
|
selectedOrganization ??
|
||||||
navigationActiveOrganization ??
|
navigationActiveOrganization ??
|
||||||
continuityActiveOrganization ??
|
continuityActiveOrganization ??
|
||||||
input.normalizeOrganizationScopeValue(lastActiveOrganization) ??
|
|
||||||
(knownOrganizations.length === 1 ? knownOrganizations[0] : null);
|
(knownOrganizations.length === 1 ? knownOrganizations[0] : null);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -4495,74 +4495,6 @@ function extractKnownOrganizationsFromNavigationState(addressNavigationState) {
|
||||||
}
|
}
|
||||||
return mergeKnownOrganizations(collected);
|
return mergeKnownOrganizations(collected);
|
||||||
}
|
}
|
||||||
function extractKnownOrganizationsFromHistory(items, addressNavigationState = null) {
|
|
||||||
const collected = [];
|
|
||||||
const navigationOrganizations = extractKnownOrganizationsFromNavigationState(addressNavigationState);
|
|
||||||
if (navigationOrganizations.length > 0) {
|
|
||||||
collected.push(...navigationOrganizations);
|
|
||||||
}
|
|
||||||
for (let index = (Array.isArray(items) ? items.length : 0) - 1; index >= 0; index -= 1) {
|
|
||||||
const item = items[index];
|
|
||||||
if (!item || item.role !== "assistant") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const debug = item.debug && typeof item.debug === "object" ? item.debug : null;
|
|
||||||
if (debug) {
|
|
||||||
const directFromProbe = Array.isArray(debug.living_chat_data_scope_probe_organizations)
|
|
||||||
? debug.living_chat_data_scope_probe_organizations
|
|
||||||
: [];
|
|
||||||
const knownFromDebug = Array.isArray(debug.assistant_known_organizations)
|
|
||||||
? debug.assistant_known_organizations
|
|
||||||
: [];
|
|
||||||
const directFromCandidates = Array.isArray(debug.organization_candidates)
|
|
||||||
? debug.organization_candidates
|
|
||||||
: [];
|
|
||||||
const directFromResolved = [
|
|
||||||
normalizeOrganizationScopeValue(debug.assistant_active_organization),
|
|
||||||
normalizeOrganizationScopeValue(debug.living_chat_selected_organization),
|
|
||||||
normalizeOrganizationScopeValue(debug.extracted_filters?.organization),
|
|
||||||
normalizeOrganizationScopeValue(debug.address_root_frame_context?.organization)
|
|
||||||
].filter(Boolean);
|
|
||||||
if (directFromProbe.length > 0 || knownFromDebug.length > 0 || directFromCandidates.length > 0 || directFromResolved.length > 0) {
|
|
||||||
collected.push(...directFromProbe, ...knownFromDebug, ...directFromCandidates, ...directFromResolved);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const parsedFromText = parseOrganizationsFromDataScopeAssistantText(item.text);
|
|
||||||
if (parsedFromText.length > 0) {
|
|
||||||
collected.push(...parsedFromText);
|
|
||||||
}
|
|
||||||
if (collected.length >= 20) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mergeKnownOrganizations(collected);
|
|
||||||
}
|
|
||||||
function findLastAssistantActiveOrganization(items, addressNavigationState = null) {
|
|
||||||
const sessionContext = addressNavigationState && typeof addressNavigationState === "object"
|
|
||||||
? (addressNavigationState.session_context && typeof addressNavigationState.session_context === "object"
|
|
||||||
? addressNavigationState.session_context
|
|
||||||
: null)
|
|
||||||
: null;
|
|
||||||
const navigationOrganization = normalizeOrganizationScopeValue(sessionContext?.organization_scope);
|
|
||||||
if (navigationOrganization) {
|
|
||||||
return navigationOrganization;
|
|
||||||
}
|
|
||||||
for (let index = (Array.isArray(items) ? items.length : 0) - 1; index >= 0; index -= 1) {
|
|
||||||
const item = items[index];
|
|
||||||
if (!item || item.role !== "assistant" || !item.debug || typeof item.debug !== "object") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const direct = normalizeOrganizationScopeValue(item.debug.assistant_active_organization);
|
|
||||||
if (direct) {
|
|
||||||
return direct;
|
|
||||||
}
|
|
||||||
const selected = normalizeOrganizationScopeValue(item.debug.living_chat_selected_organization);
|
|
||||||
if (selected) {
|
|
||||||
return selected;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
function resolveOrganizationSelectionFromMessage(userMessage, knownOrganizations) {
|
function resolveOrganizationSelectionFromMessage(userMessage, knownOrganizations) {
|
||||||
const known = mergeKnownOrganizations(knownOrganizations);
|
const known = mergeKnownOrganizations(knownOrganizations);
|
||||||
if (!userMessage || known.length === 0) {
|
if (!userMessage || known.length === 0) {
|
||||||
|
|
@ -4599,7 +4531,6 @@ function resolveSessionOrganizationScopeContext(userMessage, items, addressNavig
|
||||||
addressNavigationState,
|
addressNavigationState,
|
||||||
extractKnownOrganizationsFromHistory: assistantDataScopePolicy.extractKnownOrganizationsFromHistory,
|
extractKnownOrganizationsFromHistory: assistantDataScopePolicy.extractKnownOrganizationsFromHistory,
|
||||||
resolveOrganizationSelectionFromMessage,
|
resolveOrganizationSelectionFromMessage,
|
||||||
findLastAssistantActiveOrganization: assistantDataScopePolicy.findLastAssistantActiveOrganization,
|
|
||||||
normalizeOrganizationScopeValue
|
normalizeOrganizationScopeValue
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ describe("assistant organization scope runtime adapter", () => {
|
||||||
it("resolves selected organization from user message and promotes it to active scope", () => {
|
it("resolves selected organization from user message and promotes it to active scope", () => {
|
||||||
const extractKnownOrganizationsFromHistory = vi.fn(() => ["Org A", "Org B"]);
|
const extractKnownOrganizationsFromHistory = vi.fn(() => ["Org A", "Org B"]);
|
||||||
const resolveOrganizationSelectionFromMessage = vi.fn(() => "Org B");
|
const resolveOrganizationSelectionFromMessage = vi.fn(() => "Org B");
|
||||||
const findLastAssistantActiveOrganization = vi.fn(() => "Org A");
|
|
||||||
const normalizeOrganizationScopeValue = vi.fn((value: unknown) =>
|
const normalizeOrganizationScopeValue = vi.fn((value: unknown) =>
|
||||||
typeof value === "string" && value.trim() ? value.trim() : null
|
typeof value === "string" && value.trim() ? value.trim() : null
|
||||||
);
|
);
|
||||||
|
|
@ -18,7 +17,6 @@ describe("assistant organization scope runtime adapter", () => {
|
||||||
items: [] as any[],
|
items: [] as any[],
|
||||||
extractKnownOrganizationsFromHistory,
|
extractKnownOrganizationsFromHistory,
|
||||||
resolveOrganizationSelectionFromMessage,
|
resolveOrganizationSelectionFromMessage,
|
||||||
findLastAssistantActiveOrganization,
|
|
||||||
normalizeOrganizationScopeValue
|
normalizeOrganizationScopeValue
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -39,7 +37,6 @@ describe("assistant organization scope runtime adapter", () => {
|
||||||
items: [] as any[],
|
items: [] as any[],
|
||||||
extractKnownOrganizationsFromHistory: () => ["Org A"],
|
extractKnownOrganizationsFromHistory: () => ["Org A"],
|
||||||
resolveOrganizationSelectionFromMessage: () => null,
|
resolveOrganizationSelectionFromMessage: () => null,
|
||||||
findLastAssistantActiveOrganization: () => "Org A",
|
|
||||||
normalizeOrganizationScopeValue
|
normalizeOrganizationScopeValue
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -48,7 +45,6 @@ describe("assistant organization scope runtime adapter", () => {
|
||||||
selectedOrganization: null,
|
selectedOrganization: null,
|
||||||
activeOrganization: "Org A"
|
activeOrganization: "Org A"
|
||||||
});
|
});
|
||||||
expect(normalizeOrganizationScopeValue).toHaveBeenCalledWith("Org A");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("prefers organization scope from address navigation state when present", () => {
|
it("prefers organization scope from address navigation state when present", () => {
|
||||||
|
|
@ -79,7 +75,6 @@ describe("assistant organization scope runtime adapter", () => {
|
||||||
} as any,
|
} as any,
|
||||||
extractKnownOrganizationsFromHistory: () => ["Org A"],
|
extractKnownOrganizationsFromHistory: () => ["Org A"],
|
||||||
resolveOrganizationSelectionFromMessage: () => null,
|
resolveOrganizationSelectionFromMessage: () => null,
|
||||||
findLastAssistantActiveOrganization: () => "Org A",
|
|
||||||
normalizeOrganizationScopeValue
|
normalizeOrganizationScopeValue
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -108,7 +103,6 @@ describe("assistant organization scope runtime adapter", () => {
|
||||||
] as any[],
|
] as any[],
|
||||||
extractKnownOrganizationsFromHistory: () => [],
|
extractKnownOrganizationsFromHistory: () => [],
|
||||||
resolveOrganizationSelectionFromMessage: () => null,
|
resolveOrganizationSelectionFromMessage: () => null,
|
||||||
findLastAssistantActiveOrganization: () => null,
|
|
||||||
normalizeOrganizationScopeValue
|
normalizeOrganizationScopeValue
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue