# app/models/syndarix/agent_instance.py """ AgentInstance model for Syndarix AI consulting platform. An AgentInstance is a spawned instance of an AgentType, assigned to a specific project to perform work. """ from sqlalchemy import ( BigInteger, Column, DateTime, Enum, ForeignKey, Index, Integer, Numeric, String, Text, ) from sqlalchemy.dialects.postgresql import ( JSONB, UUID as PGUUID, ) from sqlalchemy.orm import relationship from app.models.base import Base, TimestampMixin, UUIDMixin from .enums import AgentStatus class AgentInstance(Base, UUIDMixin, TimestampMixin): """ AgentInstance model representing a spawned agent working on a project. Tracks: - Current status and task - Memory (short-term in DB, long-term reference to vector store) - Session information for MCP connections - Usage metrics (tasks completed, tokens, cost) """ __tablename__ = "agent_instances" # Foreign keys agent_type_id = Column( PGUUID(as_uuid=True), ForeignKey("agent_types.id", ondelete="RESTRICT"), nullable=False, index=True, ) project_id = Column( PGUUID(as_uuid=True), ForeignKey("projects.id", ondelete="CASCADE"), nullable=False, index=True, ) # Agent instance name (e.g., "Dave", "Eve") for personality name = Column(String(100), nullable=False, index=True) # Status tracking status: Column[AgentStatus] = Column( Enum( AgentStatus, name="agent_status", values_callable=lambda x: [e.value for e in x], ), default=AgentStatus.IDLE, nullable=False, index=True, ) # Current task description (brief summary of what agent is doing) current_task = Column(Text, nullable=True) # Short-term memory stored in database (conversation context, recent decisions) short_term_memory = Column(JSONB, default=dict, nullable=False) # Reference to long-term memory in vector store (e.g., "project-123/agent-456") long_term_memory_ref = Column(String(500), nullable=True) # Session ID for active MCP connections session_id = Column(String(255), nullable=True, index=True) # Activity tracking last_activity_at = Column(DateTime(timezone=True), nullable=True, index=True) terminated_at = Column(DateTime(timezone=True), nullable=True, index=True) # Usage metrics tasks_completed = Column(Integer, default=0, nullable=False) tokens_used = Column(BigInteger, default=0, nullable=False) cost_incurred = Column(Numeric(precision=10, scale=4), default=0, nullable=False) # Relationships agent_type = relationship("AgentType", back_populates="instances") project = relationship("Project", back_populates="agent_instances") assigned_issues = relationship( "Issue", back_populates="assigned_agent", foreign_keys="Issue.assigned_agent_id", ) __table_args__ = ( Index("ix_agent_instances_project_status", "project_id", "status"), Index("ix_agent_instances_type_status", "agent_type_id", "status"), Index("ix_agent_instances_project_type", "project_id", "agent_type_id"), ) def __repr__(self) -> str: return ( f"" )