set permalink in frontmatter, re-index file_path on move during sync

This commit is contained in:
phernandez
2025-01-22 17:59:46 -06:00
parent bd1d91081e
commit 23922f2915
5 changed files with 76 additions and 28 deletions
+31 -23
View File
@@ -1,14 +1,16 @@
"""Writer for knowledge entity markdown files."""
from typing import Optional
from loguru import logger
from basic_memory.markdown import EntityFrontmatter
from basic_memory.models import Entity as EntityModel, Observation
class KnowledgeWriter:
"""Formats entities into markdown files.
Content handling:
1. If raw content is provided, use it directly
2. If structured data exists (observations/relations), generate structured content
@@ -18,7 +20,7 @@ class KnowledgeWriter:
async def format_frontmatter(self, entity: EntityModel) -> dict:
"""Generate frontmatter metadata for entity."""
frontmatter = {
"id": entity.permalink,
"permalink": entity.permalink,
"type": entity.entity_type,
"created": entity.created_at.isoformat(),
"modified": entity.updated_at.isoformat(),
@@ -35,19 +37,19 @@ class KnowledgeWriter:
if obs.tags:
line += " " + " ".join(f"#{tag}" for tag in sorted(obs.tags))
# Add context if present
# Add context if present
if obs.context:
line += f" ({obs.context})"
return line
async def format_content(self, entity: EntityModel, content: Optional[str] = None) -> str:
"""Format entity content as markdown.
Args:
entity: Entity to format
content: Optional raw content to use instead of generating structured content
Returns:
Formatted markdown content
"""
@@ -58,25 +60,29 @@ class KnowledgeWriter:
# Otherwise, build structured content from entity data
sections = []
# Only add entity title if we don't have structured content
# This prevents duplicate titles when raw content already has a title
if not (entity.observations or entity.outgoing_relations):
sections.extend([
f"# {entity.title}",
"", # Empty line after title
])
sections.extend(
[
f"# {entity.title}",
"", # Empty line after title
]
)
if entity.summary:
sections.extend([entity.summary, ""])
# Add observations if present
if entity.observations:
sections.extend([
"## Observations",
"<!-- Format: - [category] Content text #tag1 #tag2 (optional context) -->",
"",
])
sections.extend(
[
"## Observations",
"<!-- Format: - [category] Content text #tag1 #tag2 (optional context) -->",
"",
]
)
for obs in entity.observations:
sections.append(await self.format_observation(obs))
@@ -84,12 +90,14 @@ class KnowledgeWriter:
# Add relations if present
if entity.outgoing_relations:
sections.extend([
"## Relations",
"<!-- Format: - relation_type [[Entity]] (context) -->",
"", # Empty line after format comment
])
sections.extend(
[
"## Relations",
"<!-- Format: - relation_type [[Entity]] (context) -->",
"", # Empty line after format comment
]
)
for rel in entity.outgoing_relations:
line = f"- {rel.relation_type} [[{rel.to_entity.title}]]"
if rel.context:
+3 -1
View File
@@ -69,9 +69,11 @@ class SyncService:
entity = await self.entity_repository.get_by_file_path(old_path)
if entity:
# Update file_path but keep the same permalink for link stability
await self.entity_repository.update(
updated = await self.entity_repository.update(
entity.id, {"file_path": new_path, "checksum": changes.checksums[new_path]}
)
# update search index
await self.search_service.index_entity(updated)
# Handle deletions next
# remove rows from db for files no longer present