from django.db.models import CASCADE, SET_NULL, BooleanField, CharField, DateTimeField, ForeignKey, JSONField, Model, TextField from django.utils.translation import gettext_lazy as _ from apps.accounts.mixins import IdentifierMixin, TimeStampMixin from apps.accounts.models import Organization, Role, User class AgentConfig(IdentifierMixin, TimeStampMixin, Model): AGENT_TYPES = [ ('curriculum', 'Curriculum Agent (CA)'), ('knowledge', 'Knowledge Agent (KA)'), ('assessment', 'Assessment Agent (AA)'), ('monitor', 'Progress Monitor Agent (PMA)'), ] organization = ForeignKey(Organization, on_delete=CASCADE, related_name='agent_configs', verbose_name=_("Organization")) role = ForeignKey(Role, on_delete=CASCADE, related_name='agent_configs', verbose_name=_("Role"), null=True, blank=True) name = CharField(max_length=255, verbose_name=_("Agent Name")) agent_type = CharField(max_length=40, choices=AGENT_TYPES, verbose_name=_("Agent Type")) system_prompt = TextField(verbose_name=_("System Prompt"), blank=True, default='') class Meta: verbose_name = _('Agent Config') verbose_name_plural = _('Agent Configs') def __str__(self): return f"{self.name} ({self.organization.name})" class OnboardingFlow(IdentifierMixin, TimeStampMixin, Model): title = CharField(max_length=255, verbose_name=_("Flow Title")) role = ForeignKey(Role, on_delete=CASCADE, related_name='flows', verbose_name=_("Role")) structure = JSONField(default=list, blank=True, verbose_name=_("Flow Structure")) is_active = BooleanField(default=True, verbose_name=_("Is Active")) class Meta: verbose_name = _('Onboarding Flow') verbose_name_plural = _('Onboarding Flows') def __str__(self): return self.title class OnboardingSession(IdentifierMixin, TimeStampMixin, Model): STATUS_CHOICES = [ ('active', 'Active'), ('completed', 'Completed'), ('paused', 'Paused'), ] user = ForeignKey(User, on_delete=CASCADE, related_name='onboarding_sessions', verbose_name=_("User")) role = ForeignKey(Role, on_delete=CASCADE, related_name='onboarding_sessions', verbose_name=_("Target Role")) flow = ForeignKey(OnboardingFlow, on_delete=SET_NULL, null=True, blank=True, related_name='sessions', verbose_name=_("Onboarding Flow")) status = CharField(max_length=20, choices=STATUS_CHOICES, default='active', verbose_name=_("Session Status")) state = JSONField(default=dict, blank=True, verbose_name=_("Session State")) completed_at = DateTimeField(null=True, blank=True, verbose_name=_("Completed At")) class Meta: verbose_name = _('Onboarding Session') verbose_name_plural = _('Onboarding Sessions') def __str__(self): return f"{self.user.email_address} - {self.role.name}" class AgentInteractionLog(IdentifierMixin, TimeStampMixin, Model): SENDER_TYPES = [ ('system', 'System'), ('ai', 'AI'), ('user', 'User'), ('tool', 'Tool Output'), ] session = ForeignKey(OnboardingSession, on_delete=CASCADE, related_name='logs', verbose_name=_("Session")) agent_config = ForeignKey(AgentConfig, on_delete=CASCADE, null=True, blank=True, verbose_name=_("Agent Config")) sender_type = CharField(max_length=20, choices=SENDER_TYPES, verbose_name=_("Sender Type")) content = TextField(verbose_name=_("Message Content")) tool_call_metadata = JSONField(default=dict, blank=True, verbose_name=_("Tool Call Metadata")) class Meta: verbose_name = _('Interaction Log') verbose_name_plural = _('Interaction Logs') ordering = ['created_at'] def __str__(self): return f"{self.sender_type} in {self.session.uuid}"