From 84ccc7c0e3fb1c02beca0083ae5d092d3d8dcb30 Mon Sep 17 00:00:00 2001 From: KaifAhmad1 Date: Wed, 26 Aug 2026 15:30:26 +0530 Subject: [PATCH] fix(mcp): extract_relations tool crashes with missing entities arg RelationExtractor.extract_relations(text, entities, ...) requires entities, but the tool called it with only text, raising TypeError on every invocation. Run NER first and pass the resulting entities through, matching how the rest of the pipeline extracts relations. --- semantica/mcp_server/__init__.py | 7 +++++-- tests/context/test_decision_persistence_pr967.py | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) 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