Согласовать MCP planner с value-flow цепочками
This commit is contained in:
@@ -766,11 +766,7 @@ export function searchAssistantMcpCatalogPrimitivesByDecompositionCandidates(
|
||||
}
|
||||
|
||||
for (const contract of PRIMITIVE_CONTRACTS) {
|
||||
if (
|
||||
contract.primitive_id === "aggregate_by_axis" &&
|
||||
normalizedCandidate === "aggregate_by_month" &&
|
||||
!allowAggregateByAxis
|
||||
) {
|
||||
if (contract.primitive_id === "aggregate_by_axis" && !allowAggregateByAxis) {
|
||||
continue;
|
||||
}
|
||||
if (!contract.decomposition_hints.includes(normalizedCandidate)) {
|
||||
|
||||
@@ -326,6 +326,13 @@ function dateScopeToFilters(dateScope: string | null): Pick<AddressFilterSet, "p
|
||||
period_to: `${yearMatch[1]}-12-31`
|
||||
};
|
||||
}
|
||||
const rangeMatch = dateScope.match(/^(\d{4}-\d{2}-\d{2})\.\.(\d{4}-\d{2}-\d{2})$/);
|
||||
if (rangeMatch) {
|
||||
return {
|
||||
period_from: rangeMatch[1],
|
||||
period_to: rangeMatch[2]
|
||||
};
|
||||
}
|
||||
const dateMatch = dateScope.match(/^(\d{4})-(\d{2})-(\d{2})/);
|
||||
if (dateMatch) {
|
||||
const date = `${dateMatch[1]}-${dateMatch[2]}-${dateMatch[3]}`;
|
||||
|
||||
@@ -386,6 +386,34 @@ function preferredPrimitiveFromExplicitDataNeedGraph(
|
||||
return null;
|
||||
}
|
||||
|
||||
function catalogTemplateIdFromChainId(
|
||||
chainId: AssistantMcpDiscoveryChainId
|
||||
): AssistantMcpCatalogChainTemplateId | null {
|
||||
if (chainId === "metadata_lane_clarification") {
|
||||
return null;
|
||||
}
|
||||
return chainId;
|
||||
}
|
||||
|
||||
function promoteConfirmedMetadataSurfaceChainTemplate(input: {
|
||||
matches: AssistantMcpCatalogChainTemplateId[];
|
||||
metadataSurface?: AssistantMcpDiscoveryMetadataSurfaceRef | null;
|
||||
selectedChainId?: AssistantMcpCatalogChainTemplateId | null;
|
||||
}): AssistantMcpCatalogChainTemplateId[] {
|
||||
const surfaceRouteFamily = routeFamilyFromMetadataSurfaceRef(input.metadataSurface);
|
||||
const selectedChainId = input.selectedChainId ?? null;
|
||||
if (!surfaceRouteFamily || !selectedChainId || selectedChainId !== surfaceRouteFamily) {
|
||||
return input.matches;
|
||||
}
|
||||
if (input.matches[0] === selectedChainId || !input.matches.includes(selectedChainId)) {
|
||||
return input.matches;
|
||||
}
|
||||
return [
|
||||
selectedChainId,
|
||||
...input.matches.filter((chainId) => chainId !== selectedChainId)
|
||||
];
|
||||
}
|
||||
|
||||
function hasCarriedMetadataSurfaceScoringEvidence(
|
||||
surface: AssistantMcpDiscoveryMetadataSurfaceRef | null | undefined
|
||||
): boolean {
|
||||
@@ -456,6 +484,7 @@ function selectPrimitivesFromGraphAndCatalog(input: {
|
||||
metadataSurface?: AssistantMcpDiscoveryMetadataSurfaceRef | null;
|
||||
actionFamily?: string | null;
|
||||
allowAggregateByAxis?: boolean;
|
||||
selectedChainId?: AssistantMcpCatalogChainTemplateId | null;
|
||||
}): { primitives: AssistantMcpDiscoveryPrimitive[]; reasonCodes: string[] } {
|
||||
const reasonCodes: string[] = [];
|
||||
const decompositionCandidates = input.dataNeedGraph?.decomposition_candidates ?? [];
|
||||
@@ -500,7 +529,7 @@ function selectPrimitivesFromGraphAndCatalog(input: {
|
||||
reasonCodes.push("planner_selected_catalog_primitives_from_fact_axis_search");
|
||||
}
|
||||
|
||||
const chainTemplateMatches = input.dataNeedGraph
|
||||
const rawChainTemplateMatches = input.dataNeedGraph
|
||||
? searchAssistantMcpCatalogChainTemplatesByFactAxis({
|
||||
business_fact_family: input.dataNeedGraph.business_fact_family,
|
||||
action_family: input.actionFamily ?? input.dataNeedGraph.action_family,
|
||||
@@ -510,8 +539,16 @@ function selectPrimitivesFromGraphAndCatalog(input: {
|
||||
aggregation_need: input.dataNeedGraph.aggregation_need
|
||||
})
|
||||
: [];
|
||||
const chainTemplateMatches = promoteConfirmedMetadataSurfaceChainTemplate({
|
||||
matches: rawChainTemplateMatches,
|
||||
metadataSurface: input.metadataSurface,
|
||||
selectedChainId: input.selectedChainId
|
||||
});
|
||||
if (chainTemplateMatches.length > 0) {
|
||||
reasonCodes.push("planner_scored_catalog_chain_templates_from_fact_axis");
|
||||
if (rawChainTemplateMatches[0] !== chainTemplateMatches[0]) {
|
||||
reasonCodes.push("planner_catalog_chain_template_promoted_by_confirmed_metadata_surface");
|
||||
}
|
||||
reasonCodes.push(`planner_catalog_chain_template_search_top_${chainTemplateMatches[0]}`);
|
||||
}
|
||||
|
||||
@@ -565,8 +602,10 @@ function budgetOverrideFor(input: AssistantMcpDiscoveryPlannerInput, recipe: Pla
|
||||
const meaning = input.turnMeaning ?? null;
|
||||
const requestedAggregationAxis = aggregationAxis(meaning);
|
||||
const isValueFlowRecipe =
|
||||
recipe.semanticDataNeed === "counterparty value-flow evidence" &&
|
||||
recipe.primitives.includes("query_movements");
|
||||
recipe.primitives.includes("query_movements") &&
|
||||
(recipe.semanticDataNeed === "counterparty value-flow evidence" ||
|
||||
recipe.semanticDataNeed === "bidirectional value-flow comparison evidence" ||
|
||||
recipe.semanticDataNeed === "ranked value-flow evidence");
|
||||
if (!isValueFlowRecipe) {
|
||||
return {};
|
||||
}
|
||||
@@ -586,7 +625,7 @@ function catalogChainTemplateMatchesForContract(
|
||||
if (!dataNeedGraph) {
|
||||
return [];
|
||||
}
|
||||
return searchAssistantMcpCatalogChainTemplatesByFactAxis({
|
||||
const matches = searchAssistantMcpCatalogChainTemplatesByFactAxis({
|
||||
business_fact_family: dataNeedGraph.business_fact_family,
|
||||
action_family: toNonEmptyString(input.turnMeaning?.asked_action_family) ?? dataNeedGraph.action_family,
|
||||
required_axes: recipe.axes,
|
||||
@@ -594,6 +633,11 @@ function catalogChainTemplateMatchesForContract(
|
||||
ranking_need: dataNeedGraph.ranking_need,
|
||||
aggregation_need: dataNeedGraph.aggregation_need
|
||||
});
|
||||
return promoteConfirmedMetadataSurfaceChainTemplate({
|
||||
matches,
|
||||
metadataSurface: input.metadataSurface,
|
||||
selectedChainId: catalogTemplateIdFromChainId(recipe.chainId)
|
||||
});
|
||||
}
|
||||
|
||||
function catalogChainTemplateAlignmentForContract(
|
||||
@@ -700,7 +744,8 @@ function recipeFor(input: AssistantMcpDiscoveryPlannerInput): PlannerRecipe {
|
||||
fallbackPrimitives: template.fallback_primitives,
|
||||
requiredAxes: axes,
|
||||
metadataSurface: input.metadataSurface,
|
||||
actionFamily: action
|
||||
actionFamily: action,
|
||||
selectedChainId: "document_evidence"
|
||||
});
|
||||
return recipeFromCatalogChainTemplate({
|
||||
chainId: "document_evidence",
|
||||
@@ -725,7 +770,8 @@ function recipeFor(input: AssistantMcpDiscoveryPlannerInput): PlannerRecipe {
|
||||
fallbackPrimitives: template.fallback_primitives,
|
||||
requiredAxes: axes,
|
||||
metadataSurface: input.metadataSurface,
|
||||
actionFamily: action
|
||||
actionFamily: action,
|
||||
selectedChainId: "movement_evidence"
|
||||
});
|
||||
return recipeFromCatalogChainTemplate({
|
||||
chainId: "movement_evidence",
|
||||
@@ -750,7 +796,8 @@ function recipeFor(input: AssistantMcpDiscoveryPlannerInput): PlannerRecipe {
|
||||
fallbackPrimitives: template.fallback_primitives,
|
||||
requiredAxes: axes,
|
||||
metadataSurface: input.metadataSurface,
|
||||
actionFamily: action
|
||||
actionFamily: action,
|
||||
selectedChainId: "catalog_drilldown"
|
||||
});
|
||||
return recipeFromCatalogChainTemplate({
|
||||
chainId: "catalog_drilldown",
|
||||
|
||||
@@ -298,6 +298,32 @@ function readStringArray(value: unknown): string[] {
|
||||
: [];
|
||||
}
|
||||
|
||||
function hasValueFlowActionConflictWithDiscoveryTurnMeaning(
|
||||
input: ApplyAssistantMcpDiscoveryResponsePolicyInput,
|
||||
entryPoint: AssistantMcpDiscoveryRuntimeEntryPointContract | null
|
||||
): boolean {
|
||||
if (!isDiscoveryReadyAddressCandidate(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (!hasEffectivelyFactualAddressReply(input)) {
|
||||
return false;
|
||||
}
|
||||
const turnMeaning = readDiscoveryTurnMeaning(entryPoint);
|
||||
const askedDomain = toNonEmptyString(turnMeaning?.asked_domain_family);
|
||||
const askedAction = toNonEmptyString(turnMeaning?.asked_action_family);
|
||||
if (askedDomain !== "counterparty_value") {
|
||||
return false;
|
||||
}
|
||||
const detectedIntent = toNonEmptyString(input.addressRuntimeMeta?.detected_intent);
|
||||
if (askedAction === "payout") {
|
||||
return detectedIntent !== "supplier_payouts_profile";
|
||||
}
|
||||
if (askedAction === "net_value_flow") {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function hasExactMatchedFactualAddressReply(
|
||||
input: ApplyAssistantMcpDiscoveryResponsePolicyInput,
|
||||
entryPoint: AssistantMcpDiscoveryRuntimeEntryPointContract | null
|
||||
@@ -311,6 +337,9 @@ function hasExactMatchedFactualAddressReply(
|
||||
if (hasOpenScopeValueFlowDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasValueFlowActionConflictWithDiscoveryTurnMeaning(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
const mcpCallStatus = toNonEmptyString(input.addressRuntimeMeta?.mcp_call_status);
|
||||
const truthMode = toNonEmptyString(input.addressRuntimeMeta?.truth_mode);
|
||||
const selectedRecipe = toNonEmptyString(input.addressRuntimeMeta?.selected_recipe);
|
||||
@@ -522,6 +551,10 @@ export function applyAssistantMcpDiscoveryResponsePolicy(
|
||||
const exactMatchedFactualAddressReply = hasExactMatchedFactualAddressReply(input, entryPoint);
|
||||
const runtimeAdjustedExactReply = hasRuntimeAdjustedExactReply(input, entryPoint);
|
||||
const openScopeValueFlowDiscoveryPriority = hasOpenScopeValueFlowDiscoveryPriority(input, entryPoint);
|
||||
const valueFlowActionConflictWithDiscoveryTurnMeaning = hasValueFlowActionConflictWithDiscoveryTurnMeaning(
|
||||
input,
|
||||
entryPoint
|
||||
);
|
||||
|
||||
if (!entryPoint) {
|
||||
pushReason(reasonCodes, "mcp_discovery_response_policy_no_entry_point");
|
||||
@@ -544,6 +577,9 @@ export function applyAssistantMcpDiscoveryResponsePolicy(
|
||||
if (semanticConflictWithDiscoveryTurnMeaning) {
|
||||
pushReason(reasonCodes, "mcp_discovery_response_policy_semantic_conflict_allows_candidate_override");
|
||||
}
|
||||
if (valueFlowActionConflictWithDiscoveryTurnMeaning) {
|
||||
pushReason(reasonCodes, "mcp_discovery_response_policy_value_flow_action_conflict_allows_candidate_override");
|
||||
}
|
||||
if (openScopeValueFlowDiscoveryPriority) {
|
||||
pushReason(reasonCodes, "mcp_discovery_response_policy_open_scope_value_flow_candidate_priority");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user