diff --git a/semantica/mcp_server/__init__.py b/semantica/mcp_server/__init__.py index 6953ac45..8e200b53 100644 --- a/semantica/mcp_server/__init__.py +++ b/semantica/mcp_server/__init__.py @@ -127,13 +127,16 @@ def _tool_extract_relations(args: dict) -> dict: text = args.get("text", "") if not text: return {"error": "text is required"} - from semantica.semantic_extract import RelationExtractor, TripletExtractor + from semantica.semantic_extract import NamedEntityRecognizer, RelationExtractor, TripletExtractor rel_kwargs = {} + ner_kwargs = {} for k in ("model", "language"): if args.get(k) is not None: rel_kwargs[k] = args[k] + ner_kwargs[k] = args[k] method = args.get("method", "pattern") - relations = RelationExtractor(method=method, **rel_kwargs).extract_relations(text) + entities = NamedEntityRecognizer(methods=["ml"], **ner_kwargs).extract_entities(text) or [] + relations = RelationExtractor(method=method, **rel_kwargs).extract_relations(text, entities) triplets = TripletExtractor().extract_triplets(text) return { "relations": [ diff --git a/tests/context/test_decision_persistence_pr967.py b/tests/context/test_decision_persistence_pr967.py index 5636030f..02e08c2d 100644 --- a/tests/context/test_decision_persistence_pr967.py +++ b/tests/context/test_decision_persistence_pr967.py @@ -877,6 +877,22 @@ class TestEntityExtractionSurfaceText(unittest.TestCase): result = _tool_extract_relations({}) self.assertIn("error", result) + def test_extract_relations_with_text_does_not_raise(self): + """extract_relations must not raise TypeError for missing `entities` + (RelationExtractor.extract_relations requires an `entities` arg; + the tool must supply one, e.g. by running NER first).""" + from semantica.mcp_server import _tool_extract_relations + + try: + result = _tool_extract_relations({"text": "Apple announced new iPhone"}) + except Exception as exc: + self.fail(f"extract_relations raised unexpectedly: {exc!r}") + + self.assertNotIn("error", result, + "extract_relations should not error on valid text input") + self.assertIn("relations", result) + self.assertIn("triplets", result) + # --------------------------------------------------------------------------- # Part 13: query_graph node / search modes