uchill/chatnext/backend/apps/chatbot/models/user_preference.py

174 lines
5.5 KiB
Python

"""
User Preference Model - AI chatbot settings and preferences.
"""
from django.db import models
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from core.models import TimestampedModel
class UserPreference(TimestampedModel):
"""
User-specific AI chatbot preferences and settings.
Stores default configurations for new chat sessions and
global user preferences for AI interactions.
"""
# One preference per user
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name="ai_preferences",
help_text=_("User these preferences belong to"),
)
# Default model settings
default_model = models.CharField(
max_length=100,
default="gpt-5-mini",
choices=[
("gpt-5-mini", "GPT-5 Mini (Recommended)"),
("gpt-5-nano", "GPT-5 Nano (Smaller/Faster)"),
("gpt-4.1-mini", "GPT-4.1 Mini (Faster/Cheaper)"),
("gpt-4o-mini", "GPT-4o Mini (Faster/Cheaper)"),
("o4-mini", "GPT-o4 Mini (Reasoning)"),
],
help_text=_("Default AI model for new conversations"),
)
default_temperature = models.FloatField(
default=0.7,
help_text=_("Default temperature (0.0-2.0). Higher = more creative"),
)
default_max_tokens = models.IntegerField(
default=2000, help_text=_("Default max tokens for responses")
)
# Summarization preferences
enable_auto_summarization = models.BooleanField(
default=True, help_text=_("Enable automatic conversation summarization")
)
summarization_trigger_tokens = models.IntegerField(
default=384, help_text=_("Token count to trigger summarization")
)
max_summary_tokens = models.IntegerField(
default=128, help_text=_("Maximum tokens in summary")
)
summarization_style = models.CharField(
max_length=20,
default="concise",
choices=[
("concise", "Concise (Brief summaries)"),
("detailed", "Detailed (More context)"),
("bullet", "Bullet Points"),
],
help_text=_("Style of automatic summaries"),
)
# System prompt
custom_system_prompt = models.TextField(
blank=True, null=True, help_text=_("Custom system prompt for all conversations")
)
use_custom_system_prompt = models.BooleanField(
default=False, help_text=_("Use custom system prompt instead of default")
)
# Response preferences
response_language = models.CharField(
max_length=10,
default="en",
help_text=_("Preferred response language code (e.g., en, es, fr)"),
)
enable_streaming = models.BooleanField(
default=True, help_text=_("Enable streaming responses (word-by-word)")
)
enable_code_execution = models.BooleanField(
default=False, help_text=_("Allow AI to execute code (advanced users only)")
)
# Usage limits
daily_message_limit = models.IntegerField(
default=100, help_text=_("Maximum messages per day (0 = unlimited)")
)
daily_token_limit = models.IntegerField(
default=50000, help_text=_("Maximum tokens per day (0 = unlimited)")
)
# UI preferences
theme = models.CharField(
max_length=20,
default="auto",
choices=[
("light", "Light Theme"),
("dark", "Dark Theme"),
("auto", "Auto (System)"),
],
help_text=_("Chat interface theme"),
)
show_token_count = models.BooleanField(
default=False, help_text=_("Show token count in chat interface")
)
enable_notifications = models.BooleanField(
default=True, help_text=_("Enable browser notifications for AI responses")
)
# Privacy settings
save_conversation_history = models.BooleanField(
default=True, help_text=_("Save conversation history for future reference")
)
allow_data_training = models.BooleanField(
default=False,
help_text=_("Allow conversations to be used for model improvement"),
)
# Advanced settings
additional_settings = models.JSONField(
default=dict, blank=True, help_text=_("Additional user-specific settings")
)
class Meta:
verbose_name = _("User Preference")
verbose_name_plural = _("User Preferences")
def __str__(self):
return f"Preferences for {self.user.email}"
def get_session_config(self):
"""
Get configuration dict for new chat sessions.
Returns:
dict: Configuration for ChatSession and LangGraph
"""
return {
"model_name": self.default_model,
"temperature": self.default_temperature,
"max_tokens": self.default_max_tokens,
"enable_summarization": self.enable_auto_summarization,
"summarization_threshold": self.summarization_trigger_tokens,
"max_summary_tokens": self.max_summary_tokens,
"system_prompt": (
self.custom_system_prompt if self.use_custom_system_prompt else None
),
"language": self.response_language,
"streaming": self.enable_streaming,
}
@property
def has_usage_limits(self):
"""Check if user has any usage limits set."""
return self.daily_message_limit > 0 or self.daily_token_limit > 0