Добавить evidence planner для автономного маршрута
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ASSISTANT_EVIDENCE_PLANNER_SCHEMA_VERSION = void 0;
|
||||
exports.buildAssistantEvidencePlanner = buildAssistantEvidencePlanner;
|
||||
exports.ASSISTANT_EVIDENCE_PLANNER_SCHEMA_VERSION = "assistant_evidence_planner_v1";
|
||||
function toNonEmptyString(value) {
|
||||
if (value === null || value === undefined) {
|
||||
return null;
|
||||
}
|
||||
const text = String(value).trim();
|
||||
return text.length > 0 ? text : null;
|
||||
}
|
||||
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 uniqueStrings(values) {
|
||||
const result = [];
|
||||
for (const value of values) {
|
||||
const text = toNonEmptyString(value);
|
||||
if (text && !result.includes(text)) {
|
||||
result.push(text);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function providedAxesFromMeaning(meaning) {
|
||||
const result = [];
|
||||
if ((meaning?.explicit_entity_candidates?.length ?? 0) > 0) {
|
||||
result.push("counterparty");
|
||||
result.push("business_entity");
|
||||
}
|
||||
if (toNonEmptyString(meaning?.explicit_organization_scope)) {
|
||||
result.push("organization");
|
||||
}
|
||||
if (toNonEmptyString(meaning?.explicit_date_scope)) {
|
||||
result.push("period");
|
||||
}
|
||||
if (toNonEmptyString(meaning?.asked_aggregation_axis)) {
|
||||
result.push("aggregate_axis");
|
||||
}
|
||||
if (toNonEmptyString(meaning?.metadata_scope_hint)) {
|
||||
result.push("metadata_scope");
|
||||
}
|
||||
return uniqueStrings(result);
|
||||
}
|
||||
function missingAxes(requiredAxes, providedAxes) {
|
||||
return requiredAxes.filter((axis) => !providedAxes.includes(axis));
|
||||
}
|
||||
function coverageExpectationFor(graph) {
|
||||
if (graph?.proof_expectation === "bounded_inference") {
|
||||
return "bounded_inference";
|
||||
}
|
||||
if (graph?.proof_expectation === "clarification_required") {
|
||||
return "clarification";
|
||||
}
|
||||
return "confirmed_coverage";
|
||||
}
|
||||
function answerModeFor(input) {
|
||||
if (input.plannerStatus === "needs_clarification") {
|
||||
return "clarification_required";
|
||||
}
|
||||
if (input.plannerStatus === "blocked") {
|
||||
return "checked_sources_only";
|
||||
}
|
||||
if (input.coverageExpectation === "bounded_inference") {
|
||||
return "bounded_business_inference";
|
||||
}
|
||||
if (input.coverageExpectation === "clarification") {
|
||||
return "clarification_required";
|
||||
}
|
||||
return "confirmed_business_answer";
|
||||
}
|
||||
function requiredUserLayersFor(answerMode) {
|
||||
if (answerMode === "clarification_required") {
|
||||
return ["clarifying_question", "why_needed", "available_calculation"];
|
||||
}
|
||||
if (answerMode === "bounded_business_inference") {
|
||||
return ["business_conclusion", "key_figures", "evidence_boundary", "next_step"];
|
||||
}
|
||||
if (answerMode === "checked_sources_only") {
|
||||
return ["checked_sources_boundary", "unknowns", "next_probe"];
|
||||
}
|
||||
return ["direct_business_answer", "key_figures", "evidence_boundary", "next_step"];
|
||||
}
|
||||
function buildAssistantEvidencePlanner(input) {
|
||||
const graph = input.dataNeedGraph ?? null;
|
||||
const plan = input.discoveryPlan;
|
||||
const turnMeaning = plan.turn_meaning_ref;
|
||||
const requiredAxes = uniqueStrings(plan.required_axes);
|
||||
const providedAxes = providedAxesFromMeaning(turnMeaning);
|
||||
const graphClarificationGaps = uniqueStrings(graph?.clarification_gaps ?? []);
|
||||
const axisGaps = missingAxes(requiredAxes, providedAxes);
|
||||
const clarificationGaps = uniqueStrings([...graphClarificationGaps, ...axisGaps]);
|
||||
const coverageExpectation = coverageExpectationFor(graph);
|
||||
const answerMode = answerModeFor({
|
||||
plannerStatus: input.plannerStatus,
|
||||
coverageExpectation
|
||||
});
|
||||
const reasonCodes = uniqueStrings(plan.reason_codes);
|
||||
pushReason(reasonCodes, "evidence_planner_contract_built");
|
||||
if (graph) {
|
||||
pushReason(reasonCodes, "evidence_planner_consumed_data_need_graph");
|
||||
}
|
||||
if (clarificationGaps.length > 0) {
|
||||
pushReason(reasonCodes, "evidence_planner_has_missing_axes_or_gaps");
|
||||
}
|
||||
return {
|
||||
schema_version: exports.ASSISTANT_EVIDENCE_PLANNER_SCHEMA_VERSION,
|
||||
policy_owner: "assistantEvidencePlanner",
|
||||
planner_status: input.plannerStatus,
|
||||
semantic_data_need: toNonEmptyString(input.semanticDataNeed),
|
||||
selected_chain_id: input.selectedChainId,
|
||||
data_need: {
|
||||
business_fact_family: graph?.business_fact_family ?? null,
|
||||
action_family: graph?.action_family ?? null,
|
||||
aggregation_need: graph?.aggregation_need ?? null,
|
||||
comparison_need: graph?.comparison_need ?? null,
|
||||
ranking_need: graph?.ranking_need ?? null,
|
||||
time_scope_need: graph?.time_scope_need ?? null,
|
||||
proof_expectation: graph?.proof_expectation ?? null,
|
||||
subject_candidates: uniqueStrings(graph?.subject_candidates ?? [])
|
||||
},
|
||||
evidence_axes: {
|
||||
required_axes: requiredAxes,
|
||||
provided_axes: providedAxes,
|
||||
missing_axes: axisGaps,
|
||||
clarification_gaps: clarificationGaps
|
||||
},
|
||||
primitive_plan: {
|
||||
selected_chain_id: input.selectedChainId,
|
||||
allowed_primitives: plan.allowed_primitives,
|
||||
rejected_primitives: plan.rejected_primitives,
|
||||
execution_budget: plan.execution_budget
|
||||
},
|
||||
coverage_gate: {
|
||||
requires_evidence_gate: true,
|
||||
expected_coverage: coverageExpectation,
|
||||
answer_permission_if_satisfied: answerMode,
|
||||
answer_may_use_raw_model_claims: false
|
||||
},
|
||||
answer_contract: {
|
||||
answer_mode: answerMode,
|
||||
required_user_layers: requiredUserLayersFor(answerMode),
|
||||
forbidden_overclaim_flags: uniqueStrings(graph?.forbidden_overclaim_flags ?? []),
|
||||
must_keep_internal_mechanics_hidden: true
|
||||
},
|
||||
reason_codes: reasonCodes
|
||||
};
|
||||
}
|
||||
@@ -38,6 +38,10 @@ function isRouteCandidateContract(value) {
|
||||
return (record?.schema_version === "assistant_mcp_route_candidate_v1" &&
|
||||
record?.policy_owner === "assistantMcpDiscoveryRuntimeBridge");
|
||||
}
|
||||
function isEvidencePlannerContract(value) {
|
||||
const record = toRecordObject(value);
|
||||
return record?.schema_version === "assistant_evidence_planner_v1" && record?.policy_owner === "assistantEvidencePlanner";
|
||||
}
|
||||
function resolveEntryPoint(input) {
|
||||
if (isMcpDiscoveryEntryPointContract(input.entryPoint)) {
|
||||
return input.entryPoint;
|
||||
@@ -51,6 +55,10 @@ function buildAssistantMcpDiscoveryDebugAttachmentFields(input) {
|
||||
const entryPoint = resolveEntryPoint(input);
|
||||
const bridge = toRecordObject(entryPoint?.bridge);
|
||||
const planner = toRecordObject(bridge?.planner);
|
||||
const evidencePlan = isEvidencePlannerContract(planner?.evidence_plan) ? planner.evidence_plan : null;
|
||||
const evidencePlanAxes = toRecordObject(evidencePlan?.evidence_axes);
|
||||
const evidencePlanCoverageGate = toRecordObject(evidencePlan?.coverage_gate);
|
||||
const evidencePlanAnswerContract = toRecordObject(evidencePlan?.answer_contract);
|
||||
const chainAlignment = toRecordObject(planner?.catalog_chain_template_alignment);
|
||||
const routeCandidate = isRouteCandidateContract(bridge?.route_candidate) ? bridge.route_candidate : null;
|
||||
const answerDraft = toRecordObject(bridge?.answer_draft);
|
||||
@@ -61,6 +69,11 @@ function buildAssistantMcpDiscoveryDebugAttachmentFields(input) {
|
||||
mcp_discovery_hot_runtime_wired: false,
|
||||
mcp_discovery_bridge_status: toNonEmptyString(bridge?.bridge_status),
|
||||
mcp_discovery_selected_chain_id: toNonEmptyString(planner?.selected_chain_id),
|
||||
mcp_discovery_evidence_plan_v1: evidencePlan,
|
||||
mcp_discovery_evidence_plan_status: toNonEmptyString(evidencePlan?.planner_status),
|
||||
mcp_discovery_evidence_plan_answer_mode: toNonEmptyString(evidencePlanAnswerContract?.answer_mode),
|
||||
mcp_discovery_evidence_plan_missing_axes: toStringArray(evidencePlanAxes?.missing_axes),
|
||||
mcp_discovery_evidence_plan_expected_coverage: toNonEmptyString(evidencePlanCoverageGate?.expected_coverage),
|
||||
mcp_discovery_catalog_chain_template_matches: toStringArray(planner?.catalog_chain_template_matches),
|
||||
mcp_discovery_catalog_chain_alignment_status: toNonEmptyString(chainAlignment?.alignment_status),
|
||||
mcp_discovery_catalog_chain_top_match: toNonEmptyString(chainAlignment?.top_chain_template_match),
|
||||
|
||||
@@ -4,6 +4,7 @@ exports.ASSISTANT_MCP_DISCOVERY_PLANNER_SCHEMA_VERSION = void 0;
|
||||
exports.planAssistantMcpDiscovery = planAssistantMcpDiscovery;
|
||||
const assistantMcpDiscoveryPolicy_1 = require("./assistantMcpDiscoveryPolicy");
|
||||
const assistantMcpCatalogIndex_1 = require("./assistantMcpCatalogIndex");
|
||||
const assistantEvidencePlanner_1 = require("./assistantEvidencePlanner");
|
||||
exports.ASSISTANT_MCP_DISCOVERY_PLANNER_SCHEMA_VERSION = "assistant_mcp_discovery_planner_v1";
|
||||
const CHUNKED_COVERAGE_PROBE_BUDGET = 30;
|
||||
function toNonEmptyString(value) {
|
||||
@@ -1139,6 +1140,13 @@ function planAssistantMcpDiscovery(input) {
|
||||
else {
|
||||
pushReason(reasonCodes, "planner_needs_more_user_or_scope_context");
|
||||
}
|
||||
const evidencePlan = (0, assistantEvidencePlanner_1.buildAssistantEvidencePlanner)({
|
||||
selectedChainId: recipe.chainId,
|
||||
plannerStatus,
|
||||
semanticDataNeed,
|
||||
dataNeedGraph,
|
||||
discoveryPlan: plan
|
||||
});
|
||||
return {
|
||||
schema_version: exports.ASSISTANT_MCP_DISCOVERY_PLANNER_SCHEMA_VERSION,
|
||||
policy_owner: "assistantMcpDiscoveryPlanner",
|
||||
@@ -1152,6 +1160,7 @@ function planAssistantMcpDiscovery(input) {
|
||||
catalog_chain_template_alignment: catalogChainTemplateAlignment,
|
||||
proposed_primitives: recipe.primitives,
|
||||
required_axes: recipe.axes,
|
||||
evidence_plan: evidencePlan,
|
||||
discovery_plan: plan,
|
||||
catalog_review: adjustedReview,
|
||||
reason_codes: reasonCodes
|
||||
|
||||
Reference in New Issue
Block a user