ARCH: связать metadata grounding с document MCP lane

This commit is contained in:
2026-04-21 23:01:12 +03:00
parent 6d9c1568c3
commit 7ef788fa50
18 changed files with 706 additions and 54 deletions
@@ -149,6 +149,7 @@ interface AssistantMcpDiscoveryCoverageAwareQueryExecution {
export type AssistantMcpDiscoveryPilotScope =
| "metadata_inspection_v1"
| "counterparty_document_evidence_query_documents_v1"
| "counterparty_lifecycle_query_documents_v1"
| "counterparty_value_flow_query_movements_v1"
| "counterparty_supplier_payout_query_movements_v1"
@@ -291,6 +292,18 @@ function isLifecyclePilotEligible(planner: AssistantMcpDiscoveryPlannerContract)
);
}
function isDocumentEvidencePilotEligible(planner: AssistantMcpDiscoveryPlannerContract): boolean {
const meaning = planner.discovery_plan.turn_meaning_ref;
const domain = String(meaning?.asked_domain_family ?? "").toLowerCase();
const action = String(meaning?.asked_action_family ?? "").toLowerCase();
const unsupported = String(meaning?.unsupported_but_understood_family ?? "").toLowerCase();
const combined = `${domain} ${action} ${unsupported}`;
return (
planner.proposed_primitives.includes("query_documents") &&
(combined.includes("document") || combined.includes("list_documents"))
);
}
function isValueFlowPilotEligible(planner: AssistantMcpDiscoveryPlannerContract): boolean {
const meaning = planner.discovery_plan.turn_meaning_ref;
const domain = String(meaning?.asked_domain_family ?? "").toLowerCase();
@@ -641,6 +654,16 @@ function summarizeLifecycleRows(result: AddressMcpQueryExecutorResult): string |
return `${result.fetched_rows} MCP document rows fetched, ${result.matched_rows} matched lifecycle scope`;
}
function summarizeDocumentRows(result: AddressMcpQueryExecutorResult): string | null {
if (result.error) {
return null;
}
if (result.fetched_rows <= 0) {
return "0 MCP document rows fetched";
}
return `${result.fetched_rows} MCP document rows fetched, ${result.matched_rows} matched document scope`;
}
function summarizeValueFlowRows(result: AssistantMcpDiscoveryCoverageAwareQueryResult): string | null {
if (result.error) {
return null;
@@ -1310,6 +1333,17 @@ function buildLifecycleConfirmedFacts(result: AddressMcpQueryExecutorResult, cou
];
}
function buildDocumentConfirmedFacts(result: AddressMcpQueryExecutorResult, counterparty: string | null): string[] {
if (result.error || result.matched_rows <= 0) {
return [];
}
return [
counterparty
? `1C document rows were found for counterparty ${counterparty}`
: "1C document rows were found for the requested scope"
];
}
function buildValueFlowConfirmedFacts(
result: AssistantMcpDiscoveryCoverageAwareQueryResult,
counterparty: string | null,
@@ -1357,6 +1391,13 @@ function buildLifecycleInferredFacts(result: AddressMcpQueryExecutorResult): str
return ["Business activity duration may be inferred from first and latest confirmed 1C activity rows"];
}
function buildDocumentInferredFacts(result: AddressMcpQueryExecutorResult): string[] {
if (result.error || result.fetched_rows <= 0) {
return [];
}
return ["Counterparty document evidence is limited to confirmed 1C document rows in the checked scope"];
}
function buildValueFlowInferredFacts(derived: AssistantMcpDiscoveryDerivedValueFlow | null): string[] {
if (!derived) {
return [];
@@ -1400,6 +1441,14 @@ function buildLifecycleUnknownFacts(): string[] {
return ["Legal registration date is not proven by this MCP discovery pilot"];
}
function buildDocumentUnknownFacts(periodScope: string | null): string[] {
return [
periodScope
? "Full document history outside the checked period is not proven by this MCP discovery pilot"
: "Full document history is not proven without an explicit checked period"
];
}
function buildValueFlowUnknownFacts(
periodScope: string | null,
direction: AssistantMcpDiscoveryDerivedValueFlow["value_flow_direction"],
@@ -1465,6 +1514,9 @@ function pilotScopeForPlanner(planner: AssistantMcpDiscoveryPlannerContract): As
if (isValueFlowPilotEligible(planner)) {
return valueFlowPilotProfile(planner).scope;
}
if (isDocumentEvidencePilotEligible(planner)) {
return "counterparty_document_evidence_query_documents_v1";
}
return "counterparty_lifecycle_query_documents_v1";
}
@@ -1533,10 +1585,11 @@ export async function executeAssistantMcpDiscoveryPilot(
}
const metadataPilotEligible = isMetadataPilotEligible(planner);
const documentPilotEligible = isDocumentEvidencePilotEligible(planner);
const lifecyclePilotEligible = isLifecyclePilotEligible(planner);
const valueFlowPilotEligible = isValueFlowPilotEligible(planner);
if (!metadataPilotEligible && !lifecyclePilotEligible && !valueFlowPilotEligible) {
if (!metadataPilotEligible && !documentPilotEligible && !lifecyclePilotEligible && !valueFlowPilotEligible) {
pushReason(reasonCodes, "pilot_scope_unsupported_for_live_execution");
for (const step of dryRun.execution_steps) {
skippedPrimitives.push(step.primitive_id);
@@ -1631,6 +1684,89 @@ export async function executeAssistantMcpDiscoveryPilot(
};
}
if (documentPilotEligible) {
let queryResult: AddressMcpQueryExecutorResult | null = null;
const filters = buildLifecycleFilters(planner);
const selection = selectAddressRecipe("list_documents_by_counterparty", filters);
if (!selection.selected_recipe) {
pushReason(reasonCodes, "pilot_document_recipe_not_available");
const evidence = buildEmptyEvidence(planner, dryRun, probeResults, "Document-evidence recipe is not available");
return {
schema_version: ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION,
policy_owner: "assistantMcpDiscoveryPilotExecutor",
pilot_status: "unsupported",
pilot_scope: "counterparty_document_evidence_query_documents_v1",
dry_run: dryRun,
mcp_execution_performed: false,
executed_primitives: executedPrimitives,
skipped_primitives: skippedPrimitives,
probe_results: probeResults,
evidence,
source_rows_summary: null,
derived_metadata_surface: null,
derived_activity_period: null,
derived_value_flow: null,
derived_bidirectional_value_flow: null,
query_limitations: ["Document-evidence recipe is not available"],
reason_codes: reasonCodes
};
}
const recipePlan = buildAddressRecipePlan(selection.selected_recipe, filters);
for (const step of dryRun.execution_steps) {
if (step.primitive_id !== "query_documents") {
skippedPrimitives.push(step.primitive_id);
probeResults.push(skippedProbeResult(step, "pilot_only_executes_query_documents"));
continue;
}
queryResult = await runtimeDeps.executeAddressMcpQuery({
query: recipePlan.query,
limit: recipePlan.limit,
account_scope: recipePlan.account_scope
});
executedPrimitives.push(step.primitive_id);
probeResults.push(queryResultToProbeResult(step.primitive_id, queryResult));
if (queryResult.error) {
pushUnique(queryLimitations, queryResult.error);
pushReason(reasonCodes, "pilot_query_documents_mcp_error");
} else {
pushReason(reasonCodes, "pilot_query_documents_mcp_executed");
}
}
const sourceRowsSummary = queryResult ? summarizeDocumentRows(queryResult) : null;
const evidence = resolveAssistantMcpDiscoveryEvidence({
plan: planner.discovery_plan,
probeResults,
confirmedFacts: queryResult ? buildDocumentConfirmedFacts(queryResult, counterparty) : [],
inferredFacts: queryResult ? buildDocumentInferredFacts(queryResult) : [],
unknownFacts: buildDocumentUnknownFacts(dateScope),
sourceRowsSummary,
queryLimitations,
recommendedNextProbe: "explain_evidence_basis"
});
return {
schema_version: ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION,
policy_owner: "assistantMcpDiscoveryPilotExecutor",
pilot_status: "executed",
pilot_scope: "counterparty_document_evidence_query_documents_v1",
dry_run: dryRun,
mcp_execution_performed: executedPrimitives.length > 0,
executed_primitives: executedPrimitives,
skipped_primitives: skippedPrimitives,
probe_results: probeResults,
evidence,
source_rows_summary: sourceRowsSummary,
derived_metadata_surface: null,
derived_activity_period: null,
derived_value_flow: null,
derived_bidirectional_value_flow: null,
query_limitations: queryLimitations,
reason_codes: reasonCodes
};
}
if (valueFlowPilotEligible) {
let queryResult: AssistantMcpDiscoveryCoverageAwareQueryResult | null = null;
const filters = buildValueFlowFilters(planner);