Add Themis application with custom widgets, views, and utilities

- Implemented custom form widgets for date, time, and datetime fields with DaisyUI styling.
- Created utility functions for formatting dates, times, and numbers according to user preferences.
- Developed views for profile settings, API key management, and notifications, including health check endpoints.
- Added URL configurations for Themis tests and main application routes.
- Established test cases for custom widgets to ensure proper functionality and integration.
- Defined project metadata and dependencies in pyproject.toml for package management.
This commit is contained in:
2026-03-21 02:00:18 +00:00
parent e99346d014
commit 99bdb4ac92
351 changed files with 65123 additions and 2 deletions

251
mnemosyne/library/models.py Normal file
View File

@@ -0,0 +1,251 @@
"""
Neo4j graph models for the Mnemosyne content library.
All content data (libraries, collections, items, chunks, concepts, images)
lives in Neo4j as a knowledge graph. These models use neomodel's StructuredNode
OGM — they do NOT participate in Django's ORM or migrations.
"""
from neomodel import (
ArrayProperty,
DateTimeProperty,
FloatProperty,
IntegerProperty,
JSONProperty,
RelationshipTo,
StringProperty,
StructuredNode,
StructuredRel,
UniqueIdProperty,
)
# --- Relationship models ---
class ReferencesRel(StructuredRel):
"""Relationship properties for Item -> Concept REFERENCES edges."""
weight = FloatProperty(default=1.0)
context = StringProperty(default="")
class RelatedToRel(StructuredRel):
"""Relationship properties for Item -> Item RELATED_TO edges."""
relationship_type = StringProperty(default="")
weight = FloatProperty(default=1.0)
class NearbyImageRel(StructuredRel):
"""Relationship properties for Chunk -> Image HAS_NEARBY_IMAGE edges."""
proximity = StringProperty(default="same_page") # same_page, inline, same_slide, same_chapter
# --- Node models ---
class Library(StructuredNode):
"""
Top-level container representing a content library.
Each library has a type (fiction, technical, music, film, art, journal)
that drives chunking strategy, embedding instructions, and LLM prompts.
"""
uid = UniqueIdProperty()
name = StringProperty(unique_index=True, required=True)
library_type = StringProperty(
required=True,
choices={
"fiction": "Fiction",
"technical": "Technical",
"music": "Music",
"film": "Film",
"art": "Art",
"journal": "Journal",
},
)
description = StringProperty(default="")
# Content-type configuration
chunking_config = JSONProperty(default={})
embedding_instruction = StringProperty(default="")
reranker_instruction = StringProperty(default="")
llm_context_prompt = StringProperty(default="")
created_at = DateTimeProperty(default_now=True)
# Relationships
collections = RelationshipTo("Collection", "CONTAINS")
def __str__(self):
return f"{self.name} ({self.library_type})"
class Collection(StructuredNode):
"""
A grouping of items within a library.
Examples: a book series, an album discography, a project folder.
"""
uid = UniqueIdProperty()
name = StringProperty(required=True)
description = StringProperty(default="")
metadata = JSONProperty(default={})
created_at = DateTimeProperty(default_now=True)
# Relationships
items = RelationshipTo("Item", "CONTAINS")
library = RelationshipTo("Library", "BELONGS_TO")
def __str__(self):
return self.name
class Item(StructuredNode):
"""
An individual piece of content: a document, song, image set, journal entry, etc.
Items store their original file in S3 (via s3_key) and are chunked
for embedding and retrieval.
"""
uid = UniqueIdProperty()
title = StringProperty(required=True)
item_type = StringProperty(default="")
s3_key = StringProperty(default="")
content_hash = StringProperty(index=True)
file_type = StringProperty(default="")
file_size = IntegerProperty(default=0)
metadata = JSONProperty(default={})
created_at = DateTimeProperty(default_now=True)
updated_at = DateTimeProperty(default_now=True)
# Embedding pipeline fields (Phase 2)
embedding_status = StringProperty(
default="pending",
choices={
"pending": "Pending",
"processing": "Processing",
"completed": "Completed",
"failed": "Failed",
},
)
embedding_model_name = StringProperty(default="")
chunk_count = IntegerProperty(default=0)
image_count = IntegerProperty(default=0)
error_message = StringProperty(default="")
# Relationships
chunks = RelationshipTo("Chunk", "HAS_CHUNK")
images = RelationshipTo("Image", "HAS_IMAGE")
concepts = RelationshipTo("Concept", "REFERENCES", model=ReferencesRel)
related_items = RelationshipTo("Item", "RELATED_TO", model=RelatedToRel)
def __str__(self):
return self.title
class Chunk(StructuredNode):
"""
A text chunk extracted from an Item for embedding and retrieval.
Chunk text is stored in S3; text_preview holds the first 500 chars
for Neo4j full-text indexing.
"""
uid = UniqueIdProperty()
chunk_index = IntegerProperty(required=True)
chunk_s3_key = StringProperty(required=True)
chunk_size = IntegerProperty(default=0)
text_preview = StringProperty(default="") # First 500 chars for full-text index
embedding = ArrayProperty(FloatProperty()) # 4096d vector
created_at = DateTimeProperty(default_now=True)
# Relationships
mentions = RelationshipTo("Concept", "MENTIONS")
nearby_images = RelationshipTo("Image", "HAS_NEARBY_IMAGE", model=NearbyImageRel)
def __str__(self):
return f"Chunk {self.chunk_index} ({self.uid})"
class Concept(StructuredNode):
"""
A named entity or topic extracted from content.
Concepts form the backbone of the knowledge graph, linking items
and chunks through shared references.
"""
uid = UniqueIdProperty()
name = StringProperty(unique_index=True, required=True)
concept_type = StringProperty(
default="",
choices={
"person": "Person",
"place": "Place",
"topic": "Topic",
"technique": "Technique",
"theme": "Theme",
},
)
embedding = ArrayProperty(FloatProperty()) # 4096d vector
# Relationships
related_concepts = RelationshipTo("Concept", "RELATED_TO")
def __str__(self):
return self.name
class Image(StructuredNode):
"""
An image associated with an Item (cover art, diagram, photo, etc.).
The image file is stored in S3; embeddings enable multimodal search.
"""
uid = UniqueIdProperty()
s3_key = StringProperty(required=True)
image_type = StringProperty(
default="",
choices={
"cover": "Cover",
"diagram": "Diagram",
"artwork": "Artwork",
"still": "Still",
"photo": "Photo",
},
)
description = StringProperty(default="")
metadata = JSONProperty(default={})
created_at = DateTimeProperty(default_now=True)
# Relationships
embeddings = RelationshipTo("ImageEmbedding", "HAS_EMBEDDING")
def __str__(self):
return f"Image {self.image_type} ({self.uid})"
class ImageEmbedding(StructuredNode):
"""
A multimodal embedding vector for an Image node.
Generated by Qwen3-VL for unified text+image vector space.
"""
uid = UniqueIdProperty()
embedding = ArrayProperty(FloatProperty()) # 4096d multimodal vector
created_at = DateTimeProperty(default_now=True)
def __str__(self):
return f"ImageEmbedding ({self.uid})"