NODEDC_1C/llm_normalizer/backend/dist/services/assistantMcpDiscoveryPlanne...

162 lines
6.0 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ASSISTANT_MCP_DISCOVERY_PLANNER_SCHEMA_VERSION = void 0;
exports.planAssistantMcpDiscovery = planAssistantMcpDiscovery;
const assistantMcpDiscoveryPolicy_1 = require("./assistantMcpDiscoveryPolicy");
const assistantMcpCatalogIndex_1 = require("./assistantMcpCatalogIndex");
exports.ASSISTANT_MCP_DISCOVERY_PLANNER_SCHEMA_VERSION = "assistant_mcp_discovery_planner_v1";
function toNonEmptyString(value) {
if (value === null || value === undefined) {
return null;
}
const text = String(value).trim();
return text.length > 0 ? text : null;
}
function lower(value) {
return String(value ?? "").trim().toLowerCase();
}
function normalizeReasonCode(value) {
const normalized = value
.trim()
.replace(/[^\p{L}\p{N}_.:-]+/gu, "_")
.replace(/^_+|_+$/g, "")
.toLowerCase();
return normalized.length > 0 ? normalized.slice(0, 120) : null;
}
function pushReason(target, value) {
const normalized = normalizeReasonCode(value);
if (normalized && !target.includes(normalized)) {
target.push(normalized);
}
}
function pushUnique(target, value) {
const text = value.trim();
if (text && !target.includes(text)) {
target.push(text);
}
}
function hasEntity(meaning) {
return (meaning?.explicit_entity_candidates?.length ?? 0) > 0;
}
function addScopeAxes(axes, meaning) {
if (hasEntity(meaning)) {
pushUnique(axes, "counterparty");
}
if (toNonEmptyString(meaning?.explicit_organization_scope)) {
pushUnique(axes, "organization");
}
if (toNonEmptyString(meaning?.explicit_date_scope)) {
pushUnique(axes, "period");
}
}
function includesAny(text, tokens) {
return tokens.some((token) => text.includes(token));
}
function recipeFor(input) {
const meaning = input.turnMeaning ?? null;
const domain = lower(meaning?.asked_domain_family);
const action = lower(meaning?.asked_action_family);
const unsupported = lower(meaning?.unsupported_but_understood_family);
const combined = `${domain} ${action} ${unsupported}`.trim();
const axes = [];
addScopeAxes(axes, meaning);
if (includesAny(combined, ["turnover", "revenue", "payment", "payout", "value"])) {
pushUnique(axes, "aggregate_axis");
pushUnique(axes, "amount");
pushUnique(axes, "coverage_target");
return {
semanticDataNeed: "counterparty value-flow evidence",
primitives: ["resolve_entity_reference", "query_movements", "aggregate_by_axis", "probe_coverage"],
axes,
reason: "planner_selected_value_flow_recipe"
};
}
if (includesAny(combined, ["document", "documents"])) {
pushUnique(axes, "coverage_target");
return {
semanticDataNeed: "document evidence",
primitives: ["resolve_entity_reference", "query_documents", "probe_coverage"],
axes,
reason: "planner_selected_document_recipe"
};
}
if (includesAny(combined, ["lifecycle", "activity", "duration", "age"])) {
pushUnique(axes, "document_date");
pushUnique(axes, "coverage_target");
pushUnique(axes, "evidence_basis");
return {
semanticDataNeed: "counterparty lifecycle evidence",
primitives: ["resolve_entity_reference", "query_documents", "probe_coverage", "explain_evidence_basis"],
axes,
reason: "planner_selected_lifecycle_recipe"
};
}
if (includesAny(combined, ["metadata", "schema", "catalog"])) {
pushUnique(axes, "metadata_scope");
return {
semanticDataNeed: "1C metadata evidence",
primitives: ["inspect_1c_metadata"],
axes,
reason: "planner_selected_metadata_recipe"
};
}
if (hasEntity(meaning)) {
pushUnique(axes, "business_entity");
return {
semanticDataNeed: "entity discovery evidence",
primitives: ["search_business_entity", "resolve_entity_reference", "probe_coverage"],
axes,
reason: "planner_selected_entity_resolution_recipe"
};
}
return {
semanticDataNeed: "unclassified 1C discovery need",
primitives: ["inspect_1c_metadata"],
axes,
reason: "planner_selected_clarification_recipe"
};
}
function statusFrom(plan, review) {
if (plan.plan_status === "blocked" || review.review_status === "catalog_blocked") {
return "blocked";
}
if (plan.plan_status !== "allowed" || review.review_status !== "catalog_compatible") {
return "needs_clarification";
}
return "ready_for_execution";
}
function planAssistantMcpDiscovery(input) {
const recipe = recipeFor(input);
const semanticDataNeed = toNonEmptyString(input.semanticDataNeed) ?? recipe.semanticDataNeed;
const reasonCodes = [];
pushReason(reasonCodes, recipe.reason);
const plan = (0, assistantMcpDiscoveryPolicy_1.buildAssistantMcpDiscoveryPlan)({
semanticDataNeed,
turnMeaning: input.turnMeaning,
proposedPrimitives: recipe.primitives,
requiredAxes: recipe.axes
});
const review = (0, assistantMcpCatalogIndex_1.reviewAssistantMcpDiscoveryPlanAgainstCatalog)(plan);
const plannerStatus = statusFrom(plan, review);
if (plannerStatus === "ready_for_execution") {
pushReason(reasonCodes, "planner_ready_for_guarded_mcp_execution");
}
else if (plannerStatus === "blocked") {
pushReason(reasonCodes, "planner_blocked_by_policy_or_catalog");
}
else {
pushReason(reasonCodes, "planner_needs_more_user_or_scope_context");
}
return {
schema_version: exports.ASSISTANT_MCP_DISCOVERY_PLANNER_SCHEMA_VERSION,
policy_owner: "assistantMcpDiscoveryPlanner",
planner_status: plannerStatus,
semantic_data_need: semanticDataNeed,
proposed_primitives: recipe.primitives,
required_axes: recipe.axes,
discovery_plan: plan,
catalog_review: review,
reason_codes: reasonCodes
};
}