Files
ai-agents/dashboard/models.py
T

112 lines
4.5 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)
requires_llm = 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 RouteLog(Base):
__tablename__ = "route_log"
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
request_text = Column(Text, nullable=False)
recommended_agent = Column(String, default="")
action = Column(String, default="")
reasoning = Column(Text, default="")
outcome = Column(String, default="pending") # pending, accepted, rejected, success, failed
metadata_ = Column("metadata", JSON, default=dict)
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
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)