from django import forms from django.contrib.auth.forms import UserCreationForm from django.forms import ModelForm from mixins.restrictions import RestrictedFormMixin from .models import ( AI, ChatSession, Group, Manipulation, Message, NotificationSettings, Person, Persona, PersonIdentifier, QueuedMessage, User, ) # Create your forms here. class NewUserForm(UserCreationForm): email = forms.EmailField(required=True) class Meta: model = User fields = ( "username", "email", "first_name", "last_name", "password1", "password2", ) def save(self, commit=True): user = super(NewUserForm, self).save(commit=False) user.email = self.cleaned_data["email"] if commit: user.save() return user class NotificationSettingsForm(RestrictedFormMixin, ModelForm): class Meta: model = NotificationSettings fields = ( "ntfy_topic", "ntfy_url", ) help_texts = { "ntfy_topic": "The topic to send notifications to.", "ntfy_url": "Custom NTFY server. Leave blank to use the default server.", } class CustomUserCreationForm(UserCreationForm): class Meta: model = User fields = "__all__" class AIForm(RestrictedFormMixin, forms.ModelForm): class Meta: model = AI fields = ("base_url", "api_key", "model") # widgets = { # "api_key": forms.PasswordInput(attrs={"class": "input"}), # } help_texts = { "base_url": "URL of the OpenAI-compatible server.", "api_key": "API key for authentication.", "model": "Select the AI model to be used.", } class PersonIdentifierForm(RestrictedFormMixin, forms.ModelForm): class Meta: model = PersonIdentifier fields = ("identifier", "service") help_texts = { "identifier": ( "The unique identifier (e.g., username or phone number) " "for the person." ), "service": ( "The platform associated with this identifier " "(e.g., Signal, WhatsApp, Instagram, XMPP)." ), } class PersonForm(RestrictedFormMixin, forms.ModelForm): class Meta: model = Person fields = ( "name", "summary", "profile", "revealed", "dislikes", "likes", "sentiment", "timezone", "last_interaction", ) help_texts = { "name": "The full name of the person.", "summary": "A brief summary or description of this person.", "profile": "Detailed profile information about this person.", "revealed": "Information about what has been revealed to others.", "dislikes": "Things this person dislikes.", "likes": "Things this person enjoys.", "sentiment": "Sentiment score ranging from -1 (disliked) to +1 (trusted).", "timezone": "The person's timezone for accurate timestamping.", "last_interaction": "The date and time of the last recorded interaction.", } class GroupForm(RestrictedFormMixin, forms.ModelForm): class Meta: model = Group fields = ("name", "people") help_texts = { "name": "The name of the group.", "people": "People who are part of this group.", } people = forms.ModelMultipleChoiceField( queryset=Person.objects.all(), widget=forms.CheckboxSelectMultiple, help_text=Meta.help_texts["people"], required=False, ) class PersonaForm(RestrictedFormMixin, forms.ModelForm): class Meta: model = Persona fields = ( "alias", "mbti", "mbti_identity", "inner_story", "core_values", "communication_style", "flirting_style", "humor_style", "likes", "dislikes", "tone", "response_tactics", "persuasion_tactics", "boundaries", "trust", "adaptability", ) help_texts = { "alias": "The preferred name or identity for this persona.", "mbti": "Select the Myers-Briggs Type Indicator (MBTI) personality type.", "mbti_identity": ( "Identity assertiveness: -1 (Turbulent) to +1 (Assertive)." ), "inner_story": "A brief background or philosophy that shapes this persona.", "core_values": "The guiding principles and values of this persona.", "communication_style": ( "How this persona prefers to communicate " "(e.g., direct, formal, casual)." ), "flirting_style": "How this persona expresses attraction.", "humor_style": "Preferred style of humor (e.g., dry, dark, sarcastic).", "likes": "Topics and things this persona enjoys discussing.", "dislikes": "Topics and behaviors this persona prefers to avoid.", "tone": ( "The general tone this persona prefers " "(e.g., formal, witty, detached)." ), "response_tactics": ( "How this persona handles manipulation " "(e.g., gaslighting, guilt-tripping)." ), "persuasion_tactics": "The methods this persona uses to convince others.", "boundaries": "What this persona will not tolerate in conversations.", "trust": "Initial trust level (0-100) given in interactions.", "adaptability": "How easily this persona shifts tones or styles (0-100).", } class ManipulationForm(RestrictedFormMixin, forms.ModelForm): class Meta: model = Manipulation fields = ("name", "group", "ai", "persona", "enabled", "mode", "filter_enabled") help_texts = { "name": "The name of this manipulation strategy.", "group": "The group involved in this manipulation strategy.", # "self": "Group for own UUIDs.", "ai": "The AI associated with this manipulation.", "persona": "The persona used for this manipulation.", "enabled": "Whether this manipulation is enabled.", "mode": "Mode of operation.", "filter_enabled": ( "Whether incoming messages will be filtered using the persona." ), } class SessionForm(RestrictedFormMixin, forms.ModelForm): class Meta: model = ChatSession fields = ("identifier", "summary") help_texts = { "identifier": "Person identifier.", "summary": "Summary of chat transcript.", } class MessageForm(RestrictedFormMixin, forms.ModelForm): class Meta: model = Message fields = ( "session", "sender_uuid", "text", "custom_author", "delivered_ts", "read_ts", "read_source_service", "read_by_identifier", "receipt_payload", ) help_texts = { "session": "Chat session this message was sent in.", "sender_uuid": "UUID of the sender.", "text": "Content of the message.", "custom_author": "For detecting USER and BOT messages.", "delivered_ts": "Delivery timestamp in unix milliseconds, if known.", "read_ts": "Read timestamp in unix milliseconds, if known.", "read_source_service": "Service that reported this read receipt.", "read_by_identifier": "Identifier that read this message.", "receipt_payload": "Raw normalized receipt metadata.", } class QueueForm(RestrictedFormMixin, forms.ModelForm): class Meta: model = QueuedMessage fields = ("session", "manipulation", "text") help_texts = { "session": "Chat session this message will be sent in.", "manipulation": "Manipulation that generated the message.", "text": "Content of the proposed message.", } class AIWorkspaceWindowForm(forms.Form): """Controls the message window size for AI workspace previews.""" limit = forms.ChoiceField( choices=( ("20", "Last 20"), ("50", "Last 50"), ("100", "Last 100"), ), initial="20", required=True, help_text="How many most-recent messages to load for the selected person.", widget=forms.Select(attrs={"class": "is-fullwidth"}), )