Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions memanto/memory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from dataclasses import dataclass, field
from datetime import datetime
from typing import Dict, Optional, Union

@dataclass
class MemoryRecord:
"""
A structured memory record with content, metadata, provenance, and timestamps.
"""
content: str
metadata: Dict[str, Union[str, int, float, bool]] = field(default_factory=dict)
provenance: str = "explicit_statement" # Default provenance
created_at: datetime = field(default_factory=datetime.now)
updated_at: datetime = field(default_factory=datetime.now)

def update(self, content: Optional[str] = None, metadata: Optional[Dict] = None, provenance: Optional[str] = None):
"""
Update the memory record, preserving existing metadata and provenance unless explicitly changed.
"""
if content is not None:
self.content = content
if metadata is not None:
self.metadata.update(metadata)
if provenance is not None:
self.provenance = provenance
self.updated_at = datetime.now()
17 changes: 17 additions & 0 deletions memanto/storage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from typing import Dict, Optional, Union
from .memory import MemoryRecord

class MemoryStorage:
def __init__(self):
self.memories: Dict[str, MemoryRecord] = {}

def update_memory(self, memory_id: str, content: Optional[str] = None, metadata: Optional[Dict] = None, provenance: Optional[str] = None) -> MemoryRecord:
"""
Update an existing memory, preserving existing metadata and provenance unless explicitly changed.
"""
if memory_id not in self.memories:
raise ValueError(f"Memory with ID {memory_id} not found")

memory = self.memories[memory_id]
memory.update(content, metadata, provenance)
return memory
45 changes: 45 additions & 0 deletions tests/test_memory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import unittest
from datetime import datetime
from memanto.memory import MemoryRecord

class TestMemoryRecord(unittest.TestCase):
def test_update_preserves_provenance(self):
"""
Test that updating a memory preserves the original provenance unless explicitly changed.
"""
original_provenance = "validated"
memory = MemoryRecord(
content="Original content",
metadata={"key": "value"},
provenance=original_provenance
)

# Update with new content and metadata, but no provenance change
memory.update(
content="Updated content",
metadata={"new_key": "new_value"}
)

# Verify provenance is preserved
self.assertEqual(memory.provenance, original_provenance)
self.assertEqual(memory.content, "Updated content")
self.assertIn("key", memory.metadata)
self.assertIn("new_key", memory.metadata)

def test_update_changes_provenance(self):
"""
Test that updating a memory with a new provenance changes the provenance.
"""
original_provenance = "validated"
memory = MemoryRecord(
content="Original content",
metadata={"key": "value"},
provenance=original_provenance
)

# Update with new provenance
new_provenance = "corrected"
memory.update(provenance=new_provenance)

# Verify provenance is updated
self.assertEqual(memory.provenance, new_provenance)
44 changes: 44 additions & 0 deletions tests/test_storage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import unittest
from memanto.storage import MemoryStorage
from memanto.memory import MemoryRecord

class TestMemoryStorage(unittest.TestCase):
def setUp(self):
self.storage = MemoryStorage()
self.memory_id = "test_memory"
self.original_provenance = "validated"
self.memory = MemoryRecord(
content="Original content",
metadata={"key": "value"},
provenance=self.original_provenance
)
self.storage.memories[self.memory_id] = self.memory

def test_update_memory_preserves_provenance(self):
"""
Test that updating a memory through the storage preserves the original provenance unless explicitly changed.
"""
updated_memory = self.storage.update_memory(
memory_id=self.memory_id,
content="Updated content",
metadata={"new_key": "new_value"}
)

# Verify provenance is preserved
self.assertEqual(updated_memory.provenance, self.original_provenance)
self.assertEqual(updated_memory.content, "Updated content")
self.assertIn("key", updated_memory.metadata)
self.assertIn("new_key", updated_memory.metadata)

def test_update_memory_changes_provenance(self):
"""
Test that updating a memory through the storage with a new provenance changes the provenance.
"""
new_provenance = "corrected"
updated_memory = self.storage.update_memory(
memory_id=self.memory_id,
provenance=new_provenance
)

# Verify provenance is updated
self.assertEqual(updated_memory.provenance, new_provenance)
Loading