269 lines
11 KiB
TypeScript
269 lines
11 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
||
import { applyAssistantMcpDiscoveryResponsePolicy } from "../src/services/assistantMcpDiscoveryResponsePolicy";
|
||
|
||
function entryPoint(overrides: Record<string, unknown> = {}) {
|
||
return {
|
||
schema_version: "assistant_mcp_discovery_runtime_entry_point_v1",
|
||
policy_owner: "assistantMcpDiscoveryRuntimeEntryPoint",
|
||
entry_status: "bridge_executed",
|
||
hot_runtime_wired: false,
|
||
discovery_attempted: true,
|
||
turn_input: { adapter_status: "ready" },
|
||
bridge: {
|
||
bridge_status: "answer_draft_ready",
|
||
user_facing_response_allowed: true,
|
||
business_fact_answer_allowed: true,
|
||
requires_user_clarification: false,
|
||
answer_draft: {
|
||
answer_mode: "confirmed_with_bounded_inference",
|
||
headline: "Confirmed scoped answer.",
|
||
confirmed_lines: ["Confirmed fact"],
|
||
inference_lines: ["Bounded inference"],
|
||
unknown_lines: ["Unconfirmed fact"],
|
||
limitation_lines: ["Limited source window"],
|
||
next_step_line: null
|
||
}
|
||
},
|
||
reason_codes: ["runtime_entry_point_bridge_executed"],
|
||
...overrides
|
||
} as any;
|
||
}
|
||
|
||
describe("assistant MCP discovery response policy", () => {
|
||
it("applies a guarded candidate only for unsupported current-turn boundary replies", () => {
|
||
const result = applyAssistantMcpDiscoveryResponsePolicy({
|
||
currentReply: "route is not wired",
|
||
currentReplySource: "deterministic_unsupported_current_turn_boundary",
|
||
modeDecisionReason: "unsupported_current_turn_meaning_boundary",
|
||
addressRuntimeMeta: {
|
||
mcpDiscoveryRuntimeEntryPoint: entryPoint()
|
||
}
|
||
});
|
||
|
||
expect(result.applied).toBe(true);
|
||
expect(result.decision).toBe("apply_candidate");
|
||
expect(result.reply_source).toBe("mcp_discovery_response_candidate_guarded");
|
||
expect(result.reply_text).toContain("Confirmed fact");
|
||
expect(result.reply_text).not.toContain("query_documents");
|
||
expect(result.reason_codes).toContain("mcp_discovery_response_policy_candidate_applied");
|
||
});
|
||
|
||
it("keeps the current reply when the turn is not an unsupported boundary", () => {
|
||
const result = applyAssistantMcpDiscoveryResponsePolicy({
|
||
currentReply: "regular chat",
|
||
currentReplySource: "llm_chat",
|
||
modeDecisionReason: "living_chat_signal_detected",
|
||
addressRuntimeMeta: {
|
||
mcpDiscoveryRuntimeEntryPoint: entryPoint()
|
||
}
|
||
});
|
||
|
||
expect(result.applied).toBe(false);
|
||
expect(result.decision).toBe("keep_current_reply");
|
||
expect(result.reply_text).toBe("regular chat");
|
||
expect(result.reply_source).toBe("llm_chat");
|
||
expect(result.reason_codes).toContain("mcp_discovery_response_policy_not_unsupported_boundary");
|
||
expect(result.reason_codes).toContain("mcp_discovery_response_policy_not_discovery_ready_chat_candidate");
|
||
});
|
||
|
||
it("applies a guarded candidate for discovery-ready llm chat business answers", () => {
|
||
const result = applyAssistantMcpDiscoveryResponsePolicy({
|
||
currentReply: "stale llm business answer",
|
||
currentReplySource: "llm_chat",
|
||
modeDecisionReason: "non_domain_query_indexed",
|
||
addressRuntimeMeta: {
|
||
mcpDiscoveryRuntimeEntryPoint: entryPoint({
|
||
turn_input: {
|
||
adapter_status: "ready",
|
||
should_run_discovery: true
|
||
}
|
||
})
|
||
}
|
||
});
|
||
|
||
expect(result.applied).toBe(true);
|
||
expect(result.decision).toBe("apply_candidate");
|
||
expect(result.reply_source).toBe("mcp_discovery_response_candidate_guarded");
|
||
expect(result.reply_text).toContain("Confirmed fact");
|
||
expect(result.reason_codes).toContain("mcp_discovery_response_policy_not_unsupported_boundary");
|
||
expect(result.reason_codes).not.toContain("mcp_discovery_response_policy_not_discovery_ready_chat_candidate");
|
||
});
|
||
|
||
it("applies a guarded candidate for discovery-ready deep partial answers", () => {
|
||
const result = applyAssistantMcpDiscoveryResponsePolicy({
|
||
currentReply: "wrong deep partial answer",
|
||
currentReplySource: "deep_analysis",
|
||
addressRuntimeMeta: {
|
||
mcpDiscoveryRuntimeEntryPoint: entryPoint({
|
||
turn_input: {
|
||
adapter_status: "ready",
|
||
should_run_discovery: true
|
||
}
|
||
})
|
||
}
|
||
});
|
||
|
||
expect(result.applied).toBe(true);
|
||
expect(result.reply_source).toBe("mcp_discovery_response_candidate_guarded");
|
||
expect(result.reply_text).toContain("Confirmed fact");
|
||
expect(result.reason_codes).not.toContain("mcp_discovery_response_policy_not_discovery_ready_deep_candidate");
|
||
});
|
||
|
||
it("applies a guarded candidate for discovery-ready address lane answers", () => {
|
||
const result = applyAssistantMcpDiscoveryResponsePolicy({
|
||
currentReply: "stale exact route answer",
|
||
currentReplySource: "address_query_runtime_v1",
|
||
currentReplyType: "factual",
|
||
addressRuntimeMeta: {
|
||
detected_intent: "list_documents_by_counterparty",
|
||
assistant_mcp_discovery_entry_point_v1: entryPoint({
|
||
turn_input: {
|
||
adapter_status: "ready",
|
||
should_run_discovery: true,
|
||
turn_meaning_ref: {
|
||
asked_domain_family: "counterparty_value",
|
||
asked_action_family: "payout"
|
||
}
|
||
}
|
||
})
|
||
}
|
||
});
|
||
|
||
expect(result.applied).toBe(true);
|
||
expect(result.reply_source).toBe("mcp_discovery_response_candidate_guarded");
|
||
expect(result.reply_text).toContain("Confirmed fact");
|
||
expect(result.reason_codes).not.toContain("mcp_discovery_response_policy_not_discovery_ready_address_candidate");
|
||
});
|
||
|
||
it("keeps aligned factual address lane answers when the exact lane already matched the same semantic intent", () => {
|
||
const result = applyAssistantMcpDiscoveryResponsePolicy({
|
||
currentReply: "ИП Калинин Н.М. | сумма: 216600 | операций: 2",
|
||
currentReplySource: "address_query_runtime_v1",
|
||
currentReplyType: "factual",
|
||
addressRuntimeMeta: {
|
||
detected_intent: "customer_revenue_and_payments",
|
||
assistant_mcp_discovery_entry_point_v1: entryPoint({
|
||
turn_input: {
|
||
adapter_status: "ready",
|
||
should_run_discovery: true,
|
||
turn_meaning_ref: {
|
||
asked_domain_family: "counterparty_value",
|
||
asked_action_family: "turnover"
|
||
}
|
||
}
|
||
})
|
||
}
|
||
});
|
||
|
||
expect(result.applied).toBe(false);
|
||
expect(result.decision).toBe("keep_current_reply");
|
||
expect(result.reply_text).toBe("ИП Калинин Н.М. | сумма: 216600 | операций: 2");
|
||
expect(result.reason_codes).toContain("mcp_discovery_response_policy_keep_aligned_factual_address_reply");
|
||
});
|
||
|
||
it("keeps factual address follow-up replies when they already match the continuation target intent", () => {
|
||
const result = applyAssistantMcpDiscoveryResponsePolicy({
|
||
currentReply: "ИП Калинин Н.М. | сумма: 216600 | операций: 2",
|
||
currentReplySource: "address_query_runtime_v1",
|
||
currentReplyType: "factual",
|
||
addressRuntimeMeta: {
|
||
detected_intent: "customer_revenue_and_payments",
|
||
dialogContinuationContract: {
|
||
target_intent: "customer_revenue_and_payments"
|
||
},
|
||
assistant_mcp_discovery_entry_point_v1: entryPoint({
|
||
turn_input: {
|
||
adapter_status: "ready",
|
||
should_run_discovery: true,
|
||
turn_meaning_ref: {
|
||
asked_domain_family: "counterparty_lifecycle",
|
||
asked_action_family: "activity_duration"
|
||
}
|
||
}
|
||
})
|
||
}
|
||
});
|
||
|
||
expect(result.applied).toBe(false);
|
||
expect(result.decision).toBe("keep_current_reply");
|
||
expect(result.reason_codes).toContain("mcp_discovery_response_policy_keep_factual_address_continuation_target");
|
||
});
|
||
|
||
it("keeps full-confirmed factual address replies even when discovery has a guarded candidate", () => {
|
||
const result = applyAssistantMcpDiscoveryResponsePolicy({
|
||
currentReply: "ООО Ромашка | сумма: 128000 | операций: 3",
|
||
currentReplySource: "address_query_runtime_v1",
|
||
currentReplyType: "factual",
|
||
addressRuntimeMeta: {
|
||
detected_intent: "receivables_confirmed_as_of_date",
|
||
truth_gate_contract_status: "full_confirmed",
|
||
assistant_truth_answer_policy_v1: {
|
||
truth_gate: {
|
||
coverage_status: "full",
|
||
grounding_status: "grounded",
|
||
source_truth_gate_status: "full_confirmed"
|
||
}
|
||
},
|
||
assistant_mcp_discovery_entry_point_v1: entryPoint({
|
||
turn_input: {
|
||
adapter_status: "ready",
|
||
should_run_discovery: true,
|
||
turn_meaning_ref: {
|
||
asked_domain_family: "counterparty_value",
|
||
asked_action_family: "turnover"
|
||
}
|
||
}
|
||
})
|
||
}
|
||
});
|
||
|
||
expect(result.applied).toBe(false);
|
||
expect(result.decision).toBe("keep_current_reply");
|
||
expect(result.reply_text).toBe("ООО Ромашка | сумма: 128000 | операций: 3");
|
||
expect(result.reason_codes).toContain("mcp_discovery_response_policy_keep_full_confirmed_factual_address_reply");
|
||
});
|
||
|
||
it("keeps address lane answers when discovery was not requested for the current turn", () => {
|
||
const result = applyAssistantMcpDiscoveryResponsePolicy({
|
||
currentReply: "supported exact route answer",
|
||
currentReplySource: "address_query_runtime_v1",
|
||
addressRuntimeMeta: {
|
||
assistant_mcp_discovery_entry_point_v1: entryPoint({
|
||
turn_input: {
|
||
adapter_status: "not_applicable",
|
||
should_run_discovery: false
|
||
}
|
||
})
|
||
}
|
||
});
|
||
|
||
expect(result.applied).toBe(false);
|
||
expect(result.reply_text).toBe("supported exact route answer");
|
||
expect(result.reason_codes).toContain("mcp_discovery_response_policy_not_discovery_ready_address_candidate");
|
||
});
|
||
|
||
it("keeps the current reply when the candidate has no grounded text", () => {
|
||
const result = applyAssistantMcpDiscoveryResponsePolicy({
|
||
currentReply: "route is not wired",
|
||
currentReplySource: "deterministic_unsupported_current_turn_boundary",
|
||
modeDecisionReason: "unsupported_current_turn_meaning_boundary",
|
||
addressRuntimeMeta: {
|
||
mcpDiscoveryRuntimeEntryPoint: entryPoint({
|
||
bridge: {
|
||
bridge_status: "unsupported",
|
||
user_facing_response_allowed: true,
|
||
business_fact_answer_allowed: false,
|
||
requires_user_clarification: false,
|
||
answer_draft: null
|
||
}
|
||
})
|
||
}
|
||
});
|
||
|
||
expect(result.applied).toBe(false);
|
||
expect(result.reply_text).toBe("route is not wired");
|
||
expect(result.reason_codes).toContain("mcp_discovery_response_policy_candidate_not_eligible");
|
||
expect(result.reason_codes).toContain("mcp_discovery_response_policy_kept_current_reply");
|
||
});
|
||
});
|