Files
ai-agents/dashboard/models.py
T

97 lines
3.9 KiB
Python

from sqlalchemy import Column, String, Text, DateTime, Integer, Boolean, ForeignKey, JSON
from sqlalchemy.orm import relationship
from datetime import datetime, timezone
from database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String, unique=True, nullable=False)
email = Column(String, unique=True, nullable=True)
password_hash = Column(String, nullable=False)
display_name = Column(String, default="")
role = Column(String, default="user") # admin or user
llm_config = Column(JSON, default=dict) # user's own LLM provider config
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
instances = relationship("AgentInstance", back_populates="user")
class AgentCatalog(Base):
__tablename__ = "agent_catalog"
id = Column(String, primary_key=True)
name = Column(String, nullable=False)
description = Column(Text, default="")
category = Column(String, default="utility") # data, briefing, utility
config_schema = Column(JSON, default=dict)
default_config = Column(JSON, default=dict)
supports_schedule = Column(Boolean, default=True)
is_sub_agent = Column(Boolean, default=False)
instances = relationship("AgentInstance", back_populates="catalog_entry")
class AgentInstance(Base):
__tablename__ = "agent_instances"
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
catalog_id = Column(String, ForeignKey("agent_catalog.id"), nullable=False)
name = Column(String, nullable=False)
config = Column(JSON, default=dict)
schedule = Column(String, default="manual")
status = Column(String, default="active")
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
user = relationship("User", back_populates="instances")
catalog_entry = relationship("AgentCatalog", back_populates="instances")
runs = relationship("Run", back_populates="instance", order_by="Run.started_at.desc()")
class Run(Base):
__tablename__ = "runs"
id = Column(Integer, primary_key=True, autoincrement=True)
instance_id = Column(Integer, ForeignKey("agent_instances.id"), nullable=False)
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
started_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
finished_at = Column(DateTime, nullable=True)
status = Column(String, default="running")
output = Column(Text, default="")
error = Column(Text, default="")
metadata_ = Column("metadata", JSON, default=dict)
instance = relationship("AgentInstance", back_populates="runs")
class Bridge(Base):
__tablename__ = "bridges"
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
api_key = Column(String, nullable=False) # Auth token for bridge requests
bridge_url = Column(String, default="") # http://ip:port
hostname = Column(String, default="") # e.g. "Jungbauers-MBP"
platform = Column(String, default="macos") # macos, ios (future)
capabilities = Column(JSON, default=list) # ["notes", "reading-list"]
status = Column(String, default="offline") # online, offline
last_heartbeat = Column(DateTime, nullable=True)
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
user = relationship("User")
class LLMProvider(Base):
__tablename__ = "llm_providers"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=False)
provider_type = Column(String, default="anthropic") # anthropic, openai, litellm, ollama
api_url = Column(String, default="")
api_key = Column(String, default="")
default_model = Column(String, default="")
is_default = Column(Boolean, default=False)