Harden MCP article and weight workflows
This commit is contained in:
@@ -5,9 +5,15 @@ import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import mcp_server
|
||||
from roll_calculation import ArticleRepository, calculate_roll, get_article
|
||||
from roll_calculation import (
|
||||
ArticleRepository,
|
||||
calculate_material_weight,
|
||||
calculate_roll,
|
||||
get_article,
|
||||
)
|
||||
from rollcalc_mcp_tools import (
|
||||
analyze_transport_capacity_result,
|
||||
calculate_material_weight_result,
|
||||
calculate_roll_diameter_result,
|
||||
get_article_result,
|
||||
search_articles_result,
|
||||
@@ -68,6 +74,19 @@ class McpAdapterTests(unittest.TestCase):
|
||||
"candidates": [],
|
||||
})
|
||||
|
||||
def test_material_weight_adapter_delegates_without_a_core_diameter(self):
|
||||
arguments = {
|
||||
"roll_length_m": 60.0,
|
||||
"width_m": 5.0,
|
||||
"area_weight_g_m2": 4850.079676,
|
||||
}
|
||||
|
||||
result = calculate_material_weight_result(**arguments)
|
||||
|
||||
self.assertEqual(result, calculate_material_weight(**arguments))
|
||||
self.assertEqual(result["weight_scope"], "material_only")
|
||||
self.assertAlmostEqual(result["material_weight_kg"], 1455.0239028)
|
||||
|
||||
def test_calculate_roll_diameter_delegates_for_normal_weighted_and_invalid_cases(self):
|
||||
for arguments in (
|
||||
{
|
||||
@@ -158,6 +177,7 @@ class McpAdapterTests(unittest.TestCase):
|
||||
[
|
||||
"get_article",
|
||||
"search_articles",
|
||||
"calculate_material_weight",
|
||||
"calculate_roll_diameter",
|
||||
"analyze_transport_capacity",
|
||||
],
|
||||
@@ -167,6 +187,7 @@ class McpAdapterTests(unittest.TestCase):
|
||||
instance = mcp_server.create_server()
|
||||
tools = instance._tool_manager._tools
|
||||
search_tool = tools["search_articles"]
|
||||
material_weight_tool = tools["calculate_material_weight"]
|
||||
roll_schema = tools["calculate_roll_diameter"].parameters
|
||||
transport_tool = tools["analyze_transport_capacity"]
|
||||
transport_schema = transport_tool.parameters
|
||||
@@ -175,6 +196,12 @@ class McpAdapterTests(unittest.TestCase):
|
||||
self.assertEqual(
|
||||
search_tool.parameters["properties"]["query"]["type"], "string"
|
||||
)
|
||||
material_weight_schema = material_weight_tool.parameters
|
||||
self.assertEqual(
|
||||
material_weight_schema["required"],
|
||||
["roll_length_m", "width_m", "area_weight_g_m2"],
|
||||
)
|
||||
self.assertNotIn("core_diameter_mm", material_weight_schema["properties"])
|
||||
|
||||
self.assertNotIn("include_roll_weight", roll_schema["properties"])
|
||||
preset_schema = transport_schema["properties"]["transport_preset"]
|
||||
@@ -235,10 +262,11 @@ class McpAdapterTests(unittest.TestCase):
|
||||
for text in (
|
||||
"name, family, designation, or descriptive article text",
|
||||
"Do not guess or invent an article number",
|
||||
"deterministic candidates from the RollCalc article master data",
|
||||
"deterministic retrieval candidates from the RollCalc article master data",
|
||||
"not product recommendations",
|
||||
"total_matches is exactly 1",
|
||||
"use that candidate's exact article_number",
|
||||
"do NOT select the first or highest-ranked candidate",
|
||||
"do NOT select the first or highest-ranked candidate, do not treat ranking as permission to choose",
|
||||
"ask the user which article number is intended",
|
||||
"do not calculate yet",
|
||||
"no matching RollCalc article was found",
|
||||
@@ -246,11 +274,26 @@ class McpAdapterTests(unittest.TestCase):
|
||||
"do not invent an article",
|
||||
"production_site=Malaysia is descriptive metadata only",
|
||||
"does not imply Bentofix, Bento 2, or any production machine",
|
||||
"Ranking/order expresses relevance only",
|
||||
"Ranking/order expresses retrieval relevance only",
|
||||
"get_article -> calculate_roll_diameter -> optionally analyze_transport_capacity",
|
||||
):
|
||||
self.assertIn(text, search_description)
|
||||
|
||||
material_weight_description = material_weight_tool.description
|
||||
for text in (
|
||||
"material-only roll weight",
|
||||
"does not require, accept, infer, or default a core diameter",
|
||||
"never invent a standard core",
|
||||
"excludes any core weight",
|
||||
"cannot provide roll diameter or a core-inclusive total weight",
|
||||
):
|
||||
self.assertIn(text, material_weight_description)
|
||||
|
||||
roll_description = tools["calculate_roll_diameter"].description
|
||||
self.assertIn("requires a known positive core diameter", roll_description)
|
||||
self.assertIn("do not infer or default one", roll_description)
|
||||
self.assertIn("call calculate_material_weight instead", roll_description)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user