Skip to content

Commit 01cbad1

Browse files
committed
Allow long relation_type values in responses
Signed-off-by: phernandez <paul@basicmachines.co>
1 parent a4e0422 commit 01cbad1

File tree

3 files changed

+79
-2
lines changed

3 files changed

+79
-2
lines changed

src/basic_memory/schemas/base.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,13 @@ def validate_timeframe(timeframe: str) -> str:
178178
]
179179

180180

181-
RelationType = Annotated[str, MinLen(1), MaxLen(200)]
182-
"""Type of relationship between entities. Always use active voice present tense."""
181+
RelationType = Annotated[str, MinLen(1)]
182+
"""Type of relationship between entities. Always use active voice present tense.
183+
184+
The database stores relation_type as an unrestricted string, and response models
185+
need to tolerate existing long-form values written by LLMs. Keeping an API-only
186+
200-character cap here causes reads to fail for valid stored data.
187+
"""
183188

184189
ObservationStr = Annotated[
185190
str,

tests/api/v2/test_knowledge_router.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,58 @@ async def test_get_entity_by_id(client: AsyncClient, test_graph, v2_project_url,
137137
assert entity.api_version == "v2"
138138

139139

140+
@pytest.mark.asyncio
141+
async def test_get_entity_by_id_allows_long_relation_type(
142+
client: AsyncClient,
143+
v2_project_url,
144+
relation_repository,
145+
):
146+
"""GET entity should not fail when stored relation_type exceeds 200 characters."""
147+
source_response = await client.post(
148+
f"{v2_project_url}/knowledge/entities",
149+
json={
150+
"title": "Long Relation Source",
151+
"directory": "test",
152+
"content": "Source entity content",
153+
},
154+
)
155+
assert source_response.status_code == 200
156+
source_entity = EntityResponseV2.model_validate(source_response.json())
157+
158+
target_response = await client.post(
159+
f"{v2_project_url}/knowledge/entities",
160+
json={
161+
"title": "Long Relation Target",
162+
"directory": "test",
163+
"content": "Target entity content",
164+
},
165+
)
166+
assert target_response.status_code == 200
167+
target_entity = EntityResponseV2.model_validate(target_response.json())
168+
169+
long_relation_type = (
170+
"**Architecture/efficiency concern:** "
171+
"the orchestration prompt expanded a short edge label into a full descriptive note "
172+
"that is much longer than 200 characters but should still serialize cleanly."
173+
)
174+
175+
await relation_repository.create(
176+
{
177+
"from_id": source_entity.id,
178+
"to_id": target_entity.id,
179+
"to_name": target_entity.title,
180+
"relation_type": long_relation_type,
181+
}
182+
)
183+
184+
response = await client.get(f"{v2_project_url}/knowledge/entities/{source_entity.external_id}")
185+
186+
assert response.status_code == 200
187+
entity = EntityResponseV2.model_validate(response.json())
188+
assert len(entity.relations) == 1
189+
assert entity.relations[0].relation_type == long_relation_type
190+
191+
140192
@pytest.mark.asyncio
141193
async def test_get_entity_by_id_not_found(client: AsyncClient, v2_project_url):
142194
"""Test getting a non-existent entity by external_id returns 404."""

tests/schemas/test_schemas.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,26 @@ def test_relation_response():
9191
assert relation.context is None
9292

9393

94+
def test_relation_response_allows_long_relation_type():
95+
"""Long relation labels should round-trip because stored data has no DB length cap."""
96+
long_relation_type = (
97+
"**Architecture/efficiency concern:** "
98+
"the orchestration prompt expanded a short edge label into a full descriptive note "
99+
"that is much longer than 200 characters but still represents the stored relation type."
100+
)
101+
data = {
102+
"permalink": "test/123/long/test/456",
103+
"from_id": "test/123",
104+
"to_id": "test/456",
105+
"relation_type": long_relation_type,
106+
"from_entity": {"permalink": "test/123"},
107+
"to_entity": {"permalink": "test/456"},
108+
}
109+
110+
relation = RelationResponse.model_validate(data)
111+
assert relation.relation_type == long_relation_type
112+
113+
94114
def test_relation_response_with_null_permalink():
95115
"""Test RelationResponse handles null permalinks by falling back to file_path (fixes issue #483).
96116

0 commit comments

Comments
 (0)