LaxmiVarshithaCH
Deploy NeuralKarma to HuggingFace Spaces
553a798
"""
NeuralKarma — Database Layer
SQLAlchemy ORM models and database session management.
Uses SQLite for zero-config operation.
"""
import os
from datetime import datetime, timezone
from pathlib import Path
from sqlalchemy import (
Column, Integer, Float, String, Text, DateTime, Boolean,
ForeignKey, Index, create_engine, JSON,
)
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship
# Database file in project root
DB_PATH = Path(__file__).parent.parent / "neuralkarma.db"
DATABASE_URL = f"sqlite:///{DB_PATH}"
engine = create_engine(DATABASE_URL, echo=False, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
def utcnow():
return datetime.now(timezone.utc)
class User(Base):
"""A user who performs actions and accumulates karma."""
__tablename__ = "users"
id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(100), unique=True, nullable=False, index=True)
display_name = Column(String(200), default="")
created_at = Column(DateTime, default=utcnow)
total_actions = Column(Integer, default=0)
aggregate_karma = Column(Float, default=50.0)
actions = relationship("Action", back_populates="user", cascade="all, delete-orphan")
def to_dict(self):
return {
"id": self.id,
"username": self.username,
"display_name": self.display_name,
"created_at": self.created_at.isoformat() if self.created_at else None,
"total_actions": self.total_actions,
"aggregate_karma": round(self.aggregate_karma, 2),
}
class Action(Base):
"""An action (text input) that has been scored by the karma engine."""
__tablename__ = "actions"
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True)
text = Column(Text, nullable=False)
created_at = Column(DateTime, default=utcnow, index=True)
# 5-axis scores (0-100)
prosociality_score = Column(Float, default=50.0)
harm_avoidance_score = Column(Float, default=50.0)
fairness_score = Column(Float, default=50.0)
virtue_score = Column(Float, default=50.0)
duty_score = Column(Float, default=50.0)
# Aggregate
aggregate_score = Column(Float, default=50.0, index=True)
confidence = Column(Float, default=0.0)
# Decay
decayed_score = Column(Float, default=50.0)
last_decay_update = Column(DateTime, default=utcnow)
# Karma chain
parent_action_id = Column(Integer, ForeignKey("actions.id"), nullable=True)
chain_modifier = Column(Float, default=1.0)
# Ripple
ripple_total_impact = Column(Float, default=0.0)
ripple_people_reached = Column(Integer, default=0)
# Full score breakdown (JSON)
raw_scores = Column(JSON, nullable=True)
user = relationship("User", back_populates="actions")
ripple_effects = relationship("RippleEffect", back_populates="source_action",
cascade="all, delete-orphan", foreign_keys="RippleEffect.source_action_id")
__table_args__ = (
Index("idx_action_user_time", "user_id", "created_at"),
)
def to_dict(self):
return {
"id": self.id,
"user_id": self.user_id,
"text": self.text,
"created_at": self.created_at.isoformat() if self.created_at else None,
"axis_scores": {
"prosociality": round(self.prosociality_score, 2),
"harm_avoidance": round(self.harm_avoidance_score, 2),
"fairness": round(self.fairness_score, 2),
"virtue": round(self.virtue_score, 2),
"duty": round(self.duty_score, 2),
},
"aggregate_score": round(self.aggregate_score, 2),
"confidence": round(self.confidence, 4),
"decayed_score": round(self.decayed_score, 2),
"parent_action_id": self.parent_action_id,
"chain_modifier": round(self.chain_modifier, 4),
"ripple_total_impact": round(self.ripple_total_impact, 2),
"ripple_people_reached": self.ripple_people_reached,
}
class RippleEffect(Base):
"""Tracks ripple effect propagation from one action."""
__tablename__ = "ripple_effects"
id = Column(Integer, primary_key=True, autoincrement=True)
source_action_id = Column(Integer, ForeignKey("actions.id"), nullable=False, index=True)
depth = Column(Integer, nullable=False)
impact_per_person = Column(Float, default=0.0)
people_affected = Column(Integer, default=0)
depth_total_impact = Column(Float, default=0.0)
cumulative_people = Column(Integer, default=0)
cumulative_impact = Column(Float, default=0.0)
source_action = relationship("Action", back_populates="ripple_effects",
foreign_keys=[source_action_id])
def to_dict(self):
return {
"id": self.id,
"source_action_id": self.source_action_id,
"depth": self.depth,
"impact_per_person": round(self.impact_per_person, 2),
"people_affected": self.people_affected,
"depth_total_impact": round(self.depth_total_impact, 2),
"cumulative_people": self.cumulative_people,
"cumulative_impact": round(self.cumulative_impact, 2),
}
class KarmaSnapshot(Base):
"""Periodic snapshot of a user's aggregate karma for history charting."""
__tablename__ = "karma_snapshots"
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True)
aggregate_karma = Column(Float, default=50.0)
total_actions = Column(Integer, default=0)
snapshot_at = Column(DateTime, default=utcnow, index=True)
def to_dict(self):
return {
"user_id": self.user_id,
"aggregate_karma": round(self.aggregate_karma, 2),
"total_actions": self.total_actions,
"snapshot_at": self.snapshot_at.isoformat() if self.snapshot_at else None,
}
def init_db():
"""Create all tables."""
Base.metadata.create_all(bind=engine)
print(" [OK] Database initialized")
def get_db():
"""Get a database session (for FastAPI dependency injection)."""
db = SessionLocal()
try:
yield db
finally:
db.close()