ARCH: добавить runtime bridge MCP discovery
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { runAssistantMcpDiscoveryRuntimeBridge } from "../src/services/assistantMcpDiscoveryRuntimeBridge";
|
||||
|
||||
function buildDeps(rows: Array<Record<string, unknown>>, error: string | null = null) {
|
||||
return {
|
||||
executeAddressMcpQuery: vi.fn(async () => ({
|
||||
fetched_rows: rows.length,
|
||||
matched_rows: error ? 0 : rows.length,
|
||||
raw_rows: rows,
|
||||
rows: error ? [] : rows,
|
||||
error
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
describe("assistant MCP discovery runtime bridge", () => {
|
||||
it("composes planner, pilot executor, and answer draft without wiring the hot runtime", async () => {
|
||||
const result = await runAssistantMcpDiscoveryRuntimeBridge({
|
||||
turnMeaning: {
|
||||
asked_domain_family: "counterparty_lifecycle",
|
||||
asked_action_family: "activity_duration",
|
||||
explicit_entity_candidates: ["SVK"]
|
||||
},
|
||||
deps: buildDeps([{ Период: "2020-01-15T00:00:00", Регистратор: "CP_CUSTOMER_ACTIVITY_FIRST" }])
|
||||
});
|
||||
|
||||
expect(result.schema_version).toBe("assistant_mcp_discovery_runtime_bridge_v1");
|
||||
expect(result.bridge_status).toBe("answer_draft_ready");
|
||||
expect(result.hot_runtime_wired).toBe(false);
|
||||
expect(result.pilot.mcp_execution_performed).toBe(true);
|
||||
expect(result.answer_draft.answer_mode).toBe("confirmed_with_bounded_inference");
|
||||
expect(result.business_fact_answer_allowed).toBe(true);
|
||||
expect(result.user_facing_response_allowed).toBe(true);
|
||||
expect(result.reason_codes).toContain("runtime_bridge_not_wired_to_hot_assistant_answer");
|
||||
});
|
||||
|
||||
it("keeps missing scope as clarification and does not authorize a business fact answer", async () => {
|
||||
const result = await runAssistantMcpDiscoveryRuntimeBridge({
|
||||
turnMeaning: {
|
||||
asked_domain_family: "counterparty_value",
|
||||
asked_action_family: "turnover",
|
||||
explicit_entity_candidates: ["SVK"]
|
||||
},
|
||||
deps: buildDeps([])
|
||||
});
|
||||
|
||||
expect(result.bridge_status).toBe("needs_clarification");
|
||||
expect(result.requires_user_clarification).toBe(true);
|
||||
expect(result.pilot.mcp_execution_performed).toBe(false);
|
||||
expect(result.business_fact_answer_allowed).toBe(false);
|
||||
expect(result.answer_draft.next_step_line).toContain("Уточните контрагента");
|
||||
});
|
||||
|
||||
it("keeps unsupported ready plans outside the hot answer path", async () => {
|
||||
const result = await runAssistantMcpDiscoveryRuntimeBridge({
|
||||
turnMeaning: {
|
||||
asked_domain_family: "document",
|
||||
asked_action_family: "documents",
|
||||
explicit_entity_candidates: ["SVK"]
|
||||
},
|
||||
deps: buildDeps([])
|
||||
});
|
||||
|
||||
expect(result.bridge_status).toBe("unsupported");
|
||||
expect(result.hot_runtime_wired).toBe(false);
|
||||
expect(result.pilot.mcp_execution_performed).toBe(false);
|
||||
expect(result.business_fact_answer_allowed).toBe(false);
|
||||
expect(result.reason_codes).toContain("runtime_bridge_status_unsupported");
|
||||
});
|
||||
|
||||
it("preserves the answer adapter boundary against internal mechanics leakage", async () => {
|
||||
const result = await runAssistantMcpDiscoveryRuntimeBridge({
|
||||
turnMeaning: {
|
||||
asked_domain_family: "counterparty_lifecycle",
|
||||
asked_action_family: "activity_duration",
|
||||
explicit_entity_candidates: ["SVK"]
|
||||
},
|
||||
deps: buildDeps([{ Период: "2020-01-15T00:00:00", Регистратор: "CP_CUSTOMER_ACTIVITY_FIRST" }])
|
||||
});
|
||||
const userFacing = [
|
||||
result.answer_draft.headline,
|
||||
...result.answer_draft.confirmed_lines,
|
||||
...result.answer_draft.inference_lines,
|
||||
...result.answer_draft.unknown_lines,
|
||||
...result.answer_draft.limitation_lines,
|
||||
result.answer_draft.next_step_line ?? ""
|
||||
].join("\n");
|
||||
|
||||
expect(userFacing).not.toContain("query_documents");
|
||||
expect(userFacing).not.toContain("runtime_bridge");
|
||||
expect(userFacing).not.toContain("primitive");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user