from flask import current_app from flask_wtf import FlaskForm from wtforms import (StringField, PasswordField, BooleanField, SubmitField, EmailField, IntegerField, DateField, SelectField, SelectMultipleField, FieldList, FormField, FloatField, TextAreaField) from wtforms.validators import DataRequired, Length, Email, NumberRange, Optional import pytz from common.models.user import Role class TenantForm(FlaskForm): name = StringField('Name', validators=[DataRequired(), Length(max=80)]) website = StringField('Website', validators=[DataRequired(), Length(max=255)]) # language fields default_language = SelectField('Default Language', choices=[], validators=[DataRequired()]) allowed_languages = SelectMultipleField('Allowed Languages', choices=[], validators=[DataRequired()]) # Timezone timezone = SelectField('Timezone', choices=[], validators=[DataRequired()]) # RAG context rag_context = TextAreaField('RAG Context', validators=[Optional()]) # LLM fields embedding_model = SelectField('Embedding Model', choices=[], validators=[DataRequired()]) llm_model = SelectField('Large Language Model', choices=[], validators=[DataRequired()]) # license fields license_start_date = DateField('License Start Date', id='form-control datepicker', validators=[Optional()]) license_end_date = DateField('License End Date', id='form-control datepicker', validators=[Optional()]) allowed_monthly_interactions = IntegerField('Allowed Monthly Interactions', validators=[NumberRange(min=0)]) # Embedding variables html_tags = StringField('HTML Tags', validators=[DataRequired()], default='p, h1, h2, h3, h4, h5, h6, li') html_end_tags = StringField('HTML End Tags', validators=[DataRequired()], default='p, li') html_included_elements = StringField('HTML Included Elements', validators=[Optional()]) html_excluded_elements = StringField('HTML Excluded Elements', validators=[Optional()]) # Embedding Search variables es_k = IntegerField('Limit for Searching Embeddings (5)', default=5, validators=[NumberRange(min=0)]) es_similarity_threshold = FloatField('Similarity Threshold for Searching Embeddings (0.5)', default=0.5, validators=[NumberRange(min=0, max=1)]) # Chat Variables chat_RAG_temperature = FloatField('RAG Temperature', default=0.3, validators=[NumberRange(min=0, max=1)]) chat_no_RAG_temperature = FloatField('No RAG Temperature', default=0.5, validators=[NumberRange(min=0, max=1)]) fallback_algorithms = SelectMultipleField('Fallback Algorithms', choices=[], validators=[Optional()]) # Tuning variables embed_tuning = BooleanField('Enable Embedding Tuning', default=False) rag_tuning = BooleanField('Enable RAG Tuning', default=False) submit = SubmitField('Submit') def __init__(self, *args, **kwargs): super(TenantForm, self).__init__(*args, **kwargs) # initialise language fields self.default_language.choices = [(lang, lang.lower()) for lang in current_app.config['SUPPORTED_LANGUAGES']] self.allowed_languages.choices = [(lang, lang.lower()) for lang in current_app.config['SUPPORTED_LANGUAGES']] # initialise timezone self.timezone.choices = [(tz, tz) for tz in pytz.all_timezones] # initialise LLM fields self.embedding_model.choices = [(model, model) for model in current_app.config['SUPPORTED_EMBEDDINGS']] self.llm_model.choices = [(model, model) for model in current_app.config['SUPPORTED_LLMS']] # Initialize fallback algorithms self.fallback_algorithms.choices = \ [(algorithm, algorithm.lower()) for algorithm in current_app.config['FALLBACK_ALGORITHMS']] class BaseUserForm(FlaskForm): user_name = StringField('Name', validators=[DataRequired(), Length(max=80)]) email = EmailField('Email', validators=[DataRequired(), Email()]) first_name = StringField('First Name', validators=[DataRequired(), Length(max=80)]) last_name = StringField('Last Name', validators=[DataRequired(), Length(max=80)]) valid_to = DateField('Valid to', id='form-control datepicker', validators=[Optional()]) tenant_id = IntegerField('Tenant ID', validators=[NumberRange(min=0)]) roles = SelectMultipleField('Roles', coerce=int) def __init__(self, *args, **kwargs): super(BaseUserForm, self).__init__(*args, **kwargs) self.roles.choices = [(role.id, role.name) for role in Role.query.all()] class CreateUserForm(BaseUserForm): submit = SubmitField('Create User') class EditUserForm(BaseUserForm): submit = SubmitField('Save User') class RoleForm(FlaskForm): # This subform will represent a single checkbox for each role role_id = StringField('Role ID') checked = BooleanField('Assigned') class UserRoleForm(FlaskForm): email = EmailField('Email', validators=[DataRequired(), Email()]) roles = FieldList(FormField(RoleForm), min_entries=1) submit = SubmitField('Update Roles') class TenantDomainForm(FlaskForm): domain = StringField('Domain', validators=[DataRequired(), Length(max=80)]) valid_to = DateField('Valid to', id='form-control datepicker', validators=[Optional()]) submit = SubmitField('Add Domain')