ARCH: сохранять metadata ambiguity через clarification follow-up
This commit is contained in:
parent
40cf71d118
commit
007369a78a
|
|
@ -73,6 +73,10 @@ function isMovementPilot(pilot) {
|
||||||
function isMetadataPilot(pilot) {
|
function isMetadataPilot(pilot) {
|
||||||
return pilot.pilot_scope === "metadata_inspection_v1";
|
return pilot.pilot_scope === "metadata_inspection_v1";
|
||||||
}
|
}
|
||||||
|
function isMetadataLaneChoiceClarification(pilot) {
|
||||||
|
return (pilot.reason_codes.includes("planner_selected_metadata_lane_clarification_recipe") ||
|
||||||
|
pilot.dry_run.reason_codes.includes("planner_selected_metadata_lane_clarification_recipe"));
|
||||||
|
}
|
||||||
function metadataRouteFamilyLabelRu(routeFamily) {
|
function metadataRouteFamilyLabelRu(routeFamily) {
|
||||||
if (routeFamily === "document_evidence") {
|
if (routeFamily === "document_evidence") {
|
||||||
return "контур документов";
|
return "контур документов";
|
||||||
|
|
@ -127,6 +131,12 @@ function headlineFor(mode, pilot) {
|
||||||
if (mode === "bounded_inference_only") {
|
if (mode === "bounded_inference_only") {
|
||||||
return "Точный факт не подтвержден, но есть ограниченная оценка по найденной активности в 1С.";
|
return "Точный факт не подтвержден, но есть ограниченная оценка по найденной активности в 1С.";
|
||||||
}
|
}
|
||||||
|
if (mode === "needs_clarification" && isMetadataLaneChoiceClarification(pilot)) {
|
||||||
|
return "По подтвержденной metadata-поверхности видно несколько конкурирующих data-lane, и без явного выбора дальше идти нельзя.";
|
||||||
|
}
|
||||||
|
if (mode === "needs_clarification" && isMetadataLaneChoiceClarification(pilot)) {
|
||||||
|
return "Уточните, в какой контур идти дальше: по документам или по движениям/регистрам.";
|
||||||
|
}
|
||||||
if (mode === "needs_clarification") {
|
if (mode === "needs_clarification") {
|
||||||
return "Нужно уточнить контекст перед поиском в 1С.";
|
return "Нужно уточнить контекст перед поиском в 1С.";
|
||||||
}
|
}
|
||||||
|
|
@ -136,6 +146,9 @@ function headlineFor(mode, pilot) {
|
||||||
return "Я проверил доступный контур, но подтвержденного факта для ответа не получил.";
|
return "Я проверил доступный контур, но подтвержденного факта для ответа не получил.";
|
||||||
}
|
}
|
||||||
function nextStepFor(mode, pilot) {
|
function nextStepFor(mode, pilot) {
|
||||||
|
if (mode === "needs_clarification" && isMetadataLaneChoiceClarification(pilot)) {
|
||||||
|
return "Уточните, в какой контур идти дальше: по документам или по движениям/регистрам.";
|
||||||
|
}
|
||||||
if (mode === "needs_clarification") {
|
if (mode === "needs_clarification") {
|
||||||
return "Уточните контрагента, период или организацию, и я смогу выполнить проверку по 1С.";
|
return "Уточните контрагента, период или организацию, и я смогу выполнить проверку по 1С.";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,15 @@ function recipeFor(input) {
|
||||||
const axes = [];
|
const axes = [];
|
||||||
const requestedAggregationAxis = aggregationAxis(meaning);
|
const requestedAggregationAxis = aggregationAxis(meaning);
|
||||||
addScopeAxes(axes, meaning);
|
addScopeAxes(axes, meaning);
|
||||||
|
if (includesAny(combined, ["metadata_lane_choice_clarification", "resolve_next_lane"])) {
|
||||||
|
pushUnique(axes, "lane_family_choice");
|
||||||
|
return {
|
||||||
|
semanticDataNeed: "metadata lane clarification",
|
||||||
|
primitives: [],
|
||||||
|
axes,
|
||||||
|
reason: "planner_selected_metadata_lane_clarification_recipe"
|
||||||
|
};
|
||||||
|
}
|
||||||
if (includesAny(combined, ["turnover", "revenue", "payment", "payout", "value", "net", "netting", "balance", "cashflow"])) {
|
if (includesAny(combined, ["turnover", "revenue", "payment", "payout", "value", "net", "netting", "balance", "cashflow"])) {
|
||||||
pushUnique(axes, "aggregate_axis");
|
pushUnique(axes, "aggregate_axis");
|
||||||
pushUnique(axes, "amount");
|
pushUnique(axes, "amount");
|
||||||
|
|
|
||||||
|
|
@ -441,6 +441,17 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
|
||||||
!metadataDocumentHintSignal &&
|
!metadataDocumentHintSignal &&
|
||||||
!metadataMovementHintSignal &&
|
!metadataMovementHintSignal &&
|
||||||
hasMetadataDownstreamContinuationSignal(rawText));
|
hasMetadataDownstreamContinuationSignal(rawText));
|
||||||
|
const metadataAmbiguityLaneClarificationApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
|
||||||
|
followupSeed.metadataAmbiguityDetected &&
|
||||||
|
!metadataAmbiguityCollapsesToDocumentLane(followupSeed.metadataAmbiguityEntitySets) &&
|
||||||
|
!metadataAmbiguityCollapsesToMovementLane(followupSeed.metadataAmbiguityEntitySets) &&
|
||||||
|
followupSeed.counterparty &&
|
||||||
|
!rawLifecycleSignal &&
|
||||||
|
!rawValueFlowSignal &&
|
||||||
|
!rawMetadataSignal &&
|
||||||
|
!metadataDocumentHintSignal &&
|
||||||
|
!metadataMovementHintSignal &&
|
||||||
|
hasMetadataDownstreamContinuationSignal(rawText));
|
||||||
const metadataGroundedDocumentLaneApplicable = metadataGroundedDocumentFollowupApplicable ||
|
const metadataGroundedDocumentLaneApplicable = metadataGroundedDocumentFollowupApplicable ||
|
||||||
metadataAmbiguityResolvedDocumentFollowupApplicable ||
|
metadataAmbiguityResolvedDocumentFollowupApplicable ||
|
||||||
(metadataGroundedLaneContinuationApplicable && followupSeed.metadataRouteFamily === "document_evidence") ||
|
(metadataGroundedLaneContinuationApplicable && followupSeed.metadataRouteFamily === "document_evidence") ||
|
||||||
|
|
@ -450,29 +461,36 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
|
||||||
(metadataGroundedLaneContinuationApplicable && followupSeed.metadataRouteFamily === "movement_evidence") ||
|
(metadataGroundedLaneContinuationApplicable && followupSeed.metadataRouteFamily === "movement_evidence") ||
|
||||||
metadataAmbiguityCollapsedMovementLaneContinuationApplicable;
|
metadataAmbiguityCollapsedMovementLaneContinuationApplicable;
|
||||||
const effectiveMetadataFollowupSeedApplicable = metadataFollowupSeedApplicable &&
|
const effectiveMetadataFollowupSeedApplicable = metadataFollowupSeedApplicable &&
|
||||||
|
!metadataAmbiguityLaneClarificationApplicable &&
|
||||||
!metadataGroundedDocumentLaneApplicable &&
|
!metadataGroundedDocumentLaneApplicable &&
|
||||||
!metadataGroundedMovementLaneApplicable;
|
!metadataGroundedMovementLaneApplicable;
|
||||||
const seededDomain = metadataGroundedDocumentLaneApplicable
|
const seededDomain = metadataAmbiguityLaneClarificationApplicable
|
||||||
? "documents"
|
? "metadata"
|
||||||
: metadataGroundedMovementLaneApplicable
|
: metadataGroundedDocumentLaneApplicable
|
||||||
? "movements"
|
? "documents"
|
||||||
: followupDiscoverySeedApplicable || effectiveMetadataFollowupSeedApplicable
|
: metadataGroundedMovementLaneApplicable
|
||||||
? followupSeed.domain
|
? "movements"
|
||||||
: null;
|
: followupDiscoverySeedApplicable || effectiveMetadataFollowupSeedApplicable
|
||||||
const seededAction = metadataGroundedDocumentLaneApplicable
|
? followupSeed.domain
|
||||||
? "list_documents"
|
: null;
|
||||||
: metadataGroundedMovementLaneApplicable
|
const seededAction = metadataAmbiguityLaneClarificationApplicable
|
||||||
? "list_movements"
|
? "resolve_next_lane"
|
||||||
: followupDiscoverySeedApplicable || effectiveMetadataFollowupSeedApplicable
|
: metadataGroundedDocumentLaneApplicable
|
||||||
? followupSeed.action
|
? "list_documents"
|
||||||
: null;
|
: metadataGroundedMovementLaneApplicable
|
||||||
const seededUnsupported = metadataGroundedDocumentLaneApplicable
|
? "list_movements"
|
||||||
? "document_evidence"
|
: followupDiscoverySeedApplicable || effectiveMetadataFollowupSeedApplicable
|
||||||
: metadataGroundedMovementLaneApplicable
|
? followupSeed.action
|
||||||
? "movement_evidence"
|
: null;
|
||||||
: followupDiscoverySeedApplicable || effectiveMetadataFollowupSeedApplicable
|
const seededUnsupported = metadataAmbiguityLaneClarificationApplicable
|
||||||
? followupSeed.unsupported
|
? "metadata_lane_choice_clarification"
|
||||||
: null;
|
: metadataGroundedDocumentLaneApplicable
|
||||||
|
? "document_evidence"
|
||||||
|
: metadataGroundedMovementLaneApplicable
|
||||||
|
? "movement_evidence"
|
||||||
|
: followupDiscoverySeedApplicable || effectiveMetadataFollowupSeedApplicable
|
||||||
|
? followupSeed.unsupported
|
||||||
|
: null;
|
||||||
const lifecycleSignal = rawLifecycleSignal || seededDomain === "counterparty_lifecycle";
|
const lifecycleSignal = rawLifecycleSignal || seededDomain === "counterparty_lifecycle";
|
||||||
const bidirectionalValueFlowSignal = !lifecycleSignal &&
|
const bidirectionalValueFlowSignal = !lifecycleSignal &&
|
||||||
(rawBidirectionalValueFlowSignal || seededAction === "net_value_flow");
|
(rawBidirectionalValueFlowSignal || seededAction === "net_value_flow");
|
||||||
|
|
@ -482,14 +500,16 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
|
||||||
const payoutSignal = valueFlowSignal &&
|
const payoutSignal = valueFlowSignal &&
|
||||||
!bidirectionalValueFlowSignal &&
|
!bidirectionalValueFlowSignal &&
|
||||||
(rawPayoutSignal || seededAction === "payout");
|
(rawPayoutSignal || seededAction === "payout");
|
||||||
const semanticDataNeed = semanticNeedFor({
|
const semanticDataNeed = metadataAmbiguityLaneClarificationApplicable
|
||||||
domain: rawDomain ?? seededDomain,
|
? "metadata lane clarification"
|
||||||
action: rawAction ?? seededAction,
|
: semanticNeedFor({
|
||||||
unsupported: unsupported ?? seededUnsupported,
|
domain: rawDomain ?? seededDomain,
|
||||||
lifecycleSignal,
|
action: rawAction ?? seededAction,
|
||||||
valueFlowSignal,
|
unsupported: unsupported ?? seededUnsupported,
|
||||||
metadataSignal: rawMetadataSignal || effectiveMetadataFollowupSeedApplicable
|
lifecycleSignal,
|
||||||
});
|
valueFlowSignal,
|
||||||
|
metadataSignal: rawMetadataSignal || effectiveMetadataFollowupSeedApplicable
|
||||||
|
});
|
||||||
const entityCandidates = collectEntityCandidates(assistantTurnMeaning?.explicit_entity_candidates);
|
const entityCandidates = collectEntityCandidates(assistantTurnMeaning?.explicit_entity_candidates);
|
||||||
pushUnique(entityCandidates, predecomposeEntities.counterparty);
|
pushUnique(entityCandidates, predecomposeEntities.counterparty);
|
||||||
pushUnique(entityCandidates, followupSeed.counterparty);
|
pushUnique(entityCandidates, followupSeed.counterparty);
|
||||||
|
|
@ -533,6 +553,9 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
|
||||||
: rawAction ?? seededAction,
|
: rawAction ?? seededAction,
|
||||||
asked_aggregation_axis: monthlyAggregationSignal ? "month" : rawAggregationAxis,
|
asked_aggregation_axis: monthlyAggregationSignal ? "month" : rawAggregationAxis,
|
||||||
explicit_entity_candidates: entityCandidates,
|
explicit_entity_candidates: entityCandidates,
|
||||||
|
metadata_ambiguity_entity_sets: metadataAmbiguityLaneClarificationApplicable && followupSeed.metadataAmbiguityEntitySets.length > 0
|
||||||
|
? followupSeed.metadataAmbiguityEntitySets
|
||||||
|
: undefined,
|
||||||
explicit_organization_scope: explicitOrganizationScope,
|
explicit_organization_scope: explicitOrganizationScope,
|
||||||
explicit_date_scope: explicitDateScope,
|
explicit_date_scope: explicitDateScope,
|
||||||
unsupported_but_understood_family: unsupported ??
|
unsupported_but_understood_family: unsupported ??
|
||||||
|
|
@ -548,17 +571,20 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
|
||||||
? "movement_evidence"
|
? "movement_evidence"
|
||||||
: metadataGroundedDocumentLaneApplicable
|
: metadataGroundedDocumentLaneApplicable
|
||||||
? "document_evidence"
|
? "document_evidence"
|
||||||
: rawMetadataSignal || effectiveMetadataFollowupSeedApplicable
|
: metadataAmbiguityLaneClarificationApplicable
|
||||||
? "1c_metadata_surface"
|
? "metadata_lane_choice_clarification"
|
||||||
: followupDiscoverySeedApplicable
|
: rawMetadataSignal || effectiveMetadataFollowupSeedApplicable
|
||||||
? seededUnsupported
|
? "1c_metadata_surface"
|
||||||
: null),
|
: followupDiscoverySeedApplicable
|
||||||
|
? seededUnsupported
|
||||||
|
: null),
|
||||||
stale_replay_forbidden: Boolean(assistantTurnMeaning?.stale_replay_forbidden ||
|
stale_replay_forbidden: Boolean(assistantTurnMeaning?.stale_replay_forbidden ||
|
||||||
unsupported ||
|
unsupported ||
|
||||||
lifecycleSignal ||
|
lifecycleSignal ||
|
||||||
valueFlowSignal ||
|
valueFlowSignal ||
|
||||||
metadataGroundedMovementLaneApplicable ||
|
metadataGroundedMovementLaneApplicable ||
|
||||||
metadataGroundedDocumentLaneApplicable ||
|
metadataGroundedDocumentLaneApplicable ||
|
||||||
|
metadataAmbiguityLaneClarificationApplicable ||
|
||||||
rawMetadataSignal ||
|
rawMetadataSignal ||
|
||||||
effectiveMetadataFollowupSeedApplicable ||
|
effectiveMetadataFollowupSeedApplicable ||
|
||||||
followupDiscoverySeedApplicable)
|
followupDiscoverySeedApplicable)
|
||||||
|
|
@ -576,6 +602,9 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
|
||||||
if ((turnMeaning.explicit_entity_candidates?.length ?? 0) > 0) {
|
if ((turnMeaning.explicit_entity_candidates?.length ?? 0) > 0) {
|
||||||
cleanTurnMeaning.explicit_entity_candidates = turnMeaning.explicit_entity_candidates;
|
cleanTurnMeaning.explicit_entity_candidates = turnMeaning.explicit_entity_candidates;
|
||||||
}
|
}
|
||||||
|
if ((turnMeaning.metadata_ambiguity_entity_sets?.length ?? 0) > 0) {
|
||||||
|
cleanTurnMeaning.metadata_ambiguity_entity_sets = turnMeaning.metadata_ambiguity_entity_sets;
|
||||||
|
}
|
||||||
if (toNonEmptyString(turnMeaning.explicit_organization_scope)) {
|
if (toNonEmptyString(turnMeaning.explicit_organization_scope)) {
|
||||||
cleanTurnMeaning.explicit_organization_scope = turnMeaning.explicit_organization_scope;
|
cleanTurnMeaning.explicit_organization_scope = turnMeaning.explicit_organization_scope;
|
||||||
}
|
}
|
||||||
|
|
@ -597,13 +626,14 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
|
||||||
explicitIntentCandidate,
|
explicitIntentCandidate,
|
||||||
followupDiscoverySeedApplicable: followupDiscoverySeedApplicable ||
|
followupDiscoverySeedApplicable: followupDiscoverySeedApplicable ||
|
||||||
effectiveMetadataFollowupSeedApplicable ||
|
effectiveMetadataFollowupSeedApplicable ||
|
||||||
|
metadataAmbiguityLaneClarificationApplicable ||
|
||||||
metadataGroundedMovementLaneApplicable ||
|
metadataGroundedMovementLaneApplicable ||
|
||||||
metadataGroundedDocumentLaneApplicable
|
metadataGroundedDocumentLaneApplicable
|
||||||
});
|
});
|
||||||
const hasTurnMeaning = Object.keys(cleanTurnMeaning).length > 0;
|
const hasTurnMeaning = Object.keys(cleanTurnMeaning).length > 0;
|
||||||
const sourceSignal = assistantTurnMeaning
|
const sourceSignal = assistantTurnMeaning
|
||||||
? "assistant_turn_meaning"
|
? "assistant_turn_meaning"
|
||||||
: followupDiscoverySeedApplicable || effectiveMetadataFollowupSeedApplicable
|
: followupDiscoverySeedApplicable || effectiveMetadataFollowupSeedApplicable || metadataAmbiguityLaneClarificationApplicable
|
||||||
? "followup_context"
|
? "followup_context"
|
||||||
: metadataGroundedMovementLaneApplicable
|
: metadataGroundedMovementLaneApplicable
|
||||||
? "followup_context"
|
? "followup_context"
|
||||||
|
|
@ -663,6 +693,9 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
|
||||||
if (metadataAmbiguityCollapsedMovementLaneContinuationApplicable) {
|
if (metadataAmbiguityCollapsedMovementLaneContinuationApplicable) {
|
||||||
pushReason(reasonCodes, "mcp_discovery_metadata_ambiguity_collapsed_to_movement_lane");
|
pushReason(reasonCodes, "mcp_discovery_metadata_ambiguity_collapsed_to_movement_lane");
|
||||||
}
|
}
|
||||||
|
if (metadataAmbiguityLaneClarificationApplicable) {
|
||||||
|
pushReason(reasonCodes, "mcp_discovery_metadata_ambiguity_requires_lane_choice");
|
||||||
|
}
|
||||||
if (unsupported) {
|
if (unsupported) {
|
||||||
pushReason(reasonCodes, "mcp_discovery_unsupported_but_understood_turn");
|
pushReason(reasonCodes, "mcp_discovery_unsupported_but_understood_turn");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,17 @@ function readAssistantMcpDiscoveryTurnMeaning(
|
||||||
return toRecordObject(turnInput?.turn_meaning_ref);
|
return toRecordObject(turnInput?.turn_meaning_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readAssistantMcpDiscoveryTurnMeaningMetadataAmbiguityEntitySets(
|
||||||
|
debug: Record<string, unknown> | null,
|
||||||
|
toNonEmptyString: (value: unknown) => string | null = fallbackToNonEmptyString
|
||||||
|
): string[] {
|
||||||
|
const values = readAssistantMcpDiscoveryTurnMeaning(debug)?.metadata_ambiguity_entity_sets;
|
||||||
|
if (!Array.isArray(values)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return values.map((item) => toNonEmptyString(item)).filter((item): item is string => Boolean(item));
|
||||||
|
}
|
||||||
|
|
||||||
function readAssistantMcpDiscoveryActionFamily(
|
function readAssistantMcpDiscoveryActionFamily(
|
||||||
debug: Record<string, unknown> | null,
|
debug: Record<string, unknown> | null,
|
||||||
toNonEmptyString: (value: unknown) => string | null = fallbackToNonEmptyString
|
toNonEmptyString: (value: unknown) => string | null = fallbackToNonEmptyString
|
||||||
|
|
@ -189,7 +200,10 @@ export function readAssistantMcpDiscoveryMetadataSelectedEntitySet(
|
||||||
export function readAssistantMcpDiscoveryMetadataAmbiguityDetected(
|
export function readAssistantMcpDiscoveryMetadataAmbiguityDetected(
|
||||||
debug: Record<string, unknown> | null
|
debug: Record<string, unknown> | null
|
||||||
): boolean {
|
): boolean {
|
||||||
return readAssistantMcpDiscoveryDerivedMetadataSurface(debug)?.ambiguity_detected === true;
|
return (
|
||||||
|
readAssistantMcpDiscoveryDerivedMetadataSurface(debug)?.ambiguity_detected === true ||
|
||||||
|
readAssistantMcpDiscoveryTurnMeaningMetadataAmbiguityEntitySets(debug).length > 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function readAssistantMcpDiscoveryMetadataAmbiguityEntitySets(
|
export function readAssistantMcpDiscoveryMetadataAmbiguityEntitySets(
|
||||||
|
|
@ -197,10 +211,10 @@ export function readAssistantMcpDiscoveryMetadataAmbiguityEntitySets(
|
||||||
toNonEmptyString: (value: unknown) => string | null = fallbackToNonEmptyString
|
toNonEmptyString: (value: unknown) => string | null = fallbackToNonEmptyString
|
||||||
): string[] {
|
): string[] {
|
||||||
const values = readAssistantMcpDiscoveryDerivedMetadataSurface(debug)?.ambiguity_entity_sets;
|
const values = readAssistantMcpDiscoveryDerivedMetadataSurface(debug)?.ambiguity_entity_sets;
|
||||||
if (!Array.isArray(values)) {
|
if (Array.isArray(values)) {
|
||||||
return [];
|
return values.map((item) => toNonEmptyString(item)).filter((item): item is string => Boolean(item));
|
||||||
}
|
}
|
||||||
return values.map((item) => toNonEmptyString(item)).filter((item): item is string => Boolean(item));
|
return readAssistantMcpDiscoveryTurnMeaningMetadataAmbiguityEntitySets(debug, toNonEmptyString);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapAssistantMcpDiscoveryPilotScopeToAddressIntent(
|
function mapAssistantMcpDiscoveryPilotScopeToAddressIntent(
|
||||||
|
|
|
||||||
|
|
@ -1562,6 +1562,9 @@ function buildEmptyEvidence(
|
||||||
}
|
}
|
||||||
|
|
||||||
function pilotScopeForPlanner(planner: AssistantMcpDiscoveryPlannerContract): AssistantMcpDiscoveryPilotScope {
|
function pilotScopeForPlanner(planner: AssistantMcpDiscoveryPlannerContract): AssistantMcpDiscoveryPilotScope {
|
||||||
|
if (planner.reason_codes.includes("planner_selected_metadata_lane_clarification_recipe")) {
|
||||||
|
return "metadata_inspection_v1";
|
||||||
|
}
|
||||||
if (isMetadataPilotEligible(planner)) {
|
if (isMetadataPilotEligible(planner)) {
|
||||||
return "metadata_inspection_v1";
|
return "metadata_inspection_v1";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ export interface AssistantMcpDiscoveryTurnMeaningRef {
|
||||||
asked_action_family?: string | null;
|
asked_action_family?: string | null;
|
||||||
asked_aggregation_axis?: string | null;
|
asked_aggregation_axis?: string | null;
|
||||||
explicit_entity_candidates?: string[];
|
explicit_entity_candidates?: string[];
|
||||||
|
metadata_ambiguity_entity_sets?: string[];
|
||||||
explicit_organization_scope?: string | null;
|
explicit_organization_scope?: string | null;
|
||||||
explicit_date_scope?: string | null;
|
explicit_date_scope?: string | null;
|
||||||
meaning_confidence?: number | null;
|
meaning_confidence?: number | null;
|
||||||
|
|
@ -170,6 +171,7 @@ function normalizeTurnMeaning(
|
||||||
const dateScope = toNonEmptyString(value.explicit_date_scope);
|
const dateScope = toNonEmptyString(value.explicit_date_scope);
|
||||||
const unsupported = toNonEmptyString(value.unsupported_but_understood_family);
|
const unsupported = toNonEmptyString(value.unsupported_but_understood_family);
|
||||||
const entities = toStringList(value.explicit_entity_candidates);
|
const entities = toStringList(value.explicit_entity_candidates);
|
||||||
|
const metadataAmbiguityEntitySets = toStringList(value.metadata_ambiguity_entity_sets);
|
||||||
if (domain) {
|
if (domain) {
|
||||||
result.asked_domain_family = domain;
|
result.asked_domain_family = domain;
|
||||||
}
|
}
|
||||||
|
|
@ -182,6 +184,9 @@ function normalizeTurnMeaning(
|
||||||
if (entities.length > 0) {
|
if (entities.length > 0) {
|
||||||
result.explicit_entity_candidates = entities;
|
result.explicit_entity_candidates = entities;
|
||||||
}
|
}
|
||||||
|
if (metadataAmbiguityEntitySets.length > 0) {
|
||||||
|
result.metadata_ambiguity_entity_sets = metadataAmbiguityEntitySets;
|
||||||
|
}
|
||||||
if (organization) {
|
if (organization) {
|
||||||
result.explicit_organization_scope = organization;
|
result.explicit_organization_scope = organization;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -725,6 +725,10 @@ export function buildAssistantMcpDiscoveryTurnInput(
|
||||||
: rawAction ?? seededAction,
|
: rawAction ?? seededAction,
|
||||||
asked_aggregation_axis: monthlyAggregationSignal ? "month" : rawAggregationAxis,
|
asked_aggregation_axis: monthlyAggregationSignal ? "month" : rawAggregationAxis,
|
||||||
explicit_entity_candidates: entityCandidates,
|
explicit_entity_candidates: entityCandidates,
|
||||||
|
metadata_ambiguity_entity_sets:
|
||||||
|
metadataAmbiguityLaneClarificationApplicable && followupSeed.metadataAmbiguityEntitySets.length > 0
|
||||||
|
? followupSeed.metadataAmbiguityEntitySets
|
||||||
|
: undefined,
|
||||||
explicit_organization_scope: explicitOrganizationScope,
|
explicit_organization_scope: explicitOrganizationScope,
|
||||||
explicit_date_scope: explicitDateScope,
|
explicit_date_scope: explicitDateScope,
|
||||||
unsupported_but_understood_family:
|
unsupported_but_understood_family:
|
||||||
|
|
@ -775,6 +779,9 @@ export function buildAssistantMcpDiscoveryTurnInput(
|
||||||
if ((turnMeaning.explicit_entity_candidates?.length ?? 0) > 0) {
|
if ((turnMeaning.explicit_entity_candidates?.length ?? 0) > 0) {
|
||||||
cleanTurnMeaning.explicit_entity_candidates = turnMeaning.explicit_entity_candidates;
|
cleanTurnMeaning.explicit_entity_candidates = turnMeaning.explicit_entity_candidates;
|
||||||
}
|
}
|
||||||
|
if ((turnMeaning.metadata_ambiguity_entity_sets?.length ?? 0) > 0) {
|
||||||
|
cleanTurnMeaning.metadata_ambiguity_entity_sets = turnMeaning.metadata_ambiguity_entity_sets;
|
||||||
|
}
|
||||||
if (toNonEmptyString(turnMeaning.explicit_organization_scope)) {
|
if (toNonEmptyString(turnMeaning.explicit_organization_scope)) {
|
||||||
cleanTurnMeaning.explicit_organization_scope = turnMeaning.explicit_organization_scope;
|
cleanTurnMeaning.explicit_organization_scope = turnMeaning.explicit_organization_scope;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -595,6 +595,7 @@ describe("assistant MCP discovery turn input adapter", () => {
|
||||||
asked_domain_family: "metadata",
|
asked_domain_family: "metadata",
|
||||||
asked_action_family: "resolve_next_lane",
|
asked_action_family: "resolve_next_lane",
|
||||||
explicit_entity_candidates: ["SVK"],
|
explicit_entity_candidates: ["SVK"],
|
||||||
|
metadata_ambiguity_entity_sets: ["Документ", "РегистрНакопления"],
|
||||||
explicit_date_scope: "2020",
|
explicit_date_scope: "2020",
|
||||||
unsupported_but_understood_family: "metadata_lane_choice_clarification",
|
unsupported_but_understood_family: "metadata_lane_choice_clarification",
|
||||||
stale_replay_forbidden: true
|
stale_replay_forbidden: true
|
||||||
|
|
|
||||||
|
|
@ -1227,6 +1227,61 @@ describe("assistantTransitionPolicy", () => {
|
||||||
"РегистрНакопления"
|
"РегистрНакопления"
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
it("preserves metadata ambiguity choice sets through a clarification assistant turn", () => {
|
||||||
|
const policy = buildPolicy({
|
||||||
|
findLastAddressAssistantItem: () => ({
|
||||||
|
text: "уточните: по документам или по движениям?",
|
||||||
|
debug: {
|
||||||
|
execution_lane: "living_chat",
|
||||||
|
mcp_discovery_response_applied: true,
|
||||||
|
assistant_mcp_discovery_entry_point_v1: {
|
||||||
|
schema_version: "assistant_mcp_discovery_runtime_entry_point_v1",
|
||||||
|
entry_status: "bridge_executed",
|
||||||
|
turn_input: {
|
||||||
|
turn_meaning_ref: {
|
||||||
|
asked_domain_family: "metadata",
|
||||||
|
asked_action_family: "resolve_next_lane",
|
||||||
|
explicit_entity_candidates: ["SVK"],
|
||||||
|
metadata_ambiguity_entity_sets: ["Документ", "РегистрНакопления"],
|
||||||
|
explicit_date_scope: "2020",
|
||||||
|
unsupported_but_understood_family: "metadata_lane_choice_clarification"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bridge: {
|
||||||
|
bridge_status: "needs_clarification",
|
||||||
|
business_fact_answer_allowed: false,
|
||||||
|
pilot: {
|
||||||
|
pilot_scope: "metadata_inspection_v1"
|
||||||
|
},
|
||||||
|
answer_draft: {
|
||||||
|
answer_mode: "needs_clarification"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
hasAddressFollowupContextSignal: () => true,
|
||||||
|
hasReferentialPointer: () => false,
|
||||||
|
resolveAddressIntent: () => ({ intent: "unknown" }),
|
||||||
|
resolveAddressIntentFamily: () => null,
|
||||||
|
resolveAssistantTurnMeaning: () => null
|
||||||
|
});
|
||||||
|
|
||||||
|
const carryover = policy.resolveAddressFollowupCarryoverContext(
|
||||||
|
"по движениям",
|
||||||
|
[{ kind: "assistant", text: "уточните: по документам или по движениям?" }],
|
||||||
|
"по движениям",
|
||||||
|
{ predecomposeContract: { intent: "unknown" } },
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(carryover?.followupContext?.previous_discovery_pilot_scope).toBe("metadata_inspection_v1");
|
||||||
|
expect(carryover?.followupContext?.previous_discovery_metadata_ambiguity_detected).toBe(true);
|
||||||
|
expect(carryover?.followupContext?.previous_discovery_metadata_ambiguity_entity_sets).toEqual([
|
||||||
|
"Документ",
|
||||||
|
"РегистрНакопления"
|
||||||
|
]);
|
||||||
|
});
|
||||||
it("switches to VAT tax-period intent while preserving carried period filters", () => {
|
it("switches to VAT tax-period intent while preserving carried period filters", () => {
|
||||||
const policy = buildPolicy({
|
const policy = buildPolicy({
|
||||||
findLastAddressAssistantItem: () => ({
|
findLastAddressAssistantItem: () => ({
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue