Закрепить целевой AGENT-прогон hot value-flow handoff
This commit is contained in:
@@ -193,6 +193,12 @@ function rankingNeedFromRawUtterance(value) {
|
||||
if (!text) {
|
||||
return null;
|
||||
}
|
||||
if (/\u0438\u0441\u043a\u043b\u044e\u0447[\p{L}\p{N}_]*\s+\u0442\u043e\u043f/iu.test(text)) {
|
||||
return null;
|
||||
}
|
||||
if (/(?:\u0431\u0435\u0437\s+\u0442\u043e\u043f(?:\u043e\u0432|\u0430)?\b|\u043d\u0435\s+\u0442\u043e\u043f\b|\u0438\u0441\u043a\u043b\u044e\u0447\w*\s+\u0442\u043e\u043f|\u0431\u0435\u0437\s+\u0440\u0435\u0439\u0442\u0438\u043d\u0433\u0430\b|без\s+топ(?:ов|а)?\b|не\s+топ\b|исключ\S*\s+топ|без\s+рейтинга\b)/iu.test(text)) {
|
||||
return null;
|
||||
}
|
||||
if (/(?:\u0442\u043e\u043f[-\s]?\d*|\u0441\u0430\u043c(?:\u044b\u0439|\u0430\u044f|\u043e\u0435|\u044b\u0435)|\u0431\u043e\u043b\u044c\u0448\u0435\s+\u0432\u0441\u0435\u0433\u043e|\u043d\u0430\u0438\u0431\u043e\u043b[\u0435\u0451]\u0435|\u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d|\u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c|\u043a\u0440\u0443\u043f\u043d\u0435\u0439\u0448|\u043b\u0443\u0447\u0448\u0438\u0439)/iu.test(text)) {
|
||||
return "top_desc";
|
||||
}
|
||||
|
||||
+4
-1
@@ -68,11 +68,14 @@ function buildAssistantMcpDiscoveryDebugAttachmentFields(input) {
|
||||
const routeCandidate = isRouteCandidateContract(bridge?.route_candidate) ? bridge.route_candidate : null;
|
||||
const executionHandoff = isExecutionHandoffContract(bridge?.execution_handoff) ? bridge.execution_handoff : null;
|
||||
const answerDraft = toRecordObject(bridge?.answer_draft);
|
||||
const hotRuntimeWired = entryPoint?.hot_runtime_wired === true ||
|
||||
bridge?.hot_runtime_wired === true ||
|
||||
executionHandoff?.can_use_guarded_response === true;
|
||||
return {
|
||||
assistant_mcp_discovery_entry_point_v1: entryPoint,
|
||||
mcp_discovery_entry_status: toNonEmptyString(entryPoint?.entry_status),
|
||||
mcp_discovery_attempted: Boolean(entryPoint?.discovery_attempted),
|
||||
mcp_discovery_hot_runtime_wired: false,
|
||||
mcp_discovery_hot_runtime_wired: hotRuntimeWired,
|
||||
mcp_discovery_bridge_status: toNonEmptyString(bridge?.bridge_status),
|
||||
mcp_discovery_selected_chain_id: toNonEmptyString(planner?.selected_chain_id),
|
||||
mcp_discovery_evidence_plan_v1: evidencePlan,
|
||||
|
||||
+21
-2
@@ -204,12 +204,16 @@ function hasMetadataDiscoveryPriority(input, entryPoint) {
|
||||
}
|
||||
function isOpenScopeValueFlowWithoutSubject(entryPoint) {
|
||||
const graph = readDiscoveryDataNeedGraph(entryPoint);
|
||||
const turnMeaning = readDiscoveryTurnMeaning(entryPoint);
|
||||
const businessFactFamily = toNonEmptyString(graph?.business_fact_family);
|
||||
const subjectCandidates = Array.isArray(graph?.subject_candidates) ? graph.subject_candidates : [];
|
||||
const reasonCodes = Array.isArray(graph?.reason_codes) ? graph.reason_codes : [];
|
||||
const reasonCodes = readStringArray(graph?.reason_codes);
|
||||
const clarificationGaps = readStringArray(graph?.clarification_gaps);
|
||||
const explicitOrganizationScope = toNonEmptyString(turnMeaning?.explicit_organization_scope);
|
||||
return (businessFactFamily === "value_flow" &&
|
||||
subjectCandidates.length === 0 &&
|
||||
reasonCodes.some((reason) => toNonEmptyString(reason) === "data_need_graph_open_scope_total_without_subject"));
|
||||
(reasonCodes.includes("data_need_graph_open_scope_total_without_subject") ||
|
||||
(Boolean(explicitOrganizationScope) && clarificationGaps.includes("subject"))));
|
||||
}
|
||||
function needsOpenScopeValueFlowOrganizationClarification(entryPoint) {
|
||||
const graph = readDiscoveryDataNeedGraph(entryPoint);
|
||||
@@ -440,6 +444,9 @@ function hasRuntimeAdjustedExactReply(input, entryPoint) {
|
||||
if (hasMetadataDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasOpenScopeValueFlowDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasEvidenceLaneConflictWithDiscoveryTurnMeaning(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
@@ -463,6 +470,9 @@ function hasRuntimeMatchedExactReply(input, entryPoint) {
|
||||
if (hasMetadataDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasOpenScopeValueFlowDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasEvidenceLaneConflictWithDiscoveryTurnMeaning(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
@@ -483,6 +493,9 @@ function hasAlignedFactualAddressReply(input, entryPoint) {
|
||||
if (hasMetadataDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasOpenScopeValueFlowDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasSemanticConflictWithDiscoveryTurnMeaning(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
@@ -538,6 +551,9 @@ function hasMatchedFactualAddressContinuationTarget(input, entryPoint) {
|
||||
if (hasMetadataDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasOpenScopeValueFlowDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
const detectedIntent = toNonEmptyString(input.addressRuntimeMeta?.detected_intent);
|
||||
const dialogContinuationContract = toRecordObject(input.addressRuntimeMeta?.dialogContinuationContract) ??
|
||||
toRecordObject(input.addressRuntimeMeta?.dialog_continuation_contract_v2);
|
||||
@@ -578,6 +594,9 @@ function hasFullConfirmedFactualAddressReply(input, entryPoint) {
|
||||
if (hasMetadataDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasOpenScopeValueFlowDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
return hasFullConfirmedTruth(input);
|
||||
}
|
||||
function applyAssistantMcpDiscoveryResponsePolicy(input) {
|
||||
|
||||
@@ -293,6 +293,12 @@ function rankingNeedFromRawUtterance(value: string): string | null {
|
||||
if (!text) {
|
||||
return null;
|
||||
}
|
||||
if (/\u0438\u0441\u043a\u043b\u044e\u0447[\p{L}\p{N}_]*\s+\u0442\u043e\u043f/iu.test(text)) {
|
||||
return null;
|
||||
}
|
||||
if (/(?:\u0431\u0435\u0437\s+\u0442\u043e\u043f(?:\u043e\u0432|\u0430)?\b|\u043d\u0435\s+\u0442\u043e\u043f\b|\u0438\u0441\u043a\u043b\u044e\u0447\w*\s+\u0442\u043e\u043f|\u0431\u0435\u0437\s+\u0440\u0435\u0439\u0442\u0438\u043d\u0433\u0430\b|без\s+топ(?:ов|а)?\b|не\s+топ\b|исключ\S*\s+топ|без\s+рейтинга\b)/iu.test(text)) {
|
||||
return null;
|
||||
}
|
||||
if (/(?:\u0442\u043e\u043f[-\s]?\d*|\u0441\u0430\u043c(?:\u044b\u0439|\u0430\u044f|\u043e\u0435|\u044b\u0435)|\u0431\u043e\u043b\u044c\u0448\u0435\s+\u0432\u0441\u0435\u0433\u043e|\u043d\u0430\u0438\u0431\u043e\u043b[\u0435\u0451]\u0435|\u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d|\u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c|\u043a\u0440\u0443\u043f\u043d\u0435\u0439\u0448|\u043b\u0443\u0447\u0448\u0438\u0439)/iu.test(text)) {
|
||||
return "top_desc";
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ export interface AssistantMcpDiscoveryDebugAttachmentFields {
|
||||
assistant_mcp_discovery_entry_point_v1: AssistantMcpDiscoveryRuntimeEntryPointContract | null;
|
||||
mcp_discovery_entry_status: string | null;
|
||||
mcp_discovery_attempted: boolean;
|
||||
mcp_discovery_hot_runtime_wired: false;
|
||||
mcp_discovery_hot_runtime_wired: boolean;
|
||||
mcp_discovery_bridge_status: string | null;
|
||||
mcp_discovery_selected_chain_id: string | null;
|
||||
mcp_discovery_evidence_plan_v1: AssistantEvidencePlannerContract | null;
|
||||
@@ -130,12 +130,16 @@ export function buildAssistantMcpDiscoveryDebugAttachmentFields(
|
||||
const routeCandidate = isRouteCandidateContract(bridge?.route_candidate) ? bridge.route_candidate : null;
|
||||
const executionHandoff = isExecutionHandoffContract(bridge?.execution_handoff) ? bridge.execution_handoff : null;
|
||||
const answerDraft = toRecordObject(bridge?.answer_draft);
|
||||
const hotRuntimeWired =
|
||||
entryPoint?.hot_runtime_wired === true ||
|
||||
bridge?.hot_runtime_wired === true ||
|
||||
executionHandoff?.can_use_guarded_response === true;
|
||||
|
||||
return {
|
||||
assistant_mcp_discovery_entry_point_v1: entryPoint,
|
||||
mcp_discovery_entry_status: toNonEmptyString(entryPoint?.entry_status),
|
||||
mcp_discovery_attempted: Boolean(entryPoint?.discovery_attempted),
|
||||
mcp_discovery_hot_runtime_wired: false,
|
||||
mcp_discovery_hot_runtime_wired: hotRuntimeWired,
|
||||
mcp_discovery_bridge_status: toNonEmptyString(bridge?.bridge_status),
|
||||
mcp_discovery_selected_chain_id: toNonEmptyString(planner?.selected_chain_id),
|
||||
mcp_discovery_evidence_plan_v1: evidencePlan,
|
||||
|
||||
@@ -306,13 +306,17 @@ function isOpenScopeValueFlowWithoutSubject(
|
||||
entryPoint: AssistantMcpDiscoveryRuntimeEntryPointContract | null
|
||||
): boolean {
|
||||
const graph = readDiscoveryDataNeedGraph(entryPoint);
|
||||
const turnMeaning = readDiscoveryTurnMeaning(entryPoint);
|
||||
const businessFactFamily = toNonEmptyString(graph?.business_fact_family);
|
||||
const subjectCandidates = Array.isArray(graph?.subject_candidates) ? graph.subject_candidates : [];
|
||||
const reasonCodes = Array.isArray(graph?.reason_codes) ? graph.reason_codes : [];
|
||||
const reasonCodes = readStringArray(graph?.reason_codes);
|
||||
const clarificationGaps = readStringArray(graph?.clarification_gaps);
|
||||
const explicitOrganizationScope = toNonEmptyString(turnMeaning?.explicit_organization_scope);
|
||||
return (
|
||||
businessFactFamily === "value_flow" &&
|
||||
subjectCandidates.length === 0 &&
|
||||
reasonCodes.some((reason) => toNonEmptyString(reason) === "data_need_graph_open_scope_total_without_subject")
|
||||
(reasonCodes.includes("data_need_graph_open_scope_total_without_subject") ||
|
||||
(Boolean(explicitOrganizationScope) && clarificationGaps.includes("subject")))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -609,6 +613,9 @@ function hasRuntimeAdjustedExactReply(
|
||||
if (hasMetadataDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasOpenScopeValueFlowDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasEvidenceLaneConflictWithDiscoveryTurnMeaning(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
@@ -638,6 +645,9 @@ function hasRuntimeMatchedExactReply(
|
||||
if (hasMetadataDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasOpenScopeValueFlowDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasEvidenceLaneConflictWithDiscoveryTurnMeaning(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
@@ -664,6 +674,9 @@ function hasAlignedFactualAddressReply(
|
||||
if (hasMetadataDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasOpenScopeValueFlowDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasSemanticConflictWithDiscoveryTurnMeaning(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
@@ -729,6 +742,9 @@ function hasMatchedFactualAddressContinuationTarget(
|
||||
if (hasMetadataDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasOpenScopeValueFlowDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
const detectedIntent = toNonEmptyString(input.addressRuntimeMeta?.detected_intent);
|
||||
const dialogContinuationContract =
|
||||
toRecordObject(input.addressRuntimeMeta?.dialogContinuationContract) ??
|
||||
@@ -781,6 +797,9 @@ function hasFullConfirmedFactualAddressReply(
|
||||
if (hasMetadataDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (hasOpenScopeValueFlowDiscoveryPriority(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
return hasFullConfirmedTruth(input);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,25 @@ describe("assistant MCP discovery data need graph", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("does not turn explicit no-top wording into a value-flow ranking", () => {
|
||||
const result = buildAssistantMcpDiscoveryDataNeedGraph({
|
||||
semanticDataNeed: "counterparty value-flow evidence",
|
||||
rawUtterance:
|
||||
"Определить общую сумму поступлений в ООО Альтернатива Плюс за 2020 год, исключая топ-контрагентов и детализацию по контрагентам",
|
||||
turnMeaning: {
|
||||
asked_domain_family: "counterparty_value",
|
||||
asked_action_family: "counterparty_value_or_turnover",
|
||||
explicit_organization_scope: "ООО Альтернатива Плюс",
|
||||
explicit_date_scope: "2020"
|
||||
}
|
||||
});
|
||||
|
||||
expect(result.business_fact_family).toBe("value_flow");
|
||||
expect(result.ranking_need).toBeNull();
|
||||
expect(result.decomposition_candidates).toContain("aggregate_checked_amounts");
|
||||
expect(result.decomposition_candidates).not.toContain("aggregate_ranked_axis_values");
|
||||
});
|
||||
|
||||
it("marks metadata lane choice as a clarification-required graph", () => {
|
||||
const result = buildAssistantMcpDiscoveryDataNeedGraph({
|
||||
semanticDataNeed: "metadata lane clarification",
|
||||
|
||||
@@ -100,7 +100,7 @@ describe("assistant MCP discovery debug attachment", () => {
|
||||
);
|
||||
expect(debug.mcp_discovery_entry_status).toBe("bridge_executed");
|
||||
expect(debug.mcp_discovery_attempted).toBe(true);
|
||||
expect(debug.mcp_discovery_hot_runtime_wired).toBe(false);
|
||||
expect(debug.mcp_discovery_hot_runtime_wired).toBe(true);
|
||||
expect(debug.mcp_discovery_bridge_status).toBe("answer_draft_ready");
|
||||
expect(debug.mcp_discovery_selected_chain_id).toBe("value_flow");
|
||||
expect(debug.mcp_discovery_evidence_plan_status).toBe("ready_for_execution");
|
||||
|
||||
Reference in New Issue
Block a user