Files
basicmachines-co-basic-memory/src/basic_memory/schemas/memory.py
T
Paul Hernandez 37a01b806d feat: Incremental sync on watch (#13)
- incremental sync on watch
- sync non-markdown files in knowledge base
- experimental `read_resource` tool for reading non-markdown files in raw form (pdf, image)
2025-02-24 22:13:15 -06:00

120 lines
2.9 KiB
Python

"""Schemas for memory context."""
from datetime import datetime
from typing import List, Optional, Annotated, Sequence
from annotated_types import MinLen, MaxLen
from pydantic import BaseModel, Field, BeforeValidator, TypeAdapter
from basic_memory.schemas.search import SearchItemType
def normalize_memory_url(url: str | None) -> str:
"""Normalize a MemoryUrl string.
Args:
url: A path like "specs/search" or "memory://specs/search"
Returns:
Normalized URL starting with memory://
Examples:
>>> normalize_memory_url("specs/search")
'memory://specs/search'
>>> normalize_memory_url("memory://specs/search")
'memory://specs/search'
"""
if not url:
return ""
clean_path = url.removeprefix("memory://")
return f"memory://{clean_path}"
MemoryUrl = Annotated[
str,
BeforeValidator(str.strip), # Clean whitespace
MinLen(1),
MaxLen(2028),
]
memory_url = TypeAdapter(MemoryUrl)
def memory_url_path(url: memory_url) -> str: # pyright: ignore
"""
Returns the uri for a url value by removing the prefix "memory://" from a given MemoryUrl.
This function processes a given MemoryUrl by removing the "memory://"
prefix and returns the resulting string. If the provided url does not
begin with "memory://", the function will simply return the input url
unchanged.
:param url: A MemoryUrl object representing the URL with a "memory://" prefix.
:type url: MemoryUrl
:return: A string representing the URL with the "memory://" prefix removed.
:rtype: str
"""
return url.removeprefix("memory://")
class EntitySummary(BaseModel):
"""Simplified entity representation."""
type: str = "entity"
permalink: Optional[str]
title: str
file_path: str
created_at: datetime
class RelationSummary(BaseModel):
"""Simplified relation representation."""
type: str = "relation"
permalink: str
relation_type: str
from_id: str
to_id: Optional[str] = None
class ObservationSummary(BaseModel):
"""Simplified observation representation."""
type: str = "observation"
permalink: str
category: str
content: str
class MemoryMetadata(BaseModel):
"""Simplified response metadata."""
uri: Optional[str] = None
types: Optional[List[SearchItemType]] = None
depth: int
timeframe: str
generated_at: datetime
total_results: int
total_relations: int
class GraphContext(BaseModel):
"""Complete context response."""
# Direct matches
primary_results: Sequence[EntitySummary | RelationSummary | ObservationSummary] = Field(
description="results directly matching URI"
)
# Related entities
related_results: Sequence[EntitySummary | RelationSummary | ObservationSummary] = Field(
description="related results"
)
# Context metadata
metadata: MemoryMetadata
page: int = 1
page_size: int = 1