ARCH: подключить MCP discovery к runtime meta

This commit is contained in:
2026-04-20 11:54:04 +03:00
parent de4e064885
commit f0d7e81ec0
4 changed files with 171 additions and 4 deletions
@@ -76,11 +76,98 @@ describe("assistant address orchestration runtime adapter", () => {
expect(output.addressRuntimeMeta.dialogContinuationContract).toEqual({
schema_version: "address_dialog_continuation_contract_v2"
});
expect(output.addressRuntimeMeta.mcpDiscoveryRuntimeEntryPoint).toEqual(
expect.objectContaining({
schema_version: "assistant_mcp_discovery_runtime_entry_point_v1",
entry_status: "skipped_not_applicable",
hot_runtime_wired: false
})
);
expect(input.__spies.runAddressLlmPreDecompose).toHaveBeenCalledTimes(1);
expect(input.__spies.resolveAddressFollowupCarryoverContext).toHaveBeenCalledTimes(1);
expect(input.__spies.resolveAssistantOrchestrationDecision).toHaveBeenCalledTimes(1);
});
it("runs MCP discovery entry point from real orchestration context without changing the route decision", async () => {
const runMcpDiscoveryRuntimeEntryPoint = vi.fn(async () => ({
schema_version: "assistant_mcp_discovery_runtime_entry_point_v1",
policy_owner: "assistantMcpDiscoveryRuntimeEntryPoint",
entry_status: "bridge_executed",
hot_runtime_wired: false,
discovery_attempted: true
}));
const input = buildInput({
userMessage: "Сколько лет мы работаем с Группа СВК?",
runAddressLlmPreDecompose: vi.fn(async () => ({
attempted: true,
applied: false,
effectiveMessage: "Сколько лет мы работаем с Группа СВК?",
reason: "raw_kept",
predecomposeContract: {
entities: { counterparty: "Группа СВК" },
period: {}
}
})),
resolveAssistantOrchestrationDecision: vi.fn(() => ({
runAddressLane: false,
livingMode: "chat",
livingReason: "unsupported_current_turn_meaning_boundary",
toolGateDecision: "skip_address_lane",
toolGateReason: "unsupported_current_turn_meaning_boundary",
orchestrationContract: {
schema_version: "assistant_orchestration_contract_v1",
assistant_turn_meaning: {
schema_version: "assistant_turn_meaning_v1",
asked_domain_family: "counterparty",
asked_action_family: "counterparty_lifecycle",
unsupported_but_understood_family: "counterparty_lifecycle"
}
}
})),
runMcpDiscoveryRuntimeEntryPoint
});
const output = await buildAssistantAddressOrchestrationRuntime(input);
expect(output.livingModeDecision).toEqual({
mode: "chat",
reason: "unsupported_current_turn_meaning_boundary"
});
expect(output.addressRuntimeMeta.mcpDiscoveryRuntimeEntryPoint).toEqual(
expect.objectContaining({
entry_status: "bridge_executed",
discovery_attempted: true,
hot_runtime_wired: false
})
);
expect(runMcpDiscoveryRuntimeEntryPoint).toHaveBeenCalledWith(
expect.objectContaining({
userMessage: "Сколько лет мы работаем с Группа СВК?",
effectiveMessage: "Сколько лет мы работаем с Группа СВК?",
assistantTurnMeaning: expect.objectContaining({
unsupported_but_understood_family: "counterparty_lifecycle"
}),
predecomposeContract: expect.objectContaining({
entities: { counterparty: "Группа СВК" }
})
})
);
});
it("keeps address orchestration alive when MCP discovery entry point fails", async () => {
const input = buildInput({
runMcpDiscoveryRuntimeEntryPoint: vi.fn(async () => {
throw new Error("discovery transport failed");
})
});
const output = await buildAssistantAddressOrchestrationRuntime(input);
expect(output.orchestrationDecision.runAddressLane).toBe(true);
expect(output.addressRuntimeMeta.mcpDiscoveryRuntimeEntryPoint).toBeNull();
expect(output.addressRuntimeMeta.mcpDiscoveryRuntimeEntryPointError).toBe("discovery transport failed");
});
it("builds deterministic fallback predecompose payload when feature is disabled", async () => {
const input = buildInput({
featureAddressLlmPredecomposeV1: false,