Question / suspected regression
Should a registered custom relationship type still be checked against edge_type_map before persistence, or is that mapping now intentionally only an extraction/attribute-schema hint?
At commit 9debb86a5523a3d702252090d39751f04a9b830d (0.30.1), a registered MAKES relationship with Product -> Company endpoints survives resolve_extracted_edges even when the only allowed signature is Company -> Product. This is not a request to prohibit newly discovered, unregistered relationship names.
History
I understand avoiding a second LLM classification. Is removing the deterministic signature check also intended? The custom-types documentation still describes endpoint constraints and generic relationships for unmatched pairs. Related broader question: #1789.
Offline reproduction
This invokes the real resolution function with synthetic nodes and an intentionally reversed extraction. Database/search/embedding calls are mocked; no LLM call, credentials, or database are needed. It is a function-level reproduction, not an end-to-end model benchmark.
import asyncio
from datetime import datetime, timezone
from types import SimpleNamespace
from unittest.mock import AsyncMock, patch
from pydantic import BaseModel
from graphiti_core.edges import EntityEdge
from graphiti_core.nodes import EntityNode, EpisodeType, EpisodicNode
from graphiti_core.search.search_config import SearchResults
from graphiti_core.utils.maintenance import edge_operations as ops
class Makes(BaseModel):
"""A Company makes a Product."""
async def main():
company = EntityNode(name="ExampleCo", group_id="repro", labels=["Company"])
product = EntityNode(name="ExampleApp", group_id="repro", labels=["Product"])
episode = EpisodicNode(
name="example", group_id="repro", source=EpisodeType.text,
source_description="synthetic reproduction", content="ExampleCo makes ExampleApp.",
valid_at=datetime.now(timezone.utc),
)
edge = EntityEdge(
source_node_uuid=product.uuid, target_node_uuid=company.uuid,
name="MAKES", fact="ExampleApp makes ExampleCo.", group_id="repro",
valid_at=episode.valid_at, created_at=episode.valid_at,
)
clients = SimpleNamespace(driver=object(), embedder=object(), llm_client=object())
with (
patch.object(ops, "create_entity_edge_embeddings", AsyncMock()),
patch.object(EntityEdge, "get_between_nodes", AsyncMock(return_value=[])),
patch.object(ops, "search", AsyncMock(return_value=SearchResults())),
):
resolved, _, _ = await ops.resolve_extracted_edges(
clients, [edge], episode, [company, product],
{"MAKES": Makes}, {("Company", "Product"): ["MAKES"]},
)
print([(item.name, item.source_node_uuid == product.uuid,
item.target_node_uuid == company.uuid) for item in resolved])
asyncio.run(main())
Observed (Python 3.10): [('MAKES', True, True)].
Expected under the policy in #950: this edge must not retain the registered MAKES name with disallowed endpoints; the historical behavior was generic RELATES_TO, not dropping the fact or failing ingestion.
If the current behavior is intentional, is there a supported strict-validation hook or option we should use? If it is a regression, would restoring the narrow registered-type check be appropriate?
Question / suspected regression
Should a registered custom relationship type still be checked against
edge_type_mapbefore persistence, or is that mapping now intentionally only an extraction/attribute-schema hint?At commit
9debb86a5523a3d702252090d39751f04a9b830d(0.30.1), a registeredMAKESrelationship with Product -> Company endpoints survivesresolve_extracted_edgeseven when the only allowed signature is Company -> Product. This is not a request to prohibit newly discovered, unregistered relationship names.History
RELATES_TO.c36723c71337c0c12788f0d558bb93dd015af476).I understand avoiding a second LLM classification. Is removing the deterministic signature check also intended? The custom-types documentation still describes endpoint constraints and generic relationships for unmatched pairs. Related broader question: #1789.
Offline reproduction
This invokes the real resolution function with synthetic nodes and an intentionally reversed extraction. Database/search/embedding calls are mocked; no LLM call, credentials, or database are needed. It is a function-level reproduction, not an end-to-end model benchmark.
Observed (Python 3.10):
[('MAKES', True, True)].Expected under the policy in #950: this edge must not retain the registered
MAKESname with disallowed endpoints; the historical behavior was genericRELATES_TO, not dropping the fact or failing ingestion.If the current behavior is intentional, is there a supported strict-validation hook or option we should use? If it is a regression, would restoring the narrow registered-type check be appropriate?