ARCH: закрепить open-scope continuity для org clarification
This commit is contained in:
@@ -132,6 +132,40 @@ function comparisonNeedFor(action: string): string | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
function hasOpenScopeOneSidedValueTotalHint(rawUtterance: string, action: string): boolean {
|
||||
if (!rawUtterance) {
|
||||
return false;
|
||||
}
|
||||
if (action === "turnover") {
|
||||
return /(?:\bсколько\s+(?:мы\s+)?(?:получили|получено|входящих(?:\s+денег)?|поступлений|денег\s+пришло)\b|(?:сумма|объем)\s+(?:входящих|поступлений)|поступлений\s+за\b)/iu.test(
|
||||
rawUtterance
|
||||
);
|
||||
}
|
||||
if (action === "payout") {
|
||||
return /(?:\bсколько\s+(?:мы\s+)?(?:заплатили|выплатили|потратили|исходящих(?:\s+денег)?|платежей|списаний)\b|(?:сумма|объем)\s+(?:исходящих|платежей|списаний)|(?:платежей|списаний)\s+за\b)/iu.test(
|
||||
rawUtterance
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function hasOpenScopeOneSidedValueTotalHintUtf8Safe(rawUtterance: string, action: string): boolean {
|
||||
if (!rawUtterance) {
|
||||
return false;
|
||||
}
|
||||
if (action === "turnover") {
|
||||
return /(?:\u0441\u043a\u043e\u043b\u044c\u043a\u043e\s+(?:\u043c\u044b\s+)?(?:\u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438|\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e|\u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445(?:\s+\u0434\u0435\u043d\u0435\u0433)?|\u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0439|\u0434\u0435\u043d\u0435\u0433\s+\u043f\u0440\u0438\u0448\u043b\u043e)|(?:\u0441\u0443\u043c\u043c\u0430|\u043e\u0431\u044a\u0435\u043c)\s+(?:\u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445|\u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0439)|\u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0439\s+\u0437\u0430)/u.test(
|
||||
rawUtterance
|
||||
);
|
||||
}
|
||||
if (action === "payout") {
|
||||
return /(?:\u0441\u043a\u043e\u043b\u044c\u043a\u043e\s+(?:\u043c\u044b\s+)?(?:\u0437\u0430\u043f\u043b\u0430\u0442\u0438\u043b\u0438|\u0432\u044b\u043f\u043b\u0430\u0442\u0438\u043b\u0438|\u043f\u043e\u0442\u0440\u0430\u0442\u0438\u043b\u0438|\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445(?:\s+\u0434\u0435\u043d\u0435\u0433)?|\u043f\u043b\u0430\u0442\u0435\u0436\u0435\u0439|\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0439)|(?:\u0441\u0443\u043c\u043c\u0430|\u043e\u0431\u044a\u0435\u043c)\s+(?:\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445|\u043f\u043b\u0430\u0442\u0435\u0436\u0435\u0439|\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0439)|(?:\u043f\u043b\u0430\u0442\u0435\u0436\u0435\u0439|\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0439)\s+\u0437\u0430)/u.test(
|
||||
rawUtterance
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function supportsOrganizationScopedOpenTotal(action: string): boolean {
|
||||
return action === "turnover" || action === "payout";
|
||||
}
|
||||
@@ -142,6 +176,7 @@ function allowsOpenScopeWithoutSubject(input: {
|
||||
organizationScope: string | null;
|
||||
comparisonNeed: string | null;
|
||||
rankingNeed: string | null;
|
||||
oneSidedOpenScopeTotalHint: boolean;
|
||||
}): boolean {
|
||||
if (input.family !== "value_flow") {
|
||||
return false;
|
||||
@@ -149,7 +184,9 @@ function allowsOpenScopeWithoutSubject(input: {
|
||||
if (input.rankingNeed || input.comparisonNeed === "incoming_vs_outgoing") {
|
||||
return true;
|
||||
}
|
||||
return Boolean(input.organizationScope && supportsOrganizationScopedOpenTotal(input.action));
|
||||
return Boolean(
|
||||
supportsOrganizationScopedOpenTotal(input.action) && (input.organizationScope || input.oneSidedOpenScopeTotalHint)
|
||||
);
|
||||
}
|
||||
|
||||
function rankingNeedFromRawUtterance(value: string): string | null {
|
||||
@@ -303,6 +340,7 @@ export function buildAssistantMcpDiscoveryDataNeedGraph(
|
||||
const aggregationNeed = aggregationNeedFor(aggregationAxis);
|
||||
const comparisonNeed = comparisonNeedFor(action);
|
||||
const rankingNeed = rankingNeedFromRawUtterance(rawUtterance);
|
||||
const oneSidedOpenScopeTotalHint = hasOpenScopeOneSidedValueTotalHintUtf8Safe(rawUtterance, action);
|
||||
const openScopeWithoutSubject =
|
||||
subjectCandidates.length === 0 &&
|
||||
allowsOpenScopeWithoutSubject({
|
||||
@@ -310,13 +348,24 @@ export function buildAssistantMcpDiscoveryDataNeedGraph(
|
||||
action,
|
||||
organizationScope: explicitOrganizationScope,
|
||||
comparisonNeed,
|
||||
rankingNeed
|
||||
rankingNeed,
|
||||
oneSidedOpenScopeTotalHint
|
||||
});
|
||||
const clarificationGaps: string[] = [];
|
||||
if (unsupported === "metadata_lane_choice_clarification" || action === "resolve_next_lane") {
|
||||
pushUnique(clarificationGaps, "lane_family_choice");
|
||||
}
|
||||
if (subjectCandidates.length === 0 && businessFactFamily !== "schema_surface" && !openScopeWithoutSubject) {
|
||||
if (
|
||||
subjectCandidates.length === 0 &&
|
||||
businessFactFamily === "value_flow" &&
|
||||
openScopeWithoutSubject &&
|
||||
!rankingNeed &&
|
||||
!comparisonNeed &&
|
||||
oneSidedOpenScopeTotalHint &&
|
||||
!explicitOrganizationScope
|
||||
) {
|
||||
pushUnique(clarificationGaps, "organization");
|
||||
} else if (subjectCandidates.length === 0 && businessFactFamily !== "schema_surface" && !openScopeWithoutSubject) {
|
||||
pushUnique(clarificationGaps, "subject");
|
||||
}
|
||||
const timeScopeNeed = timeScopeNeedFor({
|
||||
@@ -353,6 +402,9 @@ export function buildAssistantMcpDiscoveryDataNeedGraph(
|
||||
if (openScopeWithoutSubject && !rankingNeed && !comparisonNeed) {
|
||||
pushReason(reasonCodes, "data_need_graph_open_scope_total_without_subject");
|
||||
}
|
||||
if (clarificationGaps.includes("organization")) {
|
||||
pushReason(reasonCodes, "data_need_graph_open_scope_total_needs_organization");
|
||||
}
|
||||
if (clarificationGaps.length > 0) {
|
||||
pushReason(reasonCodes, "data_need_graph_has_clarification_gaps");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user