- Add Specialist Magic Links
- correction of some bugs: - dynamic fields for adding documents / urls to dossier catalog - tabs in latest bootstrap version no longer functional - partner association of license tier not working when no partner selected - data-type dynamic field needs conversion to isoformat - Add public tables to env.py of tenant schema
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import ast
|
||||
import json
|
||||
import uuid
|
||||
from datetime import datetime as dt, timezone as tz
|
||||
import time
|
||||
|
||||
@@ -13,9 +14,10 @@ from werkzeug.utils import secure_filename
|
||||
|
||||
from common.models.document import Embedding, DocumentVersion, Retriever
|
||||
from common.models.interaction import (ChatSession, Interaction, InteractionEmbedding, Specialist, SpecialistRetriever,
|
||||
EveAIAgent, EveAITask, EveAITool, EveAIAssetVersion)
|
||||
EveAIAgent, EveAITask, EveAITool, EveAIAssetVersion, SpecialistMagicLink)
|
||||
|
||||
from common.extensions import db, cache_manager
|
||||
from common.models.user import SpecialistMagicLinkTenant
|
||||
from common.services.interaction.specialist_services import SpecialistServices
|
||||
from common.utils.asset_utils import create_asset_stack, add_asset_version_file
|
||||
from common.utils.execution_progress import ExecutionProgressTracker
|
||||
@@ -26,7 +28,8 @@ from common.utils.nginx_utils import prefixed_url_for
|
||||
from common.utils.view_assistants import form_validation_failed, prepare_table_for_macro
|
||||
|
||||
from .interaction_forms import (SpecialistForm, EditSpecialistForm, EditEveAIAgentForm, EditEveAITaskForm,
|
||||
EditEveAIToolForm, AddEveAIAssetForm, EditEveAIAssetVersionForm, ExecuteSpecialistForm)
|
||||
EditEveAIToolForm, AddEveAIAssetForm, EditEveAIAssetVersionForm, ExecuteSpecialistForm,
|
||||
SpecialistMagicLinkForm, EditSpecialistMagicLinkForm)
|
||||
|
||||
interaction_bp = Blueprint('interaction_bp', __name__, url_prefix='/interaction')
|
||||
|
||||
@@ -669,3 +672,119 @@ def session_interactions(chat_session_id):
|
||||
"""
|
||||
chat_session = ChatSession.query.get_or_404(chat_session_id)
|
||||
return session_interactions_by_session_id(chat_session.session_id)
|
||||
|
||||
|
||||
# Routes for SpecialistMagicLink Management -------------------------------------------------------
|
||||
@interaction_bp.route('/specialist_magic_link', methods=['GET', 'POST'])
|
||||
@roles_accepted('Super User', 'Partner Admin', 'Tenant Admin')
|
||||
def specialist_magic_link():
|
||||
form = SpecialistMagicLinkForm()
|
||||
|
||||
if request.method == 'GET':
|
||||
magic_link_code = f"SPECIALIST_ML-{str(uuid.uuid4())}"
|
||||
form.magic_link_code.data = magic_link_code
|
||||
|
||||
if form.validate_on_submit():
|
||||
tenant_id = session.get('tenant').get('id')
|
||||
try:
|
||||
new_specialist_magic_link = SpecialistMagicLink()
|
||||
|
||||
# Populate fields individually instead of using populate_obj (gives problem with QueryMultipleSelectField)
|
||||
form.populate_obj(new_specialist_magic_link)
|
||||
|
||||
set_logging_information(new_specialist_magic_link, dt.now(tz.utc))
|
||||
|
||||
# Create 'public' SpecialistMagicLinkTenant
|
||||
new_spec_ml_tenant = SpecialistMagicLinkTenant()
|
||||
new_spec_ml_tenant.magic_link_code = new_specialist_magic_link.magic_link_code
|
||||
new_spec_ml_tenant.tenant_id = tenant_id
|
||||
|
||||
db.session.add(new_specialist_magic_link)
|
||||
db.session.add(new_spec_ml_tenant)
|
||||
|
||||
db.session.commit()
|
||||
flash('Specialist Magic Link successfully added!', 'success')
|
||||
current_app.logger.info(f'Specialist {new_specialist_magic_link.name} successfully added for '
|
||||
f'tenant {tenant_id}!')
|
||||
|
||||
return redirect(prefixed_url_for('interaction_bp.edit_specialist_magic_link',
|
||||
specialist_magic_link_id=new_specialist_magic_link.id))
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
current_app.logger.error(f'Failed to add specialist magic link. Error: {str(e)}', exc_info=True)
|
||||
flash(f'Failed to add specialist magic link. Error: {str(e)}', 'danger')
|
||||
|
||||
return render_template('interaction/specialist_magic_link.html', form=form)
|
||||
|
||||
|
||||
@interaction_bp.route('/specialist_magic_link/<int:specialist_magic_link_id>', methods=['GET', 'POST'])
|
||||
@roles_accepted('Super User', 'Partner Admin', 'Tenant Admin')
|
||||
def edit_specialist_magic_link(specialist_magic_link_id):
|
||||
specialist_ml = SpecialistMagicLink.query.get_or_404(specialist_magic_link_id)
|
||||
# We need to pass along the extra kwarg specialist_id, as this id is required to initialize the form
|
||||
form = EditSpecialistMagicLinkForm(request.form, obj=specialist_ml, specialist_id=specialist_ml.specialist_id)
|
||||
|
||||
# Find the Specialist type and type_version to enable to retrieve the arguments
|
||||
specialist = Specialist.query.get_or_404(specialist_ml.specialist_id)
|
||||
specialist_config = cache_manager.specialists_config_cache.get_config(specialist.type, specialist.type_version)
|
||||
|
||||
form.add_dynamic_fields("arguments", specialist_config, specialist_ml.specialist_args)
|
||||
|
||||
if form.validate_on_submit():
|
||||
# Update the basic fields
|
||||
form.populate_obj(specialist_ml)
|
||||
# Update the arguments dynamic fields
|
||||
specialist_ml.specialist_args = form.get_dynamic_data("arguments")
|
||||
|
||||
# Update logging information
|
||||
update_logging_information(specialist_ml, dt.now(tz.utc))
|
||||
|
||||
try:
|
||||
db.session.commit()
|
||||
flash('Specialist Magic Link updated successfully!', 'success')
|
||||
current_app.logger.info(f'Specialist Magic Link {specialist_ml.id} updated successfully')
|
||||
return redirect(prefixed_url_for('interaction_bp.specialist_magic_links'))
|
||||
except SQLAlchemyError as e:
|
||||
db.session.rollback()
|
||||
flash(f'Failed to update specialist Magic Link. Error: {str(e)}', 'danger')
|
||||
current_app.logger.error(f'Failed to update specialist Magic Link {specialist_ml.id}. Error: {str(e)}')
|
||||
else:
|
||||
form_validation_failed(request, form)
|
||||
|
||||
return render_template('interaction/edit_specialist_magic_link.html', form=form)
|
||||
|
||||
|
||||
@interaction_bp.route('/specialist_magic_links', methods=['GET', 'POST'])
|
||||
@roles_accepted('Super User', 'Partner Admin', 'Tenant Admin')
|
||||
def specialist_magic_links():
|
||||
page = request.args.get('page', 1, type=int)
|
||||
per_page = request.args.get('per_page', 10, type=int)
|
||||
|
||||
query = SpecialistMagicLink.query.order_by(SpecialistMagicLink.id)
|
||||
|
||||
pagination = query.paginate(page=page, per_page=per_page)
|
||||
the_specialist_magic_links = pagination.items
|
||||
|
||||
# prepare table data
|
||||
rows = prepare_table_for_macro(the_specialist_magic_links, [('id', ''), ('name', ''), ('magic_link_code', ''),])
|
||||
|
||||
# Render the catalogs in a template
|
||||
return render_template('interaction/specialist_magic_links.html', rows=rows, pagination=pagination)
|
||||
|
||||
|
||||
@interaction_bp.route('/handle_specialist_magic_link_selection', methods=['POST'])
|
||||
@roles_accepted('Super User', 'Partner Admin', 'Tenant Admin')
|
||||
def handle_specialist_magic_link_selection():
|
||||
action = request.form.get('action')
|
||||
if action == 'create_specialist_magic_link':
|
||||
return redirect(prefixed_url_for('interaction_bp.specialist_magic_link'))
|
||||
|
||||
specialist_ml_identification = request.form.get('selected_row')
|
||||
specialist_ml_id = ast.literal_eval(specialist_ml_identification).get('value')
|
||||
|
||||
if action == "edit_specialist_magic_link":
|
||||
return redirect(prefixed_url_for('interaction_bp.edit_specialist_magic_link',
|
||||
specialist_magic_link_id=specialist_ml_id))
|
||||
|
||||
return redirect(prefixed_url_for('interaction_bp.specialists'))
|
||||
|
||||
Reference in New Issue
Block a user